mirror of
git://source.winehq.org/git/wine.git
synced 2024-08-31 13:44:24 +00:00
Add a --command option to winedbg, add an "all" option to the
backtrace command.
This commit is contained in:
parent
38affc4097
commit
48210fc3e4
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue