- now storing exception info (if any) in thread structure
- added minidump function in winedbg (write only)
This commit is contained in:
parent
5c819a9895
commit
a561275579
|
@ -21,6 +21,7 @@ C_SRCS = \
|
|||
source.c \
|
||||
symbol.c \
|
||||
stack.c \
|
||||
tgt_minidump.c \
|
||||
types.c \
|
||||
winedbg.c
|
||||
|
||||
|
|
|
@ -57,7 +57,8 @@ int yyerror(const char*);
|
|||
%token tSTEPI tNEXTI tFINISH tSHOW tDIR tWHATIS tSOURCE
|
||||
%token <string> tPATH tIDENTIFIER tSTRING tDEBUGSTR tINTVAR
|
||||
%token <integer> tNUM tFORMAT
|
||||
%token tSYMBOLFILE tRUN tATTACH tDETACH tNOPROCESS tMAINTENANCE tTYPE
|
||||
%token tSYMBOLFILE tRUN tATTACH tDETACH tMAINTENANCE tTYPE tMINIDUMP
|
||||
%token tNOPROCESS
|
||||
|
||||
%token tCHAR tSHORT tINT tLONG tFLOAT tDOUBLE tUNSIGNED tSIGNED
|
||||
%token tSTRUCT tUNION tENUM
|
||||
|
@ -138,6 +139,7 @@ command:
|
|||
| tWHATIS expr_lvalue { types_print_type(&$2.type, FALSE); dbg_printf("\n"); }
|
||||
| tATTACH tNUM { dbg_attach_debuggee($2, FALSE, TRUE); }
|
||||
| tDETACH { dbg_detach_debuggee(); }
|
||||
| tMINIDUMP pathname { minidump_write($2, (dbg_curr_thread && dbg_curr_thread->in_exception) ? &dbg_curr_thread->excpt_record : NULL);}
|
||||
| run_command
|
||||
| list_command
|
||||
| disassemble_command
|
||||
|
|
|
@ -174,6 +174,7 @@ STRING \"[^\n"]+\"
|
|||
<INITIAL,NOPROCESS>run|ru|r { BEGIN(ASTRING_EXPECTED); return tRUN;}
|
||||
<INITIAL>detach|detac|deta|det { BEGIN(NOCMD); return tDETACH; }
|
||||
<INITIAL>maintenance|maint { BEGIN(MAINT_CMD); return tMAINTENANCE; }
|
||||
<INITIAL>minidump|mdmp { BEGIN(PATH_EXPECTED); return tMINIDUMP; }
|
||||
<NOPROCESS>attach|attac|atta|att { BEGIN(NOCMD); return tATTACH; }
|
||||
<INFO_CMD>share|shar|sha { return tSHARE; }
|
||||
<INFO_CMD>locals|local|loca|loc { return tLOCAL; }
|
||||
|
|
|
@ -168,6 +168,8 @@ struct dbg_thread
|
|||
char name[9];
|
||||
struct dbg_thread* next;
|
||||
struct dbg_thread* prev;
|
||||
BOOL in_exception; /* TRUE if thread stopped with an exception */
|
||||
EXCEPTION_RECORD excpt_record; /* only valid when in_exception is TRUE */
|
||||
};
|
||||
|
||||
struct dbg_delayed_bp
|
||||
|
@ -343,6 +345,9 @@ extern void symbol_info(const char* str);
|
|||
extern int symbol_info_locals(void);
|
||||
extern BOOL symbol_is_local(const char* name);
|
||||
|
||||
/* tgt_minidump.c */
|
||||
extern void minidump_write(const char*, const EXCEPTION_RECORD*);
|
||||
|
||||
/* types.c */
|
||||
extern void print_value(const struct dbg_lvalue* addr, char format, int level);
|
||||
extern int types_print_type(const struct dbg_type*, BOOL details);
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Wine debugger - minidump handling
|
||||
*
|
||||
* Copyright 2005 Eric Pouech
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "debugger.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "tlhelp32.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
|
||||
|
||||
void minidump_write(const char* file, const EXCEPTION_RECORD* rec)
|
||||
{
|
||||
HANDLE hFile;
|
||||
MINIDUMP_EXCEPTION_INFORMATION mei;
|
||||
EXCEPTION_POINTERS ep;
|
||||
DWORD wine_opt;
|
||||
|
||||
hFile = CreateFile(file, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE) return;
|
||||
|
||||
if (rec)
|
||||
{
|
||||
mei.ThreadId = dbg_curr_thread->tid;
|
||||
mei.ExceptionPointers = &ep;
|
||||
ep.ExceptionRecord = (EXCEPTION_RECORD*)rec;
|
||||
ep.ContextRecord = &dbg_context;
|
||||
mei.ClientPointers = FALSE;
|
||||
}
|
||||
/* this is a wine specific options to return also ELF modules in the
|
||||
* dumping
|
||||
*/
|
||||
SymSetOptions((wine_opt = SymGetOptions()) | 0x40000000);
|
||||
MiniDumpWriteDump(dbg_curr_process->handle, dbg_curr_process->pid,
|
||||
hFile, MiniDumpNormal/*|MiniDumpWithDataSegs*/,
|
||||
rec ? &mei : NULL, NULL, NULL);
|
||||
SymSetOptions(wine_opt);
|
||||
CloseHandle(hFile);
|
||||
}
|
|
@ -80,7 +80,6 @@ DWORD dbg_curr_pid;
|
|||
CONTEXT dbg_context;
|
||||
int dbg_curr_frame = 0;
|
||||
BOOL dbg_interactiveP = FALSE;
|
||||
static unsigned dbg_in_exception = FALSE;
|
||||
static char* dbg_last_cmd_line = NULL;
|
||||
|
||||
static struct dbg_process* dbg_process_list = NULL;
|
||||
|
@ -364,6 +363,7 @@ struct dbg_thread* dbg_add_thread(struct dbg_process* p, DWORD tid,
|
|||
t->exec_count = 0;
|
||||
t->step_over_bp.enabled = FALSE;
|
||||
t->step_over_bp.refcount = 0;
|
||||
t->in_exception = FALSE;
|
||||
|
||||
snprintf(t->name, sizeof(t->name), "0x%08lx", tid);
|
||||
|
||||
|
@ -449,7 +449,7 @@ BOOL dbg_detach_debuggee(void)
|
|||
*/
|
||||
be_cpu->single_step(&dbg_context, FALSE);
|
||||
SetThreadContext(dbg_curr_thread->handle, &dbg_context);
|
||||
if (dbg_in_exception)
|
||||
if (dbg_curr_thread->in_exception)
|
||||
ContinueDebugEvent(dbg_curr_pid, dbg_curr_tid, DBG_CONTINUE);
|
||||
if (!DebugActiveProcessStop(dbg_curr_pid)) return FALSE;
|
||||
dbg_del_process(dbg_curr_process);
|
||||
|
@ -476,14 +476,15 @@ static unsigned dbg_fetch_context(void)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static unsigned dbg_exception_prolog(BOOL is_debug, DWORD code)
|
||||
static unsigned dbg_exception_prolog(BOOL is_debug, const EXCEPTION_RECORD* rec)
|
||||
{
|
||||
ADDRESS addr;
|
||||
BOOL is_break;
|
||||
|
||||
dbg_in_exception = TRUE;
|
||||
memory_get_current_pc(&addr);
|
||||
break_suspend_execution();
|
||||
dbg_curr_thread->excpt_record = *rec;
|
||||
dbg_curr_thread->in_exception = TRUE;
|
||||
|
||||
if (!is_debug)
|
||||
{
|
||||
|
@ -507,7 +508,7 @@ static unsigned dbg_exception_prolog(BOOL is_debug, DWORD code)
|
|||
*/
|
||||
stack_backtrace(dbg_curr_tid, FALSE);
|
||||
if (is_debug &&
|
||||
break_should_continue(&addr, code, &dbg_curr_thread->exec_count, &is_break))
|
||||
break_should_continue(&addr, rec->ExceptionCode, &dbg_curr_thread->exec_count, &is_break))
|
||||
return FALSE;
|
||||
|
||||
if (addr.Mode != dbg_curr_thread->addr_mode)
|
||||
|
@ -559,10 +560,10 @@ static void dbg_exception_epilog(void)
|
|||
*/
|
||||
if (dbg_curr_thread->exec_mode == dbg_exec_cont)
|
||||
dbg_curr_thread->exec_count = 0;
|
||||
dbg_in_exception = FALSE;
|
||||
dbg_curr_thread->in_exception = FALSE;
|
||||
}
|
||||
|
||||
static DWORD dbg_handle_exception(EXCEPTION_RECORD* rec, BOOL first_chance)
|
||||
static DWORD dbg_handle_exception(const EXCEPTION_RECORD* rec, BOOL first_chance)
|
||||
{
|
||||
BOOL is_debug = FALSE;
|
||||
THREADNAME_INFO* pThreadName;
|
||||
|
@ -712,12 +713,12 @@ static DWORD dbg_handle_exception(EXCEPTION_RECORD* rec, BOOL first_chance)
|
|||
|
||||
if (dbg_action_mode == automatic_mode)
|
||||
{
|
||||
dbg_exception_prolog(is_debug, rec->ExceptionCode);
|
||||
dbg_exception_prolog(is_debug, rec);
|
||||
dbg_exception_epilog();
|
||||
return 0; /* terminate execution */
|
||||
}
|
||||
|
||||
if (dbg_exception_prolog(is_debug, rec->ExceptionCode))
|
||||
if (dbg_exception_prolog(is_debug, rec))
|
||||
{
|
||||
dbg_interactiveP = TRUE;
|
||||
return 0;
|
||||
|
@ -941,7 +942,7 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de)
|
|||
|
||||
static void dbg_resume_debuggee(DWORD cont)
|
||||
{
|
||||
if (dbg_in_exception)
|
||||
if (dbg_curr_thread->in_exception)
|
||||
{
|
||||
ADDRESS addr;
|
||||
|
||||
|
|
Loading…
Reference in New Issue