mirror of
https://github.com/reactos/wine.git
synced 2025-02-13 08:44:54 +00:00
- started infrastructure for proper multi-target support (active
process, minidump...) - all read/write memory ops are now done thru a centralized process_io facility - minor fixes & cleanups in CPU backends
This commit is contained in:
parent
3c3495ea51
commit
d6be549a76
@ -21,6 +21,7 @@ C_SRCS = \
|
|||||||
source.c \
|
source.c \
|
||||||
symbol.c \
|
symbol.c \
|
||||||
stack.c \
|
stack.c \
|
||||||
|
tgt_active.c \
|
||||||
tgt_minidump.c \
|
tgt_minidump.c \
|
||||||
types.c \
|
types.c \
|
||||||
winedbg.c
|
winedbg.c
|
||||||
|
@ -82,9 +82,9 @@ static void be_alpha_disasm_one_insn(ADDRESS* addr, int display)
|
|||||||
dbg_printf("Disasm NIY\n");
|
dbg_printf("Disasm NIY\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned be_alpha_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx,
|
static unsigned be_alpha_insert_Xpoint(HANDLE hProcess, struct be_process_io* pio,
|
||||||
enum be_xpoint_type type, void* addr,
|
CONTEXT* ctx, enum be_xpoint_type type,
|
||||||
unsigned long* val, unsigned size)
|
void* addr, unsigned long* val, unsigned size)
|
||||||
{
|
{
|
||||||
unsigned long xbp;
|
unsigned long xbp;
|
||||||
unsigned long sz;
|
unsigned long sz;
|
||||||
@ -93,9 +93,9 @@ static unsigned be_alpha_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx,
|
|||||||
{
|
{
|
||||||
case be_xpoint_break:
|
case be_xpoint_break:
|
||||||
if (!size) return 0;
|
if (!size) return 0;
|
||||||
if (!ReadProcessMemory(hProcess, addr, val, 4, &sz) || sz != 4) return 0;
|
if (!pio->read(hProcess, addr, val, 4, &sz) || sz != 4) return 0;
|
||||||
xbp = 0x7d821008; /* 7d 82 10 08 ... in big endian */
|
xbp = 0x7d821008; /* 7d 82 10 08 ... in big endian */
|
||||||
if (!WriteProcessMemory(hProcess, addr, &xbp, 4, &sz) || sz != 4) return 0;
|
if (!pio->write(hProcess, addr, &xbp, 4, &sz) || sz != 4) return 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dbg_printf("Unknown/unsupported bp type %c\n", type);
|
dbg_printf("Unknown/unsupported bp type %c\n", type);
|
||||||
@ -130,14 +130,14 @@ static int be_alpha_adjust_pc_for_break(CONTEXT* ctx, BOOL way)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int be_alpha_fetch_integer(const struct dbg_lvalue* lvalue, unsigned size,
|
static int be_alpha_fetch_integer(const struct dbg_lvalue* lvalue, unsigned size,
|
||||||
unsigned ext_sign, long long int* ret)
|
unsigned ext_sign, long long int* ret)
|
||||||
{
|
{
|
||||||
dbg_printf("not done\n");
|
dbg_printf("not done\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int be_alpha_fetch_float(const struct dbg_lvalue* lvalue, unsigned size,
|
static int be_alpha_fetch_float(const struct dbg_lvalue* lvalue, unsigned size,
|
||||||
long double* ret)
|
long double* ret)
|
||||||
{
|
{
|
||||||
dbg_printf("not done\n");
|
dbg_printf("not done\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -82,13 +82,13 @@ struct backend_cpu
|
|||||||
* break points / watchpoints handling
|
* break points / watchpoints handling
|
||||||
* -------------------------------------------------------------------------------*/
|
* -------------------------------------------------------------------------------*/
|
||||||
/* Inserts an Xpoint in the CPU context and/or debuggee address space */
|
/* Inserts an Xpoint in the CPU context and/or debuggee address space */
|
||||||
unsigned (*insert_Xpoint)(HANDLE hProcess, CONTEXT* ctx,
|
unsigned (*insert_Xpoint)(HANDLE hProcess, struct be_process_io* pio,
|
||||||
enum be_xpoint_type type, void* addr,
|
CONTEXT* ctx, enum be_xpoint_type type,
|
||||||
unsigned long* val, unsigned size);
|
void* addr, unsigned long* val, unsigned size);
|
||||||
/* Removes an Xpoint in the CPU context and/or debuggee address space */
|
/* Removes an Xpoint in the CPU context and/or debuggee address space */
|
||||||
unsigned (*remove_Xpoint)(HANDLE hProcess, CONTEXT* ctx,
|
unsigned (*remove_Xpoint)(HANDLE hProcess, struct be_process_io* pio,
|
||||||
enum be_xpoint_type type, void* addr,
|
CONTEXT* ctx, enum be_xpoint_type type,
|
||||||
unsigned long val, unsigned size);
|
void* addr, unsigned long val, unsigned size);
|
||||||
/* Checks whether a given watchpoint has been triggered */
|
/* Checks whether a given watchpoint has been triggered */
|
||||||
unsigned (*is_watchpoint_set)(const CONTEXT* ctx, unsigned idx);
|
unsigned (*is_watchpoint_set)(const CONTEXT* ctx, unsigned idx);
|
||||||
/* Clears the watchpoint indicator */
|
/* Clears the watchpoint indicator */
|
||||||
|
@ -304,7 +304,7 @@ static unsigned be_i386_is_break_insn(const void* insn)
|
|||||||
{
|
{
|
||||||
BYTE c;
|
BYTE c;
|
||||||
|
|
||||||
if (!dbg_read_memory(insn, &c, 1)) return FALSE;
|
if (!dbg_read_memory(insn, &c, sizeof(c))) return FALSE;
|
||||||
return c == 0xCC;
|
return c == 0xCC;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,9 +313,10 @@ static unsigned be_i386_is_func_call(const void* insn, ADDRESS* callee)
|
|||||||
BYTE ch;
|
BYTE ch;
|
||||||
int delta;
|
int delta;
|
||||||
|
|
||||||
dbg_read_memory(insn, &ch, sizeof(ch));
|
if (!dbg_read_memory(insn, &ch, sizeof(ch))) return FALSE;
|
||||||
if (ch == 0xe8)
|
switch (ch)
|
||||||
{
|
{
|
||||||
|
case 0xe8:
|
||||||
dbg_read_memory((const char*)insn + 1, &delta, sizeof(delta));
|
dbg_read_memory((const char*)insn + 1, &delta, sizeof(delta));
|
||||||
|
|
||||||
callee->Mode = AddrModeFlat;
|
callee->Mode = AddrModeFlat;
|
||||||
@ -324,8 +325,19 @@ static unsigned be_i386_is_func_call(const void* insn, ADDRESS* callee)
|
|||||||
callee->Offset += delta;
|
callee->Offset += delta;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
case 0xff:
|
||||||
|
if (!dbg_read_memory((const char*)insn + 1, &ch, sizeof(ch)))
|
||||||
|
return FALSE;
|
||||||
|
ch &= 0x38;
|
||||||
|
if (ch != 0x10 && ch != 0x18) return FALSE;
|
||||||
|
/* fall through */
|
||||||
|
case 0x9c:
|
||||||
|
case 0xCD:
|
||||||
|
WINE_FIXME("Unsupported yet call insn (0x%02x) at %p\n", ch, insn);
|
||||||
|
/* fall through */
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DR7_CONTROL_SHIFT 16
|
#define DR7_CONTROL_SHIFT 16
|
||||||
@ -380,9 +392,9 @@ static inline int be_i386_get_unused_DR(CONTEXT* ctx, unsigned long** r)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned be_i386_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx,
|
static unsigned be_i386_insert_Xpoint(HANDLE hProcess, struct be_process_io* pio,
|
||||||
enum be_xpoint_type type, void* addr,
|
CONTEXT* ctx, enum be_xpoint_type type,
|
||||||
unsigned long* val, unsigned size)
|
void* addr, unsigned long* val, unsigned size)
|
||||||
{
|
{
|
||||||
unsigned char ch;
|
unsigned char ch;
|
||||||
unsigned long sz;
|
unsigned long sz;
|
||||||
@ -394,10 +406,10 @@ static unsigned be_i386_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx,
|
|||||||
{
|
{
|
||||||
case be_xpoint_break:
|
case be_xpoint_break:
|
||||||
if (size != 0) return 0;
|
if (size != 0) return 0;
|
||||||
if (!ReadProcessMemory(hProcess, addr, &ch, 1, &sz) || sz != 1) return 0;
|
if (!pio->read(hProcess, addr, &ch, 1, &sz) || sz != 1) return 0;
|
||||||
*val = ch;
|
*val = ch;
|
||||||
ch = 0xcc;
|
ch = 0xcc;
|
||||||
if (!WriteProcessMemory(hProcess, addr, &ch, 1, &sz) || sz != 1) return 0;
|
if (!pio->write(hProcess, addr, &ch, 1, &sz) || sz != 1) return 0;
|
||||||
break;
|
break;
|
||||||
case be_xpoint_watch_exec:
|
case be_xpoint_watch_exec:
|
||||||
bits = DR7_RW_EXECUTE;
|
bits = DR7_RW_EXECUTE;
|
||||||
@ -431,9 +443,9 @@ static unsigned be_i386_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned be_i386_remove_Xpoint(HANDLE hProcess, CONTEXT* ctx,
|
static unsigned be_i386_remove_Xpoint(HANDLE hProcess, struct be_process_io* pio,
|
||||||
enum be_xpoint_type type, void* addr,
|
CONTEXT* ctx, enum be_xpoint_type type,
|
||||||
unsigned long val, unsigned size)
|
void* addr, unsigned long val, unsigned size)
|
||||||
{
|
{
|
||||||
unsigned long sz;
|
unsigned long sz;
|
||||||
unsigned char ch;
|
unsigned char ch;
|
||||||
@ -442,12 +454,12 @@ static unsigned be_i386_remove_Xpoint(HANDLE hProcess, CONTEXT* ctx,
|
|||||||
{
|
{
|
||||||
case be_xpoint_break:
|
case be_xpoint_break:
|
||||||
if (size != 0) return 0;
|
if (size != 0) return 0;
|
||||||
if (!ReadProcessMemory(hProcess, addr, &ch, 1, &sz) || sz != 1) return 0;
|
if (!pio->read(hProcess, addr, &ch, 1, &sz) || sz != 1) return 0;
|
||||||
if (ch != (unsigned char)0xCC)
|
if (ch != (unsigned char)0xCC)
|
||||||
WINE_FIXME("Cannot get back %02x instead of 0xCC at %08lx\n",
|
WINE_FIXME("Cannot get back %02x instead of 0xCC at %08lx\n",
|
||||||
ch, (unsigned long)addr);
|
ch, (unsigned long)addr);
|
||||||
ch = (unsigned char)val;
|
ch = (unsigned char)val;
|
||||||
if (!WriteProcessMemory(hProcess, addr, &ch, 1, &sz) || sz != 1) return 0;
|
if (!pio->write(hProcess, addr, &ch, 1, &sz) || sz != 1) return 0;
|
||||||
break;
|
break;
|
||||||
case be_xpoint_watch_exec:
|
case be_xpoint_watch_exec:
|
||||||
case be_xpoint_watch_read:
|
case be_xpoint_watch_read:
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#if defined(__powerpc__)
|
#if defined(__powerpc__)
|
||||||
|
|
||||||
static unsigned be_ppc_get_addr(HANDLE hThread, const CONTEXT* ctx,
|
static unsigned be_ppc_get_addr(HANDLE hThread, const CONTEXT* ctx,
|
||||||
enum be_cpu_addr bca, ADDRESS* addr)
|
enum be_cpu_addr bca, ADDRESS* addr)
|
||||||
{
|
{
|
||||||
switch (bca)
|
switch (bca)
|
||||||
{
|
{
|
||||||
@ -44,7 +44,7 @@ static void be_ppc_single_step(CONTEXT* ctx, unsigned enable)
|
|||||||
# define MSR_SE (1<<10)
|
# define MSR_SE (1<<10)
|
||||||
#endif
|
#endif
|
||||||
if (enable) ctx->Msr |= MSR_SE;
|
if (enable) ctx->Msr |= MSR_SE;
|
||||||
else ctx->Msr &= MSR_SE;
|
else ctx->Msr &= ~MSR_SE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void be_ppc_print_context(HANDLE hThread, const CONTEXT* ctx)
|
static void be_ppc_print_context(HANDLE hThread, const CONTEXT* ctx)
|
||||||
@ -95,9 +95,9 @@ static void be_ppc_disasm_one_insn(ADDRESS* addr, int display)
|
|||||||
dbg_printf("Disasm NIY\n");
|
dbg_printf("Disasm NIY\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned be_ppc_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx,
|
static unsigned be_ppc_insert_Xpoint(HANDLE hProcess, struct be_process_io* pio,
|
||||||
enum be_xpoint_type type, void* addr,
|
CONTEXT* ctx, enum be_xpoint_type type,
|
||||||
unsigned long* val, unsigned size)
|
void* addr, unsigned long* val, unsigned size)
|
||||||
{
|
{
|
||||||
unsigned long xbp;
|
unsigned long xbp;
|
||||||
unsigned long sz;
|
unsigned long sz;
|
||||||
@ -106,9 +106,9 @@ static unsigned be_ppc_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx,
|
|||||||
{
|
{
|
||||||
case be_xpoint_break:
|
case be_xpoint_break:
|
||||||
if (!size) return 0;
|
if (!size) return 0;
|
||||||
if (!ReadProcessMemory(hProcess, addr, val, 4, &sz) || sz != 4) return 0;
|
if (!pio->read(hProcess, addr, val, 4, &sz) || sz != 4) return 0;
|
||||||
xbp = 0x7d821008; /* 7d 82 10 08 ... in big endian */
|
xbp = 0x7d821008; /* 7d 82 10 08 ... in big endian */
|
||||||
if (!WriteProcessMemory(hProcess, addr, &xbp, 4, &sz) || sz != 4) return 0;
|
if (!pio->write(hProcess, addr, &xbp, 4, &sz) || sz != 4) return 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dbg_printf("Unknown/unsupported bp type %c\n", type);
|
dbg_printf("Unknown/unsupported bp type %c\n", type);
|
||||||
@ -117,9 +117,9 @@ static unsigned be_ppc_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned be_ppc_remove_Xpoint(HANDLE hProcess, CONTEXT* ctx,
|
static unsigned be_ppc_remove_Xpoint(HANDLE hProcess, struct be_process_io* pio,
|
||||||
enum be_xpoint_type type, void* addr,
|
CONTEXT* ctx, enum be_xpoint_type type,
|
||||||
unsigned long val, unsigned size)
|
void* addr, unsigned long val, unsigned size)
|
||||||
{
|
{
|
||||||
unsigned long sz;
|
unsigned long sz;
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ static unsigned be_ppc_remove_Xpoint(HANDLE hProcess, CONTEXT* ctx,
|
|||||||
{
|
{
|
||||||
case be_xpoint_break:
|
case be_xpoint_break:
|
||||||
if (!size) return 0;
|
if (!size) return 0;
|
||||||
if (!WriteProcessMemory(hProcess, addr, &val, 4, &sz) || sz != 4) return 0;
|
if (!pio->write(hProcess, addr, &val, 4, &sz) || sz == 4) return 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dbg_printf("Unknown/unsupported bp type %c\n", type);
|
dbg_printf("Unknown/unsupported bp type %c\n", type);
|
||||||
|
@ -53,12 +53,14 @@ void break_set_xpoints(BOOL set)
|
|||||||
addr = (void*)memory_to_linear_addr(&bp[i].addr);
|
addr = (void*)memory_to_linear_addr(&bp[i].addr);
|
||||||
|
|
||||||
if (set)
|
if (set)
|
||||||
ret = be_cpu->insert_Xpoint(dbg_curr_process->handle, &dbg_context,
|
ret = be_cpu->insert_Xpoint(dbg_curr_process->handle,
|
||||||
bp[i].xpoint_type, addr,
|
dbg_curr_process->process_io,
|
||||||
|
&dbg_context, bp[i].xpoint_type, addr,
|
||||||
&bp[i].info, size);
|
&bp[i].info, size);
|
||||||
else
|
else
|
||||||
ret = be_cpu->remove_Xpoint(dbg_curr_process->handle, &dbg_context,
|
ret = be_cpu->remove_Xpoint(dbg_curr_process->handle,
|
||||||
bp[i].xpoint_type, addr,
|
dbg_curr_process->process_io,
|
||||||
|
&dbg_context, bp[i].xpoint_type, addr,
|
||||||
bp[i].info, size);
|
bp[i].info, size);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
|
@ -191,6 +191,7 @@ struct dbg_process
|
|||||||
{
|
{
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
DWORD pid;
|
DWORD pid;
|
||||||
|
struct be_process_io* process_io;
|
||||||
const char* imageName;
|
const char* imageName;
|
||||||
struct dbg_thread* threads;
|
struct dbg_thread* threads;
|
||||||
unsigned continue_on_first_exception;
|
unsigned continue_on_first_exception;
|
||||||
@ -202,6 +203,13 @@ struct dbg_process
|
|||||||
struct dbg_process* prev;
|
struct dbg_process* prev;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* describes the way the debugger interacts with a given process */
|
||||||
|
struct be_process_io
|
||||||
|
{
|
||||||
|
BOOL (WINAPI *read)(HANDLE, const void*, void*, DWORD, DWORD*);
|
||||||
|
BOOL (WINAPI *write)(HANDLE, void*, const void*, DWORD, DWORD*);
|
||||||
|
};
|
||||||
|
|
||||||
extern struct dbg_process* dbg_curr_process;
|
extern struct dbg_process* dbg_curr_process;
|
||||||
extern DWORD dbg_curr_pid;
|
extern DWORD dbg_curr_pid;
|
||||||
extern struct dbg_thread* dbg_curr_thread;
|
extern struct dbg_thread* dbg_curr_thread;
|
||||||
@ -314,8 +322,8 @@ extern void* memory_to_linear_addr(const ADDRESS* address);
|
|||||||
extern BOOL memory_get_current_pc(ADDRESS* address);
|
extern BOOL memory_get_current_pc(ADDRESS* address);
|
||||||
extern BOOL memory_get_current_stack(ADDRESS* address);
|
extern BOOL memory_get_current_stack(ADDRESS* address);
|
||||||
extern BOOL memory_get_current_frame(ADDRESS* address);
|
extern BOOL memory_get_current_frame(ADDRESS* address);
|
||||||
extern BOOL memory_get_string(HANDLE hp, void* addr, BOOL in_debuggee, BOOL unicode, char* buffer, int size);
|
extern BOOL memory_get_string(struct dbg_process* pcs, void* addr, BOOL in_debuggee, BOOL unicode, char* buffer, int size);
|
||||||
extern BOOL memory_get_string_indirect(HANDLE hp, void* addr, BOOL unicode, char* buffer, int size);
|
extern BOOL memory_get_string_indirect(struct dbg_process* pcs, void* addr, BOOL unicode, char* buffer, int size);
|
||||||
extern void memory_disassemble(const struct dbg_lvalue*, const struct dbg_lvalue*, int instruction_count);
|
extern void memory_disassemble(const struct dbg_lvalue*, const struct dbg_lvalue*, int instruction_count);
|
||||||
extern BOOL memory_disasm_one_insn(ADDRESS* addr);
|
extern BOOL memory_disasm_one_insn(ADDRESS* addr);
|
||||||
extern void print_bare_address(const ADDRESS* addr);
|
extern void print_bare_address(const ADDRESS* addr);
|
||||||
@ -373,7 +381,8 @@ extern BOOL dbg_attach_debuggee(DWORD pid, BOOL cofe, BOOL wfe);
|
|||||||
extern BOOL dbg_detach_debuggee(void);
|
extern BOOL dbg_detach_debuggee(void);
|
||||||
extern BOOL dbg_interrupt_debuggee(void);
|
extern BOOL dbg_interrupt_debuggee(void);
|
||||||
extern void dbg_run_debuggee(const char* args);
|
extern void dbg_run_debuggee(const char* args);
|
||||||
extern struct dbg_process* dbg_add_process(DWORD pid, HANDLE h, const char* imageName);
|
extern struct dbg_process* dbg_add_process(DWORD pid, HANDLE h);
|
||||||
|
extern void dbg_set_process_name(struct dbg_process* p, const char* name);
|
||||||
extern struct dbg_process* dbg_get_process(DWORD pid);
|
extern struct dbg_process* dbg_get_process(DWORD pid);
|
||||||
extern void dbg_del_process(struct dbg_process* p);
|
extern void dbg_del_process(struct dbg_process* p);
|
||||||
struct dbg_thread* dbg_add_thread(struct dbg_process* p, DWORD tid, HANDLE h, void* teb);
|
struct dbg_thread* dbg_add_thread(struct dbg_process* p, DWORD tid, HANDLE h, void* teb);
|
||||||
|
@ -443,10 +443,14 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
|
|||||||
switch (de->dwDebugEventCode)
|
switch (de->dwDebugEventCode)
|
||||||
{
|
{
|
||||||
case CREATE_PROCESS_DEBUG_EVENT:
|
case CREATE_PROCESS_DEBUG_EVENT:
|
||||||
memory_get_string_indirect(de->u.CreateProcessInfo.hProcess,
|
gdbctx->process = dbg_add_process(de->dwProcessId,
|
||||||
|
de->u.CreateProcessInfo.hProcess);
|
||||||
|
if (!gdbctx->process) break;
|
||||||
|
memory_get_string_indirect(gdbctx->process,
|
||||||
de->u.CreateProcessInfo.lpImageName,
|
de->u.CreateProcessInfo.lpImageName,
|
||||||
de->u.CreateProcessInfo.fUnicode,
|
de->u.CreateProcessInfo.fUnicode,
|
||||||
buffer, sizeof(buffer));
|
buffer, sizeof(buffer));
|
||||||
|
dbg_set_process_name(gdbctx->process, buffer);
|
||||||
|
|
||||||
if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
|
if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
|
||||||
fprintf(stderr, "%08lx:%08lx: create process '%s'/%p @%08lx (%ld<%ld>)\n",
|
fprintf(stderr, "%08lx:%08lx: create process '%s'/%p @%08lx (%ld<%ld>)\n",
|
||||||
@ -456,9 +460,6 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
|
|||||||
de->u.CreateProcessInfo.dwDebugInfoFileOffset,
|
de->u.CreateProcessInfo.dwDebugInfoFileOffset,
|
||||||
de->u.CreateProcessInfo.nDebugInfoSize);
|
de->u.CreateProcessInfo.nDebugInfoSize);
|
||||||
|
|
||||||
gdbctx->process = dbg_add_process(de->dwProcessId,
|
|
||||||
de->u.CreateProcessInfo.hProcess,
|
|
||||||
buffer);
|
|
||||||
/* de->u.CreateProcessInfo.lpStartAddress; */
|
/* de->u.CreateProcessInfo.lpStartAddress; */
|
||||||
if (!SymInitialize(gdbctx->process->handle, NULL, TRUE))
|
if (!SymInitialize(gdbctx->process->handle, NULL, TRUE))
|
||||||
fprintf(stderr, "Couldn't initiate DbgHelp\n");
|
fprintf(stderr, "Couldn't initiate DbgHelp\n");
|
||||||
@ -476,7 +477,7 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
|
|||||||
|
|
||||||
case LOAD_DLL_DEBUG_EVENT:
|
case LOAD_DLL_DEBUG_EVENT:
|
||||||
assert(dbg_curr_thread);
|
assert(dbg_curr_thread);
|
||||||
memory_get_string_indirect(gdbctx->process->handle,
|
memory_get_string_indirect(gdbctx->process,
|
||||||
de->u.LoadDll.lpImageName,
|
de->u.LoadDll.lpImageName,
|
||||||
de->u.LoadDll.fUnicode,
|
de->u.LoadDll.fUnicode,
|
||||||
buffer, sizeof(buffer));
|
buffer, sizeof(buffer));
|
||||||
@ -547,7 +548,7 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
|
|||||||
|
|
||||||
case OUTPUT_DEBUG_STRING_EVENT:
|
case OUTPUT_DEBUG_STRING_EVENT:
|
||||||
assert(dbg_curr_thread);
|
assert(dbg_curr_thread);
|
||||||
memory_get_string(gdbctx->process->handle,
|
memory_get_string(gdbctx->process,
|
||||||
de->u.DebugString.lpDebugStringData, TRUE,
|
de->u.DebugString.lpDebugStringData, TRUE,
|
||||||
de->u.DebugString.fUnicode, buffer, sizeof(buffer));
|
de->u.DebugString.fUnicode, buffer, sizeof(buffer));
|
||||||
if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
|
if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
|
||||||
@ -1263,7 +1264,7 @@ static enum packet_return packet_read_memory(struct gdb_context* gdbctx)
|
|||||||
for (nread = 0; nread < len; nread += r, addr += r)
|
for (nread = 0; nread < len; nread += r, addr += r)
|
||||||
{
|
{
|
||||||
blk_len = min(sizeof(buffer), len - nread);
|
blk_len = min(sizeof(buffer), len - nread);
|
||||||
if (!ReadProcessMemory(gdbctx->process->handle, addr, buffer, blk_len, &r) ||
|
if (!gdbctx->process->process_io->read(gdbctx->process->handle, addr, buffer, blk_len, &r) ||
|
||||||
r == 0)
|
r == 0)
|
||||||
{
|
{
|
||||||
/* fail at first address, return error */
|
/* fail at first address, return error */
|
||||||
@ -1316,16 +1317,12 @@ static enum packet_return packet_write_memory(struct gdb_context* gdbctx)
|
|||||||
{
|
{
|
||||||
blk_len = min(sizeof(buffer), len);
|
blk_len = min(sizeof(buffer), len);
|
||||||
hex_from(buffer, ptr, blk_len);
|
hex_from(buffer, ptr, blk_len);
|
||||||
{
|
if (!gdbctx->process->process_io->write(gdbctx->process->handle, addr, buffer, blk_len, &w) ||
|
||||||
BOOL ret;
|
w != blk_len)
|
||||||
|
break;
|
||||||
ret = WriteProcessMemory(gdbctx->process->handle, addr, buffer, blk_len, &w);
|
addr += blk_len;
|
||||||
if (!ret || w != blk_len)
|
len -= blk_len;
|
||||||
break;
|
ptr += blk_len;
|
||||||
}
|
|
||||||
addr += w;
|
|
||||||
len -= w;
|
|
||||||
ptr += w;
|
|
||||||
}
|
}
|
||||||
return packet_ok; /* FIXME: error while writing ? */
|
return packet_ok; /* FIXME: error while writing ? */
|
||||||
}
|
}
|
||||||
@ -1789,7 +1786,8 @@ static enum packet_return packet_remove_breakpoint(struct gdb_context* gdbctx)
|
|||||||
{
|
{
|
||||||
if (xpt->addr == addr && xpt->type == t)
|
if (xpt->addr == addr && xpt->type == t)
|
||||||
{
|
{
|
||||||
if (be_cpu->remove_Xpoint(gdbctx->process->handle, &gdbctx->context,
|
if (be_cpu->remove_Xpoint(gdbctx->process->handle,
|
||||||
|
gdbctx->process->process_io, &gdbctx->context,
|
||||||
t, xpt->addr, xpt->val, len))
|
t, xpt->addr, xpt->val, len))
|
||||||
{
|
{
|
||||||
xpt->type = -1;
|
xpt->type = -1;
|
||||||
@ -1835,7 +1833,8 @@ static enum packet_return packet_set_breakpoint(struct gdb_context* gdbctx)
|
|||||||
{
|
{
|
||||||
if (xpt->type == -1)
|
if (xpt->type == -1)
|
||||||
{
|
{
|
||||||
if (be_cpu->insert_Xpoint(gdbctx->process->handle, &gdbctx->context,
|
if (be_cpu->insert_Xpoint(gdbctx->process->handle,
|
||||||
|
gdbctx->process->process_io, &gdbctx->context,
|
||||||
t, addr, &xpt->val, len))
|
t, addr, &xpt->val, len))
|
||||||
{
|
{
|
||||||
xpt->addr = addr;
|
xpt->addr = addr;
|
||||||
|
@ -169,13 +169,13 @@ void memory_examine(const struct dbg_lvalue *lvalue, int count, char format)
|
|||||||
{
|
{
|
||||||
case 'u':
|
case 'u':
|
||||||
if (count == 1) count = 256;
|
if (count == 1) count = 256;
|
||||||
memory_get_string(dbg_curr_process->handle, linear,
|
memory_get_string(dbg_curr_process, linear,
|
||||||
TRUE, TRUE, buffer, min(count, sizeof(buffer)));
|
TRUE, TRUE, buffer, min(count, sizeof(buffer)));
|
||||||
dbg_printf("%s\n", buffer);
|
dbg_printf("%s\n", buffer);
|
||||||
return;
|
return;
|
||||||
case 's':
|
case 's':
|
||||||
if (count == 1) count = 256;
|
if (count == 1) count = 256;
|
||||||
memory_get_string(dbg_curr_process->handle, linear,
|
memory_get_string(dbg_curr_process, linear,
|
||||||
TRUE, FALSE, buffer, min(count, sizeof(buffer)));
|
TRUE, FALSE, buffer, min(count, sizeof(buffer)));
|
||||||
dbg_printf("%s\n", buffer);
|
dbg_printf("%s\n", buffer);
|
||||||
return;
|
return;
|
||||||
@ -233,8 +233,8 @@ void memory_examine(const struct dbg_lvalue *lvalue, int count, char format)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL memory_get_string(HANDLE hp, void* addr, BOOL in_debuggee, BOOL unicode,
|
BOOL memory_get_string(struct dbg_process* pcs, void* addr, BOOL in_debuggee,
|
||||||
char* buffer, int size)
|
BOOL unicode, char* buffer, int size)
|
||||||
{
|
{
|
||||||
DWORD sz;
|
DWORD sz;
|
||||||
WCHAR* buffW;
|
WCHAR* buffW;
|
||||||
@ -243,10 +243,10 @@ BOOL memory_get_string(HANDLE hp, void* addr, BOOL in_debuggee, BOOL unicode,
|
|||||||
if (!addr) return FALSE;
|
if (!addr) return FALSE;
|
||||||
if (in_debuggee)
|
if (in_debuggee)
|
||||||
{
|
{
|
||||||
if (!unicode) return ReadProcessMemory(hp, addr, buffer, size, &sz);
|
if (!unicode) return pcs->process_io->read(pcs->handle, addr, buffer, size, &sz);
|
||||||
|
|
||||||
buffW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
|
buffW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
|
||||||
ReadProcessMemory(hp, addr, buffW, size * sizeof(WCHAR), &sz);
|
pcs->process_io->read(pcs->handle, addr, buffW, size * sizeof(WCHAR), &sz);
|
||||||
WideCharToMultiByte(CP_ACP, 0, buffW, sz / sizeof(WCHAR), buffer, size,
|
WideCharToMultiByte(CP_ACP, 0, buffW, sz / sizeof(WCHAR), buffer, size,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
HeapFree(GetProcessHeap(), 0, buffW);
|
HeapFree(GetProcessHeap(), 0, buffW);
|
||||||
@ -258,16 +258,16 @@ BOOL memory_get_string(HANDLE hp, void* addr, BOOL in_debuggee, BOOL unicode,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL memory_get_string_indirect(HANDLE hp, void* addr, BOOL unicode, char* buffer, int size)
|
BOOL memory_get_string_indirect(struct dbg_process* pcs, void* addr, BOOL unicode, char* buffer, int size)
|
||||||
{
|
{
|
||||||
void* ad;
|
void* ad;
|
||||||
DWORD sz;
|
DWORD sz;
|
||||||
|
|
||||||
buffer[0] = 0;
|
buffer[0] = 0;
|
||||||
if (addr &&
|
if (addr &&
|
||||||
ReadProcessMemory(hp, addr, &ad, sizeof(ad), &sz) && sz == sizeof(ad) && ad)
|
pcs->process_io->read(pcs->handle, addr, &ad, sizeof(ad), &sz) && sz == sizeof(ad) && ad)
|
||||||
{
|
{
|
||||||
return memory_get_string(hp, ad, TRUE, unicode, buffer, size);
|
return memory_get_string(pcs, ad, TRUE, unicode, buffer, size);
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -337,7 +337,7 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue)
|
|||||||
{
|
{
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
|
|
||||||
memory_get_string(dbg_curr_process->handle, val_ptr,
|
memory_get_string(dbg_curr_process, val_ptr,
|
||||||
lvalue->cookie == DLV_TARGET,
|
lvalue->cookie == DLV_TARGET,
|
||||||
size == 2, buffer, sizeof(buffer));
|
size == 2, buffer, sizeof(buffer));
|
||||||
dbg_printf("\"%s\"", buffer);
|
dbg_printf("\"%s\"", buffer);
|
||||||
|
39
programs/winedbg/tgt_active.c
Normal file
39
programs/winedbg/tgt_active.c
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Wine debugger - back-end for an active target
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "debugger.h"
|
||||||
|
#include "winternl.h"
|
||||||
|
#include "wine/debug.h"
|
||||||
|
#include "wine/exception.h"
|
||||||
|
|
||||||
|
WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
|
||||||
|
|
||||||
|
struct be_process_io be_process_active_io =
|
||||||
|
{
|
||||||
|
ReadProcessMemory,
|
||||||
|
WriteProcessMemory,
|
||||||
|
};
|
@ -454,7 +454,7 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level)
|
|||||||
*/
|
*/
|
||||||
/* FIXME should check basic type here (should be a char!!!!)... */
|
/* FIXME should check basic type here (should be a char!!!!)... */
|
||||||
len = min(count, sizeof(buffer));
|
len = min(count, sizeof(buffer));
|
||||||
memory_get_string(dbg_curr_process->handle,
|
memory_get_string(dbg_curr_process,
|
||||||
memory_to_linear_addr(&lvalue->addr),
|
memory_to_linear_addr(&lvalue->addr),
|
||||||
lvalue->cookie == DLV_TARGET, TRUE, buffer, len);
|
lvalue->cookie == DLV_TARGET, TRUE, buffer, len);
|
||||||
dbg_printf("\"%s%s\"", buffer, (len < count) ? "..." : "");
|
dbg_printf("\"%s%s\"", buffer, (len < count) ? "..." : "");
|
||||||
|
@ -239,8 +239,11 @@ struct dbg_process* dbg_get_process(DWORD pid)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dbg_process* dbg_add_process(DWORD pid, HANDLE h, const char* imageName)
|
struct dbg_process* dbg_add_process(DWORD pid, HANDLE h)
|
||||||
{
|
{
|
||||||
|
/* FIXME: temporary */
|
||||||
|
extern struct be_process_io be_process_active_io;
|
||||||
|
|
||||||
struct dbg_process* p;
|
struct dbg_process* p;
|
||||||
|
|
||||||
if ((p = dbg_get_process(pid)))
|
if ((p = dbg_get_process(pid)))
|
||||||
@ -252,7 +255,7 @@ struct dbg_process* dbg_add_process(DWORD pid, HANDLE h, const char* imageName)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
p->handle = h;
|
p->handle = h;
|
||||||
p->imageName = imageName ? strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(imageName) + 1), imageName) : NULL;
|
p->imageName = NULL;
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@ -260,7 +263,8 @@ struct dbg_process* dbg_add_process(DWORD pid, HANDLE h, const char* imageName)
|
|||||||
if (!(p = HeapAlloc(GetProcessHeap(), 0, sizeof(struct dbg_process)))) return NULL;
|
if (!(p = HeapAlloc(GetProcessHeap(), 0, sizeof(struct dbg_process)))) return NULL;
|
||||||
p->handle = h;
|
p->handle = h;
|
||||||
p->pid = pid;
|
p->pid = pid;
|
||||||
p->imageName = imageName ? strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(imageName) + 1), imageName) : NULL;
|
p->process_io = &be_process_active_io;
|
||||||
|
p->imageName = NULL;
|
||||||
p->threads = NULL;
|
p->threads = NULL;
|
||||||
p->continue_on_first_exception = FALSE;
|
p->continue_on_first_exception = FALSE;
|
||||||
p->next_bp = 1; /* breakpoint 0 is reserved for step-over */
|
p->next_bp = 1; /* breakpoint 0 is reserved for step-over */
|
||||||
@ -275,6 +279,16 @@ struct dbg_process* dbg_add_process(DWORD pid, HANDLE h, const char* imageName)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dbg_set_process_name(struct dbg_process* p, const char* imageName)
|
||||||
|
{
|
||||||
|
assert(p->imageName == NULL);
|
||||||
|
if (imageName)
|
||||||
|
{
|
||||||
|
char* tmp = HeapAlloc(GetProcessHeap(), 0, strlen(imageName) + 1);
|
||||||
|
if (tmp) p->imageName = strcpy(tmp, imageName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void dbg_del_process(struct dbg_process* p)
|
void dbg_del_process(struct dbg_process* p)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -418,7 +432,7 @@ BOOL dbg_attach_debuggee(DWORD pid, BOOL cofe, BOOL wfe)
|
|||||||
{
|
{
|
||||||
DEBUG_EVENT de;
|
DEBUG_EVENT de;
|
||||||
|
|
||||||
if (!(dbg_curr_process = dbg_add_process(pid, 0, NULL))) return FALSE;
|
if (!(dbg_curr_process = dbg_add_process(pid, 0))) return FALSE;
|
||||||
|
|
||||||
if (!DebugActiveProcess(pid))
|
if (!DebugActiveProcess(pid))
|
||||||
{
|
{
|
||||||
@ -660,11 +674,11 @@ static DWORD dbg_handle_exception(const EXCEPTION_RECORD* rec, BOOL first_chance
|
|||||||
case EXCEPTION_WINE_STUB:
|
case EXCEPTION_WINE_STUB:
|
||||||
{
|
{
|
||||||
char dll[32], name[64];
|
char dll[32], name[64];
|
||||||
memory_get_string(dbg_curr_process->handle,
|
memory_get_string(dbg_curr_process,
|
||||||
(void*)rec->ExceptionInformation[0], TRUE, FALSE,
|
(void*)rec->ExceptionInformation[0], TRUE, FALSE,
|
||||||
dll, sizeof(dll));
|
dll, sizeof(dll));
|
||||||
if (HIWORD(rec->ExceptionInformation[1]))
|
if (HIWORD(rec->ExceptionInformation[1]))
|
||||||
memory_get_string(dbg_curr_process->handle,
|
memory_get_string(dbg_curr_process,
|
||||||
(void*)rec->ExceptionInformation[1], TRUE, FALSE,
|
(void*)rec->ExceptionInformation[1], TRUE, FALSE,
|
||||||
name, sizeof(name));
|
name, sizeof(name));
|
||||||
else
|
else
|
||||||
@ -772,25 +786,27 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CREATE_PROCESS_DEBUG_EVENT:
|
case CREATE_PROCESS_DEBUG_EVENT:
|
||||||
memory_get_string_indirect(de->u.CreateProcessInfo.hProcess,
|
dbg_curr_process = dbg_add_process(de->dwProcessId,
|
||||||
|
de->u.CreateProcessInfo.hProcess);
|
||||||
|
if (dbg_curr_process == NULL)
|
||||||
|
{
|
||||||
|
WINE_ERR("Couldn't create process\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
memory_get_string_indirect(dbg_curr_process,
|
||||||
de->u.CreateProcessInfo.lpImageName,
|
de->u.CreateProcessInfo.lpImageName,
|
||||||
de->u.CreateProcessInfo.fUnicode,
|
de->u.CreateProcessInfo.fUnicode,
|
||||||
buffer, sizeof(buffer));
|
buffer, sizeof(buffer));
|
||||||
|
if (!buffer[0]) strcpy(buffer, "<Debugged Process>");
|
||||||
|
|
||||||
WINE_TRACE("%08lx:%08lx: create process '%s'/%p @%08lx (%ld<%ld>)\n",
|
WINE_TRACE("%08lx:%08lx: create process '%s'/%p @%08lx (%ld<%ld>)\n",
|
||||||
de->dwProcessId, de->dwThreadId,
|
de->dwProcessId, de->dwThreadId,
|
||||||
buffer, de->u.CreateProcessInfo.lpImageName,
|
buffer, de->u.CreateProcessInfo.lpImageName,
|
||||||
(unsigned long)(void*)de->u.CreateProcessInfo.lpStartAddress,
|
(unsigned long)(void*)de->u.CreateProcessInfo.lpStartAddress,
|
||||||
de->u.CreateProcessInfo.dwDebugInfoFileOffset,
|
de->u.CreateProcessInfo.dwDebugInfoFileOffset,
|
||||||
de->u.CreateProcessInfo.nDebugInfoSize);
|
de->u.CreateProcessInfo.nDebugInfoSize);
|
||||||
|
dbg_set_process_name(dbg_curr_process, buffer);
|
||||||
|
|
||||||
dbg_curr_process = dbg_add_process(de->dwProcessId,
|
|
||||||
de->u.CreateProcessInfo.hProcess,
|
|
||||||
buffer[0] ? buffer : "<Debugged Process>");
|
|
||||||
if (dbg_curr_process == NULL)
|
|
||||||
{
|
|
||||||
WINE_ERR("Couldn't create process\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!SymInitialize(dbg_curr_process->handle, NULL, TRUE))
|
if (!SymInitialize(dbg_curr_process->handle, NULL, TRUE))
|
||||||
dbg_printf("Couldn't initiate DbgHelp\n");
|
dbg_printf("Couldn't initiate DbgHelp\n");
|
||||||
|
|
||||||
@ -878,7 +894,7 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de)
|
|||||||
WINE_ERR("Unknown thread\n");
|
WINE_ERR("Unknown thread\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
memory_get_string_indirect(dbg_curr_process->handle,
|
memory_get_string_indirect(dbg_curr_process,
|
||||||
de->u.LoadDll.lpImageName,
|
de->u.LoadDll.lpImageName,
|
||||||
de->u.LoadDll.fUnicode,
|
de->u.LoadDll.fUnicode,
|
||||||
buffer, sizeof(buffer));
|
buffer, sizeof(buffer));
|
||||||
@ -918,7 +934,7 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
memory_get_string(dbg_curr_process->handle,
|
memory_get_string(dbg_curr_process,
|
||||||
de->u.DebugString.lpDebugStringData, TRUE,
|
de->u.DebugString.lpDebugStringData, TRUE,
|
||||||
de->u.DebugString.fUnicode, buffer, sizeof(buffer));
|
de->u.DebugString.fUnicode, buffer, sizeof(buffer));
|
||||||
WINE_TRACE("%08lx:%08lx: output debug string (%s)\n",
|
WINE_TRACE("%08lx:%08lx: output debug string (%s)\n",
|
||||||
@ -1057,7 +1073,7 @@ static unsigned dbg_start_debuggee(LPSTR cmdLine)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
dbg_curr_pid = info.dwProcessId;
|
dbg_curr_pid = info.dwProcessId;
|
||||||
if (!(dbg_curr_process = dbg_add_process(dbg_curr_pid, 0, NULL))) return FALSE;
|
if (!(dbg_curr_process = dbg_add_process(dbg_curr_pid, 0))) return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user