From 4448ef5031a9e3ac6f4208d238d9c27e7e0d6fd6 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Wed, 1 Dec 2021 15:30:29 +0100 Subject: [PATCH] winedbg: Support 'run' command with arguments to restart current debuggee. Signed-off-by: Eric Pouech Signed-off-by: Alexandre Julliard --- programs/winedbg/dbg.y | 10 ++++-- programs/winedbg/debug.l | 8 +++-- programs/winedbg/debugger.h | 7 +++- programs/winedbg/tgt_active.c | 57 +++++++++++++++++++++++++-------- programs/winedbg/winedbg.man.in | 8 +++++ 5 files changed, 70 insertions(+), 20 deletions(-) diff --git a/programs/winedbg/dbg.y b/programs/winedbg/dbg.y index 612e6a4106d..c5e7b2b43ca 100644 --- a/programs/winedbg/dbg.y +++ b/programs/winedbg/dbg.y @@ -43,6 +43,7 @@ static void parser(const char*); IMAGEHLP_LINE64 listing; struct expr* expression; struct type_expr_t type; + struct list_string* strings; } %token tCONT tPASS tSTEP tLIST tNEXT tQUIT tHELP tBACKTRACE tALL tINFO tUP tDOWN @@ -85,6 +86,7 @@ static void parser(const char*); %type pathname identifier cpp_identifier %type list_arg %type type_expr +%type list_of_words %% @@ -183,8 +185,12 @@ list_arg: ; run_command: - tRUN { dbg_run_debuggee(NULL); } - | tRUN tSTRING { dbg_run_debuggee($2); } + tRUN list_of_words { 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: diff --git a/programs/winedbg/debug.l b/programs/winedbg/debug.l index 280dcbfbc6b..dc93901a71c 100644 --- a/programs/winedbg/debug.l +++ b/programs/winedbg/debug.l @@ -115,6 +115,7 @@ STRING \"(\\[^\n]|[^\\"\n])*\" %x PATH_EXPECTED %x ASTRING_EXPECTED +%x AWORD_EXPECTED %x NOPROCESS %% /* set to special state when no process is loaded. */ @@ -153,10 +154,11 @@ STRING \"(\\[^\n]|[^\\"\n])*\" "/"{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;} [^\n]+ { char* p = yytext; while (*p == ' ' || *p == '\t') p++; dbg_lval.string = lexeme_alloc(p); return tSTRING; } - +[^ \t\n]+ { char* p = yytext; while (*p == ' ' || *p == '\t') p++; + dbg_lval.string = lexeme_alloc(p); return tSTRING; } info|inf|in { BEGIN(INFO_CMD); return tINFO; } up { BEGIN(NOCMD); return tUP; } down|dow|do { BEGIN(NOCMD); return tDOWN; } @@ -200,7 +202,7 @@ STRING \"(\\[^\n]|[^\\"\n])*\" watch|watc|wat { BEGIN(NOCMD); return tWATCH; } rwatch|rwatc|rwat { BEGIN(NOCMD); return tRWATCH; } whatis|whati|what { BEGIN(NOCMD); return tWHATIS; } -run|ru|r { BEGIN(ASTRING_EXPECTED); return tRUN;} +run|ru|r { BEGIN(AWORD_EXPECTED); return tRUN;} detach|detac|deta|det { BEGIN(NOCMD); return tDETACH; } kill|kil|ki|k { BEGIN(NOCMD); return tKILL; } maintenance|maint { BEGIN(MAINT_CMD); return tMAINTENANCE; } diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h index c511f3f76bc..0e6d715a2d1 100644 --- a/programs/winedbg/debugger.h +++ b/programs/winedbg/debugger.h @@ -421,7 +421,12 @@ extern enum sym_get_lval symbol_picker_scoped(const char* name, const struct sgv struct dbg_lvalue* rtn); /* 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 enum dbg_start dbg_active_attach(int argc, char* argv[]); extern BOOL dbg_set_curr_thread(DWORD tid); diff --git a/programs/winedbg/tgt_active.c b/programs/winedbg/tgt_active.c index 4bcd5ba659e..0993bddc985 100644 --- a/programs/winedbg/tgt_active.c +++ b/programs/winedbg/tgt_active.c @@ -31,6 +31,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(winedbg); +static char* dbg_executable; static char* dbg_last_cmd_line; 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; if (!(dbg_curr_process = dbg_add_process(&be_process_active_io, dbg_curr_pid, 0))) return FALSE; dbg_curr_process->active_debuggee = TRUE; + if (cmdLine != dbg_last_cmd_line) + { + free(dbg_last_cmd_line); + dbg_last_cmd_line = cmdLine; + } 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; } - else + if (!dbg_executable) { - if (!dbg_last_cmd_line) - { - 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); + dbg_printf("No active target to be restarted\n"); + return; } + 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) @@ -893,14 +921,15 @@ enum dbg_start dbg_active_launch(int argc, char* argv[]) if (argc == 0) return start_error_parse; + dbg_executable = strdup(argv[0]); cmd_line = dbg_build_command_line(argv); + if (!dbg_start_debuggee(cmd_line)) { free(cmd_line); return start_error_init; } - free(dbg_last_cmd_line); - dbg_last_cmd_line = cmd_line; + return start_ok; } diff --git a/programs/winedbg/winedbg.man.in b/programs/winedbg/winedbg.man.in index 6ed8d4474c4..871b7ad6764 100644 --- a/programs/winedbg/winedbg.man.in +++ b/programs/winedbg/winedbg.man.in @@ -109,6 +109,8 @@ of variations from \fBgdb\fR commands. Aborts the debugger. .IP \fBquit\fR Exits the debugger. +.PP +\fIProcess handling\fR .IP \fBattach\ \fIN\fR 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 @@ -119,6 +121,12 @@ Detach from a Wine-process. .IP \fBthread\ \fIN\fR Change the current thread to \fIN\fR (its Windows TID, numeric or hexadecimal). .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 \fIHelp commands\fR .IP \fBhelp\fR