winedbg: Support 'run' command with arguments to restart current debuggee.

Signed-off-by: Eric Pouech <eric.pouech@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Eric Pouech 2021-12-01 15:30:29 +01:00 committed by Alexandre Julliard
parent d331d9cb93
commit 4448ef5031
5 changed files with 70 additions and 20 deletions

View File

@ -43,6 +43,7 @@ static void parser(const char*);
IMAGEHLP_LINE64 listing; IMAGEHLP_LINE64 listing;
struct expr* expression; struct expr* expression;
struct type_expr_t type; struct type_expr_t type;
struct list_string* strings;
} }
%token tCONT tPASS tSTEP tLIST tNEXT tQUIT tHELP tBACKTRACE tALL tINFO tUP tDOWN %token tCONT tPASS tSTEP tLIST tNEXT tQUIT tHELP tBACKTRACE tALL tINFO tUP tDOWN
@ -85,6 +86,7 @@ static void parser(const char*);
%type <string> pathname identifier cpp_identifier %type <string> pathname identifier cpp_identifier
%type <listing> list_arg %type <listing> list_arg
%type <type> type_expr %type <type> type_expr
%type <strings> list_of_words
%% %%
@ -183,8 +185,12 @@ list_arg:
; ;
run_command: run_command:
tRUN { dbg_run_debuggee(NULL); } tRUN list_of_words { dbg_run_debuggee($2); }
| tRUN tSTRING { dbg_run_debuggee($2); } ;
list_of_words:
%empty { $$ = NULL; }
| tSTRING list_of_words { $$ = (struct list_string*)lexeme_alloc_size(sizeof(*$$)); $$->next = $2; $$->string = $1; }
; ;
list_command: list_command:

View File

@ -115,6 +115,7 @@ STRING \"(\\[^\n]|[^\\"\n])*\"
%x PATH_EXPECTED %x PATH_EXPECTED
%x ASTRING_EXPECTED %x ASTRING_EXPECTED
%x AWORD_EXPECTED
%x NOPROCESS %x NOPROCESS
%% %%
/* set to special state when no process is loaded. */ /* set to special state when no process is loaded. */
@ -153,10 +154,11 @@ STRING \"(\\[^\n]|[^\\"\n])*\"
<FORMAT_EXPECTED>"/"{FORMAT} { dbg_lval.integer = (1 << 8) | yytext[1]; return tFORMAT; } <FORMAT_EXPECTED>"/"{FORMAT} { dbg_lval.integer = (1 << 8) | yytext[1]; return tFORMAT; }
{STRING} { dbg_lval.string = unescape_string(yytext); return tSTRING;} <*>{STRING} { dbg_lval.string = unescape_string(yytext); return tSTRING;}
<ASTRING_EXPECTED>[^\n]+ { char* p = yytext; while (*p == ' ' || *p == '\t') p++; <ASTRING_EXPECTED>[^\n]+ { char* p = yytext; while (*p == ' ' || *p == '\t') p++;
dbg_lval.string = lexeme_alloc(p); return tSTRING; } dbg_lval.string = lexeme_alloc(p); return tSTRING; }
<AWORD_EXPECTED>[^ \t\n]+ { char* p = yytext; while (*p == ' ' || *p == '\t') p++;
dbg_lval.string = lexeme_alloc(p); return tSTRING; }
<INITIAL,NOPROCESS>info|inf|in { BEGIN(INFO_CMD); return tINFO; } <INITIAL,NOPROCESS>info|inf|in { BEGIN(INFO_CMD); return tINFO; }
<INITIAL>up { BEGIN(NOCMD); return tUP; } <INITIAL>up { BEGIN(NOCMD); return tUP; }
<INITIAL>down|dow|do { BEGIN(NOCMD); return tDOWN; } <INITIAL>down|dow|do { BEGIN(NOCMD); return tDOWN; }
@ -200,7 +202,7 @@ STRING \"(\\[^\n]|[^\\"\n])*\"
<INITIAL>watch|watc|wat { BEGIN(NOCMD); return tWATCH; } <INITIAL>watch|watc|wat { BEGIN(NOCMD); return tWATCH; }
<INITIAL>rwatch|rwatc|rwat { BEGIN(NOCMD); return tRWATCH; } <INITIAL>rwatch|rwatc|rwat { BEGIN(NOCMD); return tRWATCH; }
<INITIAL>whatis|whati|what { BEGIN(NOCMD); return tWHATIS; } <INITIAL>whatis|whati|what { BEGIN(NOCMD); return tWHATIS; }
<INITIAL,NOPROCESS>run|ru|r { BEGIN(ASTRING_EXPECTED); return tRUN;} <INITIAL,NOPROCESS>run|ru|r { BEGIN(AWORD_EXPECTED); return tRUN;}
<INITIAL>detach|detac|deta|det { BEGIN(NOCMD); return tDETACH; } <INITIAL>detach|detac|deta|det { BEGIN(NOCMD); return tDETACH; }
<INITIAL>kill|kil|ki|k { BEGIN(NOCMD); return tKILL; } <INITIAL>kill|kil|ki|k { BEGIN(NOCMD); return tKILL; }
<INITIAL,NOPROCESS>maintenance|maint { BEGIN(MAINT_CMD); return tMAINTENANCE; } <INITIAL,NOPROCESS>maintenance|maint { BEGIN(MAINT_CMD); return tMAINTENANCE; }

View File

