Commit 48210fc3 authored by Mike Hearn's avatar Mike Hearn Committed by Alexandre Julliard

Add a --command option to winedbg, add an "all" option to the

backtrace command.
parent 38affc40
......@@ -47,7 +47,7 @@ int yyerror(const char*);
struct type_expr_t type;
}
%token tCONT tPASS tSTEP tLIST tNEXT tQUIT tHELP tBACKTRACE tINFO tUP tDOWN
%token tCONT tPASS tSTEP tLIST tNEXT tQUIT tHELP tBACKTRACE tALL tINFO tUP tDOWN
%token tENABLE tDISABLE tBREAK tWATCH tDELETE tSET tMODE tPRINT tEXAM tABORT tVM86
%token tCLASS tMAPS tSTACK tSEGMENTS tSYMBOL tREGS tWND tQUEUE tLOCAL tEXCEPTION
%token tPROCESS tTHREAD tMODREF tEOL tEOF
......@@ -119,6 +119,7 @@ command:
| tABORT { abort(); }
| tBACKTRACE { stack_backtrace(dbg_curr_tid, TRUE); }
| tBACKTRACE tNUM { stack_backtrace($2, TRUE); }
| tBACKTRACE tALL { stack_backtrace(-1, TRUE); }
| tUP { stack_set_frame(dbg_curr_frame + 1); }
| tUP tNUM { stack_set_frame(dbg_curr_frame + $2); }
| tDOWN { stack_set_frame(dbg_curr_frame - 1); }
......@@ -273,8 +274,9 @@ maintenance_command:
;
noprocess_state:
tNOPROCESS {} /* <CR> shall not barf anything */
| tNOPROCESS tSTRING { dbg_printf("No process loaded, cannot execute '%s'\n", $2); }
tNOPROCESS {} /* <CR> shall not barf anything */
| tNOPROCESS tBACKTRACE tALL { stack_backtrace(-1, TRUE); } /* can backtrace all threads with no attached process */
| tNOPROCESS tSTRING { dbg_printf("No process loaded, cannot execute '%s'\n", $2); }
;
type_expr:
......@@ -449,11 +451,20 @@ static void stripwhite(char *string)
static HANDLE dbg_parser_input;
static HANDLE dbg_parser_output;
/* command passed in the command line arguments */
char *arg_command = NULL;
int input_fetch_entire_line(const char* pfx, char** line, size_t* alloc, BOOL check_nl)
{
char buf_line[256];
DWORD nread;
size_t len;
if (arg_command) {
*line = arg_command;
arg_command = "quit\n"; /* we only run one command before exiting */
return 1;
}
/* as of today, console handles can be file handles... so better use file APIs rather than
* console's
......@@ -501,7 +512,7 @@ int input_read_line(const char* pfx, char* buf, int size)
assert(line);
line[0] = '\n';
line[1] = '\0';
input_fetch_entire_line(pfx, &line, &len, FALSE);
len = strlen(line);
/* remove trailing \n */
......
......@@ -143,8 +143,8 @@ STRING \"[^\n"]+\"
<INITIAL>x { BEGIN(FORMAT_EXPECTED); return tEXAM; }
<INITIAL,NOPROCESS>help|hel|he|"?" { BEGIN(HELP_CMD); return tHELP; }
<INITIAL>backtrace|backtrac|backtra|backt|back|bac|ba|bt { BEGIN(NOCMD); return tBACKTRACE; }
<INITIAL>where|wher|whe { BEGIN(NOCMD); return tBACKTRACE; }
<INITIAL,NOPROCESS>backtrace|backtrac|backtra|backt|back|bac|ba|bt { BEGIN(NOCMD); return tBACKTRACE; }
<INITIAL,NOPROCESS>where|wher|whe { BEGIN(NOCMD); return tBACKTRACE; }
<INITIAL>cont|con|co|c { BEGIN(NOCMD); return tCONT; }
<INITIAL>pass|pas|pa { BEGIN(NOCMD); return tPASS; }
......@@ -200,6 +200,7 @@ signed { return tSIGNED; }
struct { return tSTRUCT; }
union { return tUNION; }
enum { return tENUM; }
all { return tALL; }
{IDENTIFIER} { yylval.string = lexeme_alloc(yytext); return tIDENTIFIER; }
"$"{IDENTIFIER} { yylval.string = lexeme_alloc(yytext+1); return tINTVAR; }
......
......@@ -109,6 +109,8 @@ enum dbg_exec_mode
#endif
};
extern char *arg_command;
struct dbg_breakpoint
{
ADDRESS addr;
......
......@@ -28,6 +28,7 @@
#include "stackframe.h"
#include "winbase.h"
#include "wine/debug.h"
#include "tlhelp32.h"
WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
......@@ -103,6 +104,48 @@ void stack_backtrace(DWORD tid, BOOL noisy)
struct dbg_thread* thread;
unsigned nf;
if (tid == -1) /* backtrace every thread in every process except the debugger itself, invoking via "bt all" */
{
THREADENTRY32 entry;
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (snapshot == INVALID_HANDLE_VALUE) {
dbg_printf("unable to create toolhelp snapshot\n");
return;
}
entry.dwSize = sizeof(entry);
if (!Thread32First(snapshot, &entry)) {
CloseHandle(snapshot);
return;
}
do {
if (entry.th32OwnerProcessID == GetCurrentProcessId()) continue;
if (dbg_curr_process) dbg_detach_debuggee();
dbg_printf("\n");
if (!dbg_attach_debuggee(entry.th32OwnerProcessID, FALSE, TRUE)) {
dbg_printf("\nwarning: could not attach to 0x%lx\n", entry.th32OwnerProcessID);
continue;
}
dbg_printf("Backtracing for thread 0x%lx in process 0x%lx (%s):\n", entry.th32ThreadID, dbg_curr_pid, dbg_curr_process->imageName);
stack_backtrace(entry.th32ThreadID, TRUE);
} while (Thread32Next(snapshot, &entry));
if (dbg_curr_process) dbg_detach_debuggee();
CloseHandle(snapshot);
return;
}
if (!dbg_curr_process) {
dbg_printf("You must be attached to a process to run this command.\n");
return;
}
if (tid == dbg_curr_tid)
{
ctx = dbg_context; /* as StackWalk may modify it... */
......
......@@ -1102,6 +1102,15 @@ int main(int argc, char** argv)
/* parse options */
while (argc > 1 && argv[1][0] == '-')
{
if (!strcmp(argv[1], "--command"))
{
argc--; argv++;
arg_command = HeapAlloc(GetProcessHeap(), 0, strlen(argv[1])+2);
strcpy(arg_command, argv[1]);
strcat(arg_command, "\n");
argc--; argv++;
continue;
}
if (!strcmp(argv[1], "--auto"))
{
if (dbg_action_mode != none_mode) return dbg_winedbg_usage();
......
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