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:
parent
d331d9cb93
commit
4448ef5031
|
@ -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("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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue