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

improved exception handling

merged all module handling code in new module.c file reenabled 'walk module' and 'info module' commands added ability to drive break on thread startup
parent 323af8db
......@@ -15,6 +15,7 @@ C_SRCS = \
hash.c \
info.c \
memory.c \
module.c \
msc.c \
registers.c \
source.c \
......
......@@ -208,7 +208,6 @@ void DEBUG_SetBreakpoints( BOOL set )
}
*lpdr = DEBUG_ToLinear(&breakpoints[i].addr);
fprintf(stderr, "Setting DR%d %08lx\n", (lpdr - &DEBUG_context.Dr0) / 4, *lpdr);
bits = (breakpoints[i].u.w.rw) ? DR7_RW_WRITE : DR7_RW_READ;
switch (breakpoints[i].u.w.len + 1)
{
......@@ -226,7 +225,6 @@ void DEBUG_SetBreakpoints( BOOL set )
break;
}
}
fprintf(stderr, "Setting DR7 %08lx\n", DEBUG_context.Dr7);
}
/***********************************************************************
......
......@@ -398,8 +398,9 @@ static void mode_command(int newmode)
else fprintf(stderr,"Invalid mode (use 16 or 32)\n");
}
static WINE_EXCEPTION_FILTER(wine_dbg)
static WINE_EXCEPTION_FILTER(wine_dbg_cmd)
{
fprintf(stderr, "\nwine_dbg_cmd: ");
switch (GetExceptionCode()) {
case DEBUG_STATUS_INTERNAL_ERROR:
fprintf(stderr, "WineDbg internal error\n");
......@@ -537,7 +538,7 @@ BOOL DEBUG_Main( BOOL is_debug, BOOL force, DWORD code )
if ((ret_ok = DEBUG_ValidateRegisters()))
ret_ok = DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear( &addr ), &ch, 1 );
}
__EXCEPT(wine_dbg)
__EXCEPT(wine_dbg_cmd)
{
ret_ok = 0;
}
......
......@@ -11,6 +11,7 @@
#include <assert.h>
#include "windef.h"
#include "winbase.h"
#include "wine/exception.h"
#ifdef __i386__
#define STEP_FLAG 0x00000100 /* single step flag */
......@@ -135,8 +136,8 @@ typedef struct
struct expr * condition;
} BREAKPOINT;
typedef struct tagWINE_DBG_THREAD {
struct tagWINE_DBG_PROCESS* process;
typedef struct tagDBG_THREAD {
struct tagDBG_PROCESS* process;
HANDLE handle;
DWORD tid;
LPVOID start;
......@@ -146,20 +147,29 @@ typedef struct tagWINE_DBG_THREAD {
enum exec_mode dbg_exec_mode;
int dbg_exec_count;
BREAKPOINT stepOverBP;
struct tagWINE_DBG_THREAD* next;
struct tagWINE_DBG_THREAD* prev;
} WINE_DBG_THREAD;
struct tagDBG_THREAD* next;
struct tagDBG_THREAD* prev;
} DBG_THREAD;
typedef struct tagWINE_DBG_PROCESS {
typedef struct tagDBG_PROCESS {
HANDLE handle;
DWORD pid;
WINE_DBG_THREAD* threads;
struct tagWINE_DBG_PROCESS* next;
struct tagWINE_DBG_PROCESS* prev;
} WINE_DBG_PROCESS;
DBG_THREAD* threads;
int num_threads;
struct tagDBG_MODULE* modules;
/*
* This is an index we use to keep track of the debug information
* when we have multiple sources. We use the same database to also
* allow us to do an 'info shared' type of deal, and we use the index
* to eliminate duplicates.
*/
int next_index;
struct tagDBG_PROCESS* next;
struct tagDBG_PROCESS* prev;
} DBG_PROCESS;
extern WINE_DBG_PROCESS* DEBUG_CurrProcess;
extern WINE_DBG_THREAD* DEBUG_CurrThread;
extern DBG_PROCESS* DEBUG_CurrProcess;
extern DBG_THREAD* DEBUG_CurrThread;
extern CONTEXT DEBUG_context;
#define DEBUG_READ_MEM(addr, buf, len) \
......@@ -174,6 +184,28 @@ extern CONTEXT DEBUG_context;
#define DEBUG_WRITE_MEM_VERBOSE(addr, buf, len) \
(DEBUG_WRITE_MEM((addr), (buf), (len)) || (DEBUG_InvalLinAddr( addr ),0))
typedef struct tagDBG_MODULE {
struct tagDBG_MODULE* next;
void* load_addr;
char* module_name;
char status;
char type;
short int dbg_index;
HMODULE handle;
void* extra_info;
} DBG_MODULE;
/* status field */
#define DM_STATUS_NEW 0
#define DM_STATUS_LOADED 1
#define DM_STATUS_ERROR 2
/* type field */
#define DM_TYPE_UNKNOWN 0
#define DM_TYPE_ELF 1
#define DM_TYPE_NE 2
#define DM_TYPE_PE 3
#ifdef __i386__
#ifdef REG_SP /* Some Sun includes define this */
#undef REG_SP
......@@ -249,7 +281,6 @@ extern const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
unsigned int ebp,
struct list_id * source);
extern void DEBUG_ReadSymbolTable( const char * filename );
extern int DEBUG_LoadEntryPoints( const char * prefix );
extern void DEBUG_AddLineNumber( struct name_hash * func, int line_num,
unsigned long offset );
extern struct wine_locals *
......@@ -270,7 +301,7 @@ extern BOOL DEBUG_GetLineNumberAddr( struct name_hash *, const int lineno,
extern int DEBUG_SetLocalSymbolType(struct wine_locals * sym,
struct datatype * type);
BOOL DEBUG_Normalize(struct name_hash * nh );
extern BOOL DEBUG_Normalize(struct name_hash * nh );
/* debugger/info.c */
extern void DEBUG_PrintBasic( const DBG_VALUE* value, int count, char format );
......@@ -309,6 +340,24 @@ extern int DEBUG_GetSelectorType( WORD sel );
extern int DEBUG_IsSelectorSystem( WORD sel );
#endif
/* debugger/module.c */
extern int DEBUG_LoadEntryPoints( const char * prefix );
extern void DEBUG_LoadModule32( const char* name, DWORD base );
extern DBG_MODULE* DEBUG_AddModule(const char* name, int type,
void* mod_addr, HMODULE hmod);
extern DBG_MODULE* DEBUG_FindModuleByName(const char* name, int type);
extern DBG_MODULE* DEBUG_FindModuleByHandle(HANDLE handle, int type);
extern DBG_MODULE* DEBUG_RegisterPEModule(HMODULE, u_long load_addr, const char* name);
extern DBG_MODULE* DEBUG_RegisterELFModule(u_long load_addr, const char* name);
extern int DEBUG_ProcessDeferredDebug(void);
extern void DEBUG_InfoShare(void);
/* debugger/msc.c */
extern int DEBUG_RegisterMSCDebugInfo(DBG_MODULE* module, void* nth, unsigned long nth_ofs);
extern int DEBUG_RegisterStabsDebugInfo(DBG_MODULE* module, void* nth, unsigned long nth_ofs);
extern void DEBUG_InitCVDataTypes(void);
extern int DEBUG_ProcessMSCDebugInfo(DBG_MODULE* module);
/* debugger/registers.c */
extern void DEBUG_SetRegister( enum debug_regs reg, int val );
extern int DEBUG_GetRegister( enum debug_regs reg );
......@@ -330,13 +379,6 @@ extern int DEBUG_ReadExecutableDbgInfo(void);
extern int DEBUG_ParseStabs(char * addr, unsigned int load_offset, unsigned int staboff,
int stablen, unsigned int strtaboff, int strtablen);
/* debugger/msc.c */
extern int DEBUG_RegisterDebugInfo( HMODULE, const char *);
extern int DEBUG_ProcessDeferredDebug(void);
extern int DEBUG_RegisterELFDebugInfo(int load_addr, u_long size, const char * name);
extern void DEBUG_InfoShare(void);
extern void DEBUG_InitCVDataTypes(void);
/* debugger/types.c */
extern int DEBUG_nchar;
extern void DEBUG_InitTypes(void);
......
......@@ -11,11 +11,7 @@
#include <string.h>
#include <limits.h>
#include <sys/types.h>
#include "neexe.h"
#include "module.h"
#include "process.h"
#include "debugger.h"
#include "toolhelp.h"
#define NR_NAME_HASH 16384
#ifndef PATH_MAX
......@@ -771,259 +767,6 @@ void DEBUG_ReadSymbolTable( const char * filename )
}
/***********************************************************************
* DEBUG_LoadEntryPoints16
*
* Load the entry points of a Win16 module into the hash table.
*/
static void DEBUG_LoadEntryPoints16( HMODULE16 hModule, NE_MODULE *pModule,
const char *name )
{
DBG_VALUE value;
char buffer[256];
FARPROC16 address;
unsigned char *cpnt = (unsigned char *)pModule + pModule->name_table;
value.type = NULL;
value.cookie = DV_TARGET;
value.addr.seg = 0;
value.addr.off = 0;
/* First search the resident names */
while (*cpnt)
{
cpnt += *cpnt + 1 + sizeof(WORD);
sprintf( buffer, "%s.%.*s", name, *cpnt, cpnt + 1 );
if ((address = NE_GetEntryPoint(hModule, *(WORD *)(cpnt + *cpnt + 1))))
{
value.addr.seg = HIWORD(address);
value.addr.off = LOWORD(address);
DEBUG_AddSymbol( buffer, &value, NULL, SYM_WIN32 | SYM_FUNC );
}
}
/* Now search the non-resident names table */
if (!pModule->nrname_handle) return; /* No non-resident table */
cpnt = (char *)GlobalLock16( pModule->nrname_handle );
while (*cpnt)
{
cpnt += *cpnt + 1 + sizeof(WORD);
sprintf( buffer, "%s.%.*s", name, *cpnt, cpnt + 1 );
if ((address = NE_GetEntryPoint(hModule, *(WORD *)(cpnt + *cpnt + 1))))
{
value.addr.seg = HIWORD(address);
value.addr.off = LOWORD(address);
DEBUG_AddSymbol( buffer, &value, NULL, SYM_WIN32 | SYM_FUNC );
}
}
}
/***********************************************************************
* DEBUG_LoadEntryPoints32
*
* Load the entry points of a Win32 module into the hash table.
*/
static void DEBUG_LoadEntryPoints32( HMODULE hModule, const char *name )
{
#define RVA(x) (hModule+(DWORD)(x))
DBG_VALUE value;
char buffer[256];
int i, j;
IMAGE_SECTION_HEADER *pe_seg;
IMAGE_EXPORT_DIRECTORY *exports;
IMAGE_DATA_DIRECTORY *dir;
WORD *ordinals;
void **functions;
const char **names;
value.type = NULL;
value.cookie = DV_TARGET;
value.addr.seg = 0;
value.addr.off = 0;
/* Add start of DLL */
value.addr.off = hModule;
DEBUG_AddSymbol( name, &value, NULL, SYM_WIN32 | SYM_FUNC );
/* Add entry point */
sprintf( buffer, "%s.EntryPoint", name );
value.addr.off = (DWORD)RVA_PTR( hModule, OptionalHeader.AddressOfEntryPoint );
DEBUG_AddSymbol( buffer, &value, NULL, SYM_WIN32 | SYM_FUNC );
/* Add start of sections */
pe_seg = PE_SECTIONS(hModule);
for (i = 0; i < PE_HEADER(hModule)->FileHeader.NumberOfSections; i++)
{
sprintf( buffer, "%s.%s", name, pe_seg->Name );
value.addr.off = RVA(pe_seg->VirtualAddress );
DEBUG_AddSymbol( buffer, &value, NULL, SYM_WIN32 | SYM_FUNC );
pe_seg++;
}
/* Add exported functions */
dir = &PE_HEADER(hModule)->OptionalHeader.
DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
if (dir->Size)
{
exports = (IMAGE_EXPORT_DIRECTORY *)RVA( dir->VirtualAddress );
ordinals = (WORD *)RVA( exports->AddressOfNameOrdinals );
names = (const char **)RVA( exports->AddressOfNames );
functions = (void **)RVA( exports->AddressOfFunctions );
for (i = 0; i < exports->NumberOfNames; i++)
{
if (!names[i]) continue;
sprintf( buffer, "%s.%s", name, (char *)RVA(names[i]) );
value.addr.off = RVA( functions[ordinals[i]] );
DEBUG_AddSymbol( buffer, &value, NULL, SYM_WIN32 | SYM_FUNC );
}
for (i = 0; i < exports->NumberOfFunctions; i++)
{
if (!functions[i]) continue;
/* Check if we already added it with a name */
for (j = 0; j < exports->NumberOfNames; j++)
if ((ordinals[j] == i) && names[j]) break;
if (j < exports->NumberOfNames) continue;
sprintf( buffer, "%s.%ld", name, i + exports->Base );
value.addr.off = (DWORD)RVA( functions[i] );
DEBUG_AddSymbol( buffer, &value, NULL, SYM_WIN32 | SYM_FUNC );
}
}
DEBUG_RegisterDebugInfo(hModule, name);
#undef RVA
}
typedef struct tag_lmr{
char* module_name;
BOOL is16;
struct tag_lmr* next;
} DBG_LoadedModuleRef;
typedef struct {
int rowcount;
int first;
const char* pfx;
} DBG_LEPData;
static BOOL DEBUG_LEPHelper(const char* mod_name, BOOL is16, DBG_LEPData* lep)
{
static DBG_LoadedModuleRef* lmr = NULL;
DBG_LoadedModuleRef* p;
DBG_LoadedModuleRef** pp1;
DBG_LoadedModuleRef* p2;
int len = strlen(mod_name);
int cmp;
for (p = lmr; p; p = p->next) {
cmp = strcasecmp(p->module_name, mod_name);
if (cmp == 0 && p->is16 == is16)
return FALSE;
if (cmp >= 0)
break;
}
if (!lep->first) {
if (lep->pfx) fprintf( stderr, lep->pfx );
fprintf( stderr, " " );
lep->first++;
lep->rowcount = 3;
}
if ((lep->rowcount + len) > 76)
{
fprintf( stderr, "\n ");
lep->rowcount = 3;
}
fprintf( stderr, " %s", mod_name );
lep->rowcount += len + 1;
p = DBG_alloc(sizeof(*lmr));
p->module_name = DBG_strdup(mod_name);
p->is16 = is16;
p2 = NULL;
for (pp1 = &lmr; *pp1; pp1 = &(*pp1)->next) {
if (strcasecmp((*pp1)->module_name, mod_name) > 0)
break;
p2 = *pp1;
}
if (p2 == NULL)
{
p->next = lmr;
lmr = p;
}
else if (*pp1 == NULL)
{
p->next = NULL;
*pp1 = p;
}
else
{
p->next = *pp1;
p2->next = p;
}
return TRUE;
}
/***********************************************************************
* DEBUG_LoadEntryPoints
*
* Load the entry points of all the modules into the hash table.
*/
int DEBUG_LoadEntryPoints(const char* pfx)
{
MODULEENTRY entry;
NE_MODULE* pModule;
BOOL ok;
WINE_MODREF*wm;
DBG_LEPData lep;
PDB* current = PROCESS_Current();
lep.first = 0;
lep.pfx = pfx;
/* FIXME: we assume that a module is never removed from memory */
for (ok = ModuleFirst16(&entry); ok; ok = ModuleNext16(&entry))
{
if (!(pModule = NE_GetPtr( entry.hModule ))) continue;
if (!(pModule->flags & NE_FFLAGS_WIN32) && /* NE module */
DEBUG_LEPHelper( entry.szModule, TRUE, &lep ))
DEBUG_LoadEntryPoints16( entry.hModule, pModule, entry.szModule );
}
for (wm = current->modref_list; wm; wm=wm->next)
{
if ((wm->flags & WINE_MODREF_INTERNAL))
{
if (DEBUG_LEPHelper( wm->modname, FALSE, &lep ))
DEBUG_LoadEntryPoints32( wm->module, wm->modname );
}
}
if (lep.first) fprintf( stderr, " $");
for (wm = current->modref_list; wm; wm=wm->next)
{
if (!(wm->flags & WINE_MODREF_INTERNAL))
{
if (DEBUG_LEPHelper( wm->modname, FALSE, &lep ))
DEBUG_LoadEntryPoints32( wm->module, wm->modname );
}
}
if (lep.first) fprintf( stderr, "\n" );
return lep.first;
}
void
DEBUG_AddLineNumber( struct name_hash * func, int line_num,
unsigned long offset )
......
......@@ -344,16 +344,6 @@ void DEBUG_WalkClasses(void)
DBG_free(cw.table);
}
void DEBUG_DumpModule(DWORD mod)
{
fprintf(stderr, "No longer doing info module '0x%08lx'\n", mod);
}
void DEBUG_WalkModules(void)
{
fprintf(stderr, "No longer walking modules list\n");
}
void DEBUG_DumpQueue(DWORD q)
{
fprintf(stderr, "No longer doing info queue '0x%08lx'\n", q);
......
......@@ -1237,9 +1237,9 @@ DEBUG_ProcessElfObject(const char * filename, unsigned int load_offset)
ehptr = (Elf32_Ehdr *) addr;
if( load_offset == 0 )
DEBUG_RegisterELFDebugInfo(ehptr->e_entry, statbuf.st_size, filename);
DEBUG_RegisterELFModule(ehptr->e_entry, filename);
else
DEBUG_RegisterELFDebugInfo(load_offset, statbuf.st_size, filename);
DEBUG_RegisterELFModule(load_offset, filename);
spnt = (Elf32_Shdr *) (addr + ehptr->e_shoff);
nsect = ehptr->e_shnum;
......
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