Commit 4448ef50 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

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

parent d331d9cb
...@@ -43,6 +43,7 @@ static void parser(const char*); ...@@ -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*); ...@@ -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: ...@@ -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:
......
...@@ -115,6 +115,7 @@ STRING \"(\\[^\n]|[^\\"\n])*\" ...@@ -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])*\" ...@@ -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])*\" ...@@ -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; }
......
...@@ -421,7 +421,12 @@ extern enum sym_get_lval symbol_picker_scoped(const char* name, const struct sgv ...@@ -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);
......
...@@ -31,6 +31,7 @@ ...@@ -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) ...@@ -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 ) ...@@ -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;
}
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"); free(cl);
return; return;
} }
dbg_start_debuggee(dbg_last_cmd_line); }
dbg_active_wait_for_first_exception(); else
source_list_from_addr(NULL, 0); {
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[]) ...@@ -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;
} }
......
...@@ -109,6 +109,8 @@ of variations from \fBgdb\fR commands. ...@@ -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. ...@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment