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*);
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:
......
......@@ -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; }
......
......@@ -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);
......
......@@ -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");
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;
}
......
......@@ -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
......
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