@ -421,7 +421,12 @@ extern enum sym_get_lval symbol_picker_scoped(const char* name, const struct sgv
struct dbg_lvalue* rtn); struct dbg_lvalue* rtn);
/* tgt_active.c */ /* tgt_active.c */
extern void dbg_run_debuggee(const char* args); struct list_string
{
char* string;
struct list_string* next;
};
extern void dbg_run_debuggee(struct list_string* ls);
extern void dbg_wait_next_exception(DWORD cont, int count, int mode); extern void dbg_wait_next_exception(DWORD cont, int count, int mode);
extern enum dbg_start dbg_active_attach(int argc, char* argv[]); extern enum dbg_start dbg_active_attach(int argc, char* argv[]);
extern BOOL dbg_set_curr_thread(DWORD tid); extern BOOL dbg_set_curr_thread(DWORD tid);

View File

@ -31,6 +31,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(winedbg); WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
static char* dbg_executable;
static char* dbg_last_cmd_line; static char* dbg_last_cmd_line;
static struct be_process_io be_process_active_io; static struct be_process_io be_process_active_io;
@ -632,6 +633,11 @@ static BOOL dbg_start_debuggee(LPSTR cmdLine)
dbg_curr_pid = info.dwProcessId; dbg_curr_pid = info.dwProcessId;
if (!(dbg_curr_process = dbg_add_process(&be_process_active_io, dbg_curr_pid, 0))) return FALSE; if (!(dbg_curr_process = dbg_add_process(&be_process_active_io, dbg_curr_pid, 0))) return FALSE;
dbg_curr_process->active_debuggee = TRUE; dbg_curr_process->active_debuggee = TRUE;
if (cmdLine != dbg_last_cmd_line)
{
free(dbg_last_cmd_line);
dbg_last_cmd_line = cmdLine;
}
return TRUE; return TRUE;
} }
@ -718,24 +724,46 @@ static char *dbg_build_command_line( char **argv )
} }
void dbg_run_debuggee(const char* args) void dbg_run_debuggee(struct list_string* ls)
{ {
if (args) if (dbg_curr_process)
{ {
WINE_FIXME("Re-running current program with %s as args is broken\n", wine_dbgstr_a(args)); dbg_printf("Already attached to a process. Use 'detach' or 'kill' before using 'run'\n");
return; return;
} }
else if (!dbg_executable)
{ {
if (!dbg_last_cmd_line) dbg_printf("No active target to be restarted\n");
{ return;
dbg_printf("Cannot find previously used command line.\n");
return;
}
dbg_start_debuggee(dbg_last_cmd_line);
dbg_active_wait_for_first_exception();
source_list_from_addr(NULL, 0);
} }
if (ls)
{
char* cl;
char** argv;
unsigned argc = 2, i;
struct list_string* cls;
for (cls = ls; cls; cls = cls->next) argc++;
if (!(argv = malloc(argc * sizeof(argv[0])))) return;
argv[0] = dbg_executable;
for (i = 1, cls = ls; cls; cls = cls->next, i++) argv[i] = cls->string;
argv[i] = NULL;
cl = dbg_build_command_line(argv);
free(argv);
if (!cl || !dbg_start_debuggee(cl))
{
free(cl);
return;
}
}
else
{
if (!dbg_last_cmd_line) dbg_last_cmd_line = strdup(dbg_executable);
dbg_start_debuggee(dbg_last_cmd_line);
}
dbg_active_wait_for_first_exception();
source_list_from_addr(NULL, 0);
} }
static BOOL str2int(const char* str, DWORD_PTR* val) static BOOL str2int(const char* str, DWORD_PTR* val)
@ -893,14 +921,15 @@ enum dbg_start dbg_active_launch(int argc, char* argv[])
if (argc == 0) return start_error_parse; if (argc == 0) return start_error_parse;
dbg_executable = strdup(argv[0]);
cmd_line = dbg_build_command_line(argv); cmd_line = dbg_build_command_line(argv);
if (!dbg_start_debuggee(cmd_line)) if (!dbg_start_debuggee(cmd_line))
{ {
free(cmd_line); free(cmd_line);
return start_error_init; return start_error_init;
} }
free(dbg_last_cmd_line);
dbg_last_cmd_line = cmd_line;
return start_ok; return start_ok;
} }

View File

@ -109,6 +109,8 @@ of variations from \fBgdb\fR commands.
Aborts the debugger. Aborts the debugger.
.IP \fBquit\fR .IP \fBquit\fR
Exits the debugger. Exits the debugger.
.PP
\fIProcess handling\fR
.IP \fBattach\ \fIN\fR .IP \fBattach\ \fIN\fR
Attach to a Wine process (\fIN\fR is its Windows ID, numeric or hexadecimal). Attach to a Wine process (\fIN\fR is its Windows ID, numeric or hexadecimal).
IDs can be obtained using the \fBinfo\ process\fR command. Note the IDs can be obtained using the \fBinfo\ process\fR command. Note the
@ -119,6 +121,12 @@ Detach from a Wine-process.
.IP \fBthread\ \fIN\fR .IP \fBthread\ \fIN\fR
Change the current thread to \fIN\fR (its Windows TID, numeric or hexadecimal). Change the current thread to \fIN\fR (its Windows TID, numeric or hexadecimal).
.IP .IP
.IP \fBrun\fR
Re-run the same process with the same arguments.
Note: all breakpoints of precedent process are no longer available.
.IP \fBrun\ \fIarg1\ arg2...\fR
Re-run the same process with arguments \fIarg1\ arg2...\fR.
Note: all breakpoints of precedent process are no longer available.
.PP .PP
\fIHelp commands\fR \fIHelp commands\fR
.IP \fBhelp\fR .IP \fBhelp\fR