Module: wine Branch: master Commit: 4448ef5031a9e3ac6f4208d238d9c27e7e0d6fd6 URL: https://source.winehq.org/git/wine.git/?a=commit;h=4448ef5031a9e3ac6f4208d23...
Author: Eric Pouech eric.pouech@gmail.com Date: Wed Dec 1 15:30:29 2021 +0100
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
---
programs/winedbg/dbg.y | 10 ++++++-- programs/winedbg/debug.l | 8 +++--- programs/winedbg/debugger.h | 7 +++++- programs/winedbg/tgt_active.c | 55 +++++++++++++++++++++++++++++++---------- programs/winedbg/winedbg.man.in | 8 ++++++ 5 files changed, 69 insertions(+), 19 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 <string> pathname identifier cpp_identifier %type <listing> list_arg %type <type> type_expr +%type <strings> 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_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++; 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>up { BEGIN(NOCMD); return tUP; } <INITIAL>down|dow|do { BEGIN(NOCMD); return tDOWN; } @@ -200,7 +202,7 @@ STRING "(\[^\n]|[^\"\n])*" <INITIAL>watch|watc|wat { BEGIN(NOCMD); return tWATCH; } <INITIAL>rwatch|rwatc|rwat { BEGIN(NOCMD); return tRWATCH; } <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>kill|kil|ki|k { BEGIN(NOCMD); return tKILL; } <INITIAL,NOPROCESS>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("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)) { - 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); + 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