diff --git a/programs/winedbg/dbg.y b/programs/winedbg/dbg.y index 126eef22393..ac76b5baf8a 100644 --- a/programs/winedbg/dbg.y +++ b/programs/winedbg/dbg.y @@ -139,6 +139,7 @@ command: | tWHATIS expr_lvalue { dbg_printf("type = "); types_print_type(&$2.type, FALSE); dbg_printf("\n"); } | tATTACH tNUM { dbg_attach_debuggee($2); dbg_active_wait_for_first_exception(); } | tDETACH { dbg_curr_process->process_io->close_process(dbg_curr_process, FALSE); } + | tTHREAD tNUM { dbg_set_curr_thread($2); } | tKILL { dbg_curr_process->process_io->close_process(dbg_curr_process, TRUE); } | tMINIDUMP pathname { minidump_write($2, (dbg_curr_thread && dbg_curr_thread->in_exception) ? &dbg_curr_thread->excpt_record : NULL);} | tECHO tSTRING { dbg_printf("%s\n", $2); } diff --git a/programs/winedbg/debug.l b/programs/winedbg/debug.l index ef7a2eb42bc..79cb8ccd3a8 100644 --- a/programs/winedbg/debug.l +++ b/programs/winedbg/debug.l @@ -187,6 +187,7 @@ STRING \"[^\n"]+\" display|displa|displ|disp|dis|di|d { BEGIN(NOCMD); return tDISPLAY; } undisplay|undispla|undispl|undisp|undis|undi|und { BEGIN(NOCMD); return tUNDISPLAY; } delete|delet|dele|del { BEGIN(BD_CMD); return tDELETE; } +thread|threa|thre|thr|th { BEGIN(NOCMD); return tTHREAD; } quit|qui|qu|q { BEGIN(NOCMD); return tQUIT; } set|se { BEGIN(NOCMD); return tSET; } x { BEGIN(FORMAT_EXPECTED); return tEXAM; } diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h index d8d7a699fb4..40d93d669c8 100644 --- a/programs/winedbg/debugger.h +++ b/programs/winedbg/debugger.h @@ -427,6 +427,7 @@ extern enum sym_get_lval symbol_picker_scoped(const char* name, const struct sgv extern void dbg_run_debuggee(const char* args); 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); extern enum dbg_start dbg_active_launch(int argc, char* argv[]); extern enum dbg_start dbg_active_auto(int argc, char* argv[]); extern enum dbg_start dbg_active_minidump(int argc, char* argv[]); diff --git a/programs/winedbg/info.c b/programs/winedbg/info.c index bf5ba4f6e34..123cbc934ef 100644 --- a/programs/winedbg/info.c +++ b/programs/winedbg/info.c @@ -66,7 +66,7 @@ void print_help(void) " show dir dir ", " set = set * = ", " pass whatis", - " info (see 'help info' for options)", + " info (see 'help info' for options) thread ", "The 'x' command accepts repeat counts and formats (including 'i') in the", "same way that gdb does.\n", diff --git a/programs/winedbg/tgt_active.c b/programs/winedbg/tgt_active.c index 71e0bc1944d..2b38ce95de7 100644 --- a/programs/winedbg/tgt_active.c +++ b/programs/winedbg/tgt_active.c @@ -98,6 +98,29 @@ static unsigned dbg_fetch_context(void) return TRUE; } +BOOL dbg_set_curr_thread(DWORD tid) +{ + struct dbg_thread* thread; + + if (!dbg_curr_process) + { + dbg_printf("No process loaded\n"); + return FALSE; + } + + thread = dbg_get_thread(dbg_curr_process, tid); + if (thread) + { + dbg_curr_thread = thread; + dbg_fetch_context(); + stack_fetch_frames(&dbg_context); + dbg_curr_tid = tid; + return TRUE; + } + dbg_printf("No such thread\n"); + return thread != NULL; +} + /*********************************************************************** * dbg_exception_prolog * diff --git a/programs/winedbg/winedbg.man.in b/programs/winedbg/winedbg.man.in index 6f38bc07b97..6ed8d4474c4 100644 --- a/programs/winedbg/winedbg.man.in +++ b/programs/winedbg/winedbg.man.in @@ -116,6 +116,9 @@ IDs can be obtained using the \fBinfo\ process\fR command. Note the .IP .IP \fBdetach\fR Detach from a Wine-process. +.IP \fBthread\ \fIN\fR +Change the current thread to \fIN\fR (its Windows TID, numeric or hexadecimal). +.IP .PP \fIHelp commands\fR .IP \fBhelp\fR