Commit a5612755 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

- now storing exception info (if any) in thread structure

- added minidump function in winedbg (write only)
parent 5c819a98
......@@ -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);
......
/*
* 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;
......
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