winedbg: Use Unicode strings for all module references.

This commit is contained in:
Eric Pouech 2008-10-18 09:15:10 +02:00 committed by Alexandre Julliard
parent 01e69c71e0
commit 5c8ad49158
8 changed files with 118 additions and 74 deletions

View File

@ -216,7 +216,7 @@ struct dbg_process
DWORD pid;
const struct be_process_io* process_io;
void* pio_data;
const char* imageName;
const WCHAR* imageName;
struct dbg_thread* threads;
unsigned continue_on_first_exception : 1,
active_debuggee : 1;
@ -359,7 +359,7 @@ extern BOOL memory_get_current_pc(ADDRESS64* address);
extern BOOL memory_get_current_stack(ADDRESS64* address);
extern BOOL memory_get_current_frame(ADDRESS64* address);
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(struct dbg_process* pcs, void* addr, BOOL unicode, char* buffer, int size);
extern BOOL memory_get_string_indirect(struct dbg_process* pcs, void* addr, BOOL unicode, WCHAR* buffer, int size);
extern BOOL memory_get_register(DWORD regno, DWORD** value, char* buffer, int len);
extern void memory_disassemble(const struct dbg_lvalue*, const struct dbg_lvalue*, int instruction_count);
extern BOOL memory_disasm_one_insn(ADDRESS64* addr);
@ -430,6 +430,7 @@ extern struct dbg_type types_find_type(unsigned long linear, const char* name,
/* winedbg.c */
extern void dbg_outputA(const char* buffer, int len);
extern void dbg_outputW(const WCHAR* buffer, int len);
extern const char* dbg_W2A(const WCHAR* buffer, unsigned len);
#ifdef __GNUC__
extern int dbg_printf(const char* format, ...) __attribute__((format (printf,1,2)));
#else
@ -439,14 +440,14 @@ extern const struct dbg_internal_var* dbg_get_internal_var(const char*);
extern BOOL dbg_interrupt_debuggee(void);
extern unsigned dbg_num_processes(void);
extern struct dbg_process* dbg_add_process(const struct be_process_io* pio, DWORD pid, HANDLE h);
extern void dbg_set_process_name(struct dbg_process* p, const char* name);
extern void dbg_set_process_name(struct dbg_process* p, const WCHAR* name);
extern struct dbg_process* dbg_get_process(DWORD pid);
extern struct dbg_process* dbg_get_process_h(HANDLE handle);
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);
extern struct dbg_thread* dbg_get_thread(struct dbg_process* p, DWORD tid);
extern void dbg_del_thread(struct dbg_thread* t);
extern BOOL dbg_init(HANDLE hProc, const char* in, BOOL invade);
extern BOOL dbg_init(HANDLE hProc, const WCHAR* in, BOOL invade);
extern BOOL dbg_get_debuggee_info(HANDLE hProcess, IMAGEHLP_MODULE* imh_mod);
/* gdbproxy.c */

View File

@ -63,6 +63,7 @@
#include "windef.h"
#include "winbase.h"
#include "tlhelp32.h"
#include "wine/debug.h"
#define GDBPXY_TRC_LOWLEVEL 0x01
#define GDBPXY_TRC_PACKET 0x02
@ -480,7 +481,10 @@ static BOOL handle_exception(struct gdb_context* gdbctx, EXCEPTION_DEBUG_INFO* e
static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
{
char buffer[256];
union {
char bufferA[256];
WCHAR buffer[256];
} u;
dbg_curr_thread = dbg_get_thread(gdbctx->process, de->dwThreadId);
@ -493,19 +497,20 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
memory_get_string_indirect(gdbctx->process,
de->u.CreateProcessInfo.lpImageName,
de->u.CreateProcessInfo.fUnicode,
buffer, sizeof(buffer));
dbg_set_process_name(gdbctx->process, buffer);
u.buffer, sizeof(u.buffer) / sizeof(WCHAR));
dbg_set_process_name(gdbctx->process, u.buffer);
if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
fprintf(stderr, "%04x:%04x: create process '%s'/%p @%p (%u<%u>)\n",
de->dwProcessId, de->dwThreadId,
buffer, de->u.CreateProcessInfo.lpImageName,
dbg_W2A(u.buffer, -1),
de->u.CreateProcessInfo.lpImageName,
de->u.CreateProcessInfo.lpStartAddress,
de->u.CreateProcessInfo.dwDebugInfoFileOffset,
de->u.CreateProcessInfo.nDebugInfoSize);
/* de->u.CreateProcessInfo.lpStartAddress; */
if (!dbg_init(gdbctx->process->handle, buffer, TRUE))
if (!dbg_init(gdbctx->process->handle, u.buffer, TRUE))
fprintf(stderr, "Couldn't initiate DbgHelp\n");
if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
@ -524,15 +529,16 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
memory_get_string_indirect(gdbctx->process,
de->u.LoadDll.lpImageName,
de->u.LoadDll.fUnicode,
buffer, sizeof(buffer));
u.buffer, sizeof(u.buffer) / sizeof(WCHAR));
if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
fprintf(stderr, "%04x:%04x: loads DLL %s @%p (%u<%u>)\n",
de->dwProcessId, de->dwThreadId,
buffer, de->u.LoadDll.lpBaseOfDll,
dbg_W2A(u.buffer, -1),
de->u.LoadDll.lpBaseOfDll,
de->u.LoadDll.dwDebugInfoFileOffset,
de->u.LoadDll.nDebugInfoSize);
SymLoadModule(gdbctx->process->handle, de->u.LoadDll.hFile, buffer, NULL,
(unsigned long)de->u.LoadDll.lpBaseOfDll, 0);
SymLoadModuleExW(gdbctx->process->handle, de->u.LoadDll.hFile, u.buffer, NULL,
(unsigned long)de->u.LoadDll.lpBaseOfDll, 0, NULL, 0);
break;
case UNLOAD_DLL_DEBUG_EVENT:
@ -594,10 +600,10 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
assert(dbg_curr_thread);
memory_get_string(gdbctx->process,
de->u.DebugString.lpDebugStringData, TRUE,
de->u.DebugString.fUnicode, buffer, sizeof(buffer));
de->u.DebugString.fUnicode, u.bufferA, sizeof(u.bufferA));
if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
fprintf(stderr, "%08x:%08x: output debug string (%s)\n",
de->dwProcessId, de->dwThreadId, buffer);
de->dwProcessId, de->dwThreadId, u.bufferA);
break;
case RIP_EVENT:

View File

@ -501,7 +501,8 @@ void info_win32_threads(void)
struct dbg_process* p = dbg_get_process(entry.th32OwnerProcessID);
dbg_printf("%08x%s %s\n",
entry.th32OwnerProcessID, p ? " (D)" : "", p ? p->imageName : "");
entry.th32OwnerProcessID, p ? " (D)" : "",
p ? dbg_W2A(p->imageName, -1) : "");
lastProcessId = entry.th32OwnerProcessID;
}
dbg_printf("\t%08x %4d%s\n",

View File

@ -259,16 +259,32 @@ BOOL memory_get_string(struct dbg_process* pcs, void* addr, BOOL in_debuggee,
return TRUE;
}
BOOL memory_get_string_indirect(struct dbg_process* pcs, void* addr, BOOL unicode, char* buffer, int size)
BOOL memory_get_string_indirect(struct dbg_process* pcs, void* addr, BOOL unicode, WCHAR* buffer, int size)
{
void* ad;
SIZE_T sz;
buffer[0] = 0;
if (addr &&
if (addr &&
pcs->process_io->read(pcs->handle, addr, &ad, sizeof(ad), &sz) && sz == sizeof(ad) && ad)
{
return memory_get_string(pcs, ad, TRUE, unicode, buffer, size);
LPSTR buff;
BOOL ret;
if (unicode)
ret = pcs->process_io->read(pcs->handle, ad, buffer, size * sizeof(WCHAR), &sz) && sz != 0;
else
{
if ((buff = HeapAlloc(GetProcessHeap(), 0, size)))
{
ret = pcs->process_io->read(pcs->handle, ad, buff, size, &sz) && sz != 0;
MultiByteToWideChar(CP_ACP, 0, buff, sz, buffer, size);
HeapFree(GetProcessHeap(), 0, buff);
}
else ret = FALSE;
}
if (size) buffer[size-1] = 0;
return ret;
}
return FALSE;
}

View File

@ -391,7 +391,8 @@ static void backtrace_all(void)
}
dbg_printf("\nBacktracing for thread %04x in process %04x (%s):\n",
entry.th32ThreadID, dbg_curr_pid, dbg_curr_process->imageName);
entry.th32ThreadID, dbg_curr_pid,
dbg_W2A(dbg_curr_process->imageName, -1));
backtrace_tid(dbg_curr_process, entry.th32ThreadID);
}
while (Thread32Next(snapshot, &entry));

View File

@ -30,6 +30,7 @@
#include "winternl.h"
#include "wine/debug.h"
#include "wine/exception.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
@ -418,16 +419,19 @@ static DWORD dbg_handle_exception(const EXCEPTION_RECORD* rec, BOOL first_chance
static BOOL tgt_process_active_close_process(struct dbg_process* pcs, BOOL kill);
static void fetch_module_name(void* name_addr, BOOL unicode, void* mod_addr,
char* buffer, size_t bufsz, BOOL is_pcs)
WCHAR* buffer, size_t bufsz, BOOL is_pcs)
{
static WCHAR pcspid[] = {'P','r','o','c','e','s','s','_','%','0','8','x',0};
static WCHAR dlladdr[] = {'D','L','L','_','%','0','8','l','x',0};
memory_get_string_indirect(dbg_curr_process, name_addr, unicode, buffer, bufsz);
if (!buffer[0] &&
!GetModuleFileNameExA(dbg_curr_process->handle, mod_addr, buffer, bufsz))
!GetModuleFileNameExW(dbg_curr_process->handle, mod_addr, buffer, bufsz))
{
if (is_pcs)
{
HMODULE h;
WORD (WINAPI *gpif)(HANDLE, LPSTR, DWORD);
WORD (WINAPI *gpif)(HANDLE, LPWSTR, DWORD);
/* On Windows, when we get the process creation debug event for a process
* created by winedbg, the modules' list is not initialized yet. Hence,
@ -436,18 +440,21 @@ static void fetch_module_name(void* name_addr, BOOL unicode, void* mod_addr,
* give us the expected result
*/
if (!(h = GetModuleHandleA("psapi")) ||
!(gpif = (void*)GetProcAddress(h, "GetProcessImageFileName")) ||
!(gpif = (void*)GetProcAddress(h, "GetProcessImageFileNameW")) ||
!(gpif)(dbg_curr_process->handle, buffer, bufsz))
snprintf(buffer, bufsz, "Process_%08x", dbg_curr_pid);
snprintfW(buffer, bufsz, pcspid, dbg_curr_pid);
}
else
snprintf(buffer, bufsz, "DLL_%p", mod_addr);
snprintfW(buffer, bufsz, dlladdr, (unsigned long)mod_addr);
}
}
static unsigned dbg_handle_debug_event(DEBUG_EVENT* de)
{
char buffer[256];
union {
char bufferA[256];
WCHAR buffer[256];
} u;
DWORD cont = DBG_CONTINUE;
dbg_curr_pid = de->dwProcessId;
@ -499,20 +506,21 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de)
fetch_module_name(de->u.CreateProcessInfo.lpImageName,
de->u.CreateProcessInfo.fUnicode,
de->u.CreateProcessInfo.lpBaseOfImage,
buffer, sizeof(buffer), TRUE);
u.buffer, sizeof(u.buffer) / sizeof(WCHAR), TRUE);
WINE_TRACE("%04x:%04x: create process '%s'/%p @%p (%u<%u>)\n",
de->dwProcessId, de->dwThreadId,
buffer, de->u.CreateProcessInfo.lpImageName,
wine_dbgstr_w(u.buffer),
de->u.CreateProcessInfo.lpImageName,
de->u.CreateProcessInfo.lpStartAddress,
de->u.CreateProcessInfo.dwDebugInfoFileOffset,
de->u.CreateProcessInfo.nDebugInfoSize);
dbg_set_process_name(dbg_curr_process, buffer);
dbg_set_process_name(dbg_curr_process, u.buffer);
if (!dbg_init(dbg_curr_process->handle, buffer, FALSE))
if (!dbg_init(dbg_curr_process->handle, u.buffer, FALSE))
dbg_printf("Couldn't initiate DbgHelp\n");
if (!SymLoadModule(dbg_curr_process->handle, de->u.CreateProcessInfo.hFile, buffer, NULL,
(unsigned long)de->u.CreateProcessInfo.lpBaseOfImage, 0))
if (!SymLoadModuleExW(dbg_curr_process->handle, de->u.CreateProcessInfo.hFile, u.buffer, NULL,
(unsigned long)de->u.CreateProcessInfo.lpBaseOfImage, 0, NULL, 0))
dbg_printf("couldn't load main module (%u)\n", GetLastError());
WINE_TRACE("%04x:%04x: create thread I @%p\n",
@ -593,22 +601,22 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de)
fetch_module_name(de->u.LoadDll.lpImageName,
de->u.LoadDll.fUnicode,
de->u.LoadDll.lpBaseOfDll,
buffer, sizeof(buffer), FALSE);
u.buffer, sizeof(u.buffer) / sizeof(WCHAR), FALSE);
WINE_TRACE("%04x:%04x: loads DLL %s @%p (%u<%u>)\n",
de->dwProcessId, de->dwThreadId,
buffer, de->u.LoadDll.lpBaseOfDll,
wine_dbgstr_w(u.buffer), de->u.LoadDll.lpBaseOfDll,
de->u.LoadDll.dwDebugInfoFileOffset,
de->u.LoadDll.nDebugInfoSize);
SymLoadModule(dbg_curr_process->handle, de->u.LoadDll.hFile, buffer, NULL,
(unsigned long)de->u.LoadDll.lpBaseOfDll, 0);
SymLoadModuleExW(dbg_curr_process->handle, de->u.LoadDll.hFile, u.buffer, NULL,
(unsigned long)de->u.LoadDll.lpBaseOfDll, 0, NULL, 0);
break_set_xpoints(FALSE);
break_check_delayed_bp();
break_set_xpoints(TRUE);
if (DBG_IVAR(BreakOnDllLoad))
{
dbg_printf("Stopping on DLL %s loading at 0x%08lx\n",
buffer, (unsigned long)de->u.LoadDll.lpBaseOfDll);
dbg_W2A(u.buffer, -1), (unsigned long)de->u.LoadDll.lpBaseOfDll);
if (dbg_fetch_context()) cont = 0;
}
break;
@ -631,9 +639,9 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de)
memory_get_string(dbg_curr_process,
de->u.DebugString.lpDebugStringData, TRUE,
de->u.DebugString.fUnicode, buffer, sizeof(buffer));
de->u.DebugString.fUnicode, u.bufferA, sizeof(u.bufferA));
WINE_TRACE("%04x:%04x: output debug string (%s)\n",
de->dwProcessId, de->dwThreadId, buffer);
de->dwProcessId, de->dwThreadId, u.bufferA);
break;
case RIP_EVENT:

View File

@ -172,9 +172,10 @@ static enum dbg_start minidump_do_reload(struct tgt_process_minidump_data* data)
MINIDUMP_MODULE_LIST* mml;
MINIDUMP_MODULE* mm;
MINIDUMP_STRING* mds;
char exec_name[1024];
WCHAR exec_name[1024];
WCHAR nameW[1024];
unsigned len;
static WCHAR default_exec_name[] = {'<','m','i','n','i','d','u','m','p','-','e','x','e','c','>',0};
/* fetch PID */
if (MiniDumpReadDumpStream(data->mapping, MiscInfoStream, &dir, &stream, &size))
@ -185,25 +186,24 @@ static enum dbg_start minidump_do_reload(struct tgt_process_minidump_data* data)
}
/* fetch executable name (it's normally the first one in module list) */
strcpy(exec_name, "<minidump-exec>"); /* default */
lstrcpyW(exec_name, default_exec_name);
if (MiniDumpReadDumpStream(data->mapping, ModuleListStream, &dir, &stream, &size))
{
mml = (MINIDUMP_MODULE_LIST*)stream;
if (mml->NumberOfModules)
{
char* ptr;
WCHAR* ptr;
mm = &mml->Modules[0];
mds = (MINIDUMP_STRING*)((char*)data->mapping + mm->ModuleNameRva);
len = WideCharToMultiByte(CP_ACP, 0, mds->Buffer,
mds->Length / sizeof(WCHAR),
exec_name, sizeof(exec_name) - 1, NULL, NULL);
len = mds->Length / 2;
memcpy(exec_name, mds->Buffer, mds->Length);
exec_name[len] = 0;
for (ptr = exec_name + len - 1; ptr >= exec_name; ptr--)
{
if (*ptr == '/' || *ptr == '\\')
{
memmove(exec_name, ptr + 1, strlen(ptr + 1) + 1);
memmove(exec_name, ptr + 1, (lstrlenW(ptr + 1) + 1) * sizeof(WCHAR));
break;
}
}
@ -264,7 +264,7 @@ static enum dbg_start minidump_do_reload(struct tgt_process_minidump_data* data)
break;
}
dbg_printf(" %s was running on #%d %s CPU%s",
exec_name, msi->u.s.NumberOfProcessors, str,
dbg_W2A(exec_name, -1), msi->u.s.NumberOfProcessors, str,
msi->u.s.NumberOfProcessors < 2 ? "" : "s");
switch (msi->MajorVersion)
{

View File

@ -125,22 +125,33 @@ void dbg_outputA(const char* buffer, int len)
}
}
const char* dbg_W2A(const WCHAR* buffer, unsigned len)
{
static unsigned ansilen;
static char* ansi;
unsigned newlen;
newlen = WideCharToMultiByte(CP_ACP, 0, buffer, len, NULL, 0, NULL, NULL);
if (newlen > ansilen)
{
static char* newansi;
if (ansi)
newansi = HeapReAlloc(GetProcessHeap(), 0, ansi, newlen);
else
newansi = HeapAlloc(GetProcessHeap(), 0, newlen);
if (!newansi) return NULL;
ansilen = newlen;
ansi = newansi;
}
WideCharToMultiByte(CP_ACP, 0, buffer, len, ansi, newlen, NULL, NULL);
return ansi;
}
void dbg_outputW(const WCHAR* buffer, int len)
{
char* ansi = NULL;
int newlen;
/* do a serious Unicode to ANSI conversion
* FIXME: should CP_ACP be GetConsoleCP()?
*/
newlen = WideCharToMultiByte(CP_ACP, 0, buffer, len, NULL, 0, NULL, NULL);
if (newlen)
{
if (!(ansi = HeapAlloc(GetProcessHeap(), 0, newlen))) return;
WideCharToMultiByte(CP_ACP, 0, buffer, len, ansi, newlen, NULL, NULL);
dbg_outputA(ansi, newlen);
HeapFree(GetProcessHeap(), 0, ansi);
}
const char* ansi = dbg_W2A(buffer, len);
if (ansi) dbg_outputA(ansi, strlen(ansi));
/* FIXME: should CP_ACP be GetConsoleCP()? */
}
int dbg_printf(const char* format, ...)
@ -315,13 +326,13 @@ struct dbg_process* dbg_add_process(const struct be_process_io* pio, DWORD pid,
return p;
}
void dbg_set_process_name(struct dbg_process* p, const char* imageName)
void dbg_set_process_name(struct dbg_process* p, const WCHAR* imageName)
{
assert(p->imageName == NULL);
if (imageName)
{
char* tmp = HeapAlloc(GetProcessHeap(), 0, strlen(imageName) + 1);
if (tmp) p->imageName = strcpy(tmp, imageName);
WCHAR* tmp = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(imageName) + 1) * sizeof(WCHAR));
if (tmp) p->imageName = lstrcpyW(tmp, imageName);
}
}
@ -352,29 +363,29 @@ void dbg_del_process(struct dbg_process* p)
* Initializes the dbghelp library, and also sets the application directory
* as a place holder for symbol searches.
*/
BOOL dbg_init(HANDLE hProc, const char* in, BOOL invade)
BOOL dbg_init(HANDLE hProc, const WCHAR* in, BOOL invade)
{
BOOL ret;
ret = SymInitialize(hProc, NULL, invade);
if (ret && in)
{
const char* last;
const WCHAR* last;
for (last = in + strlen(in) - 1; last >= in; last--)
for (last = in + lstrlenW(in) - 1; last >= in; last--)
{
if (*last == '/' || *last == '\\')
{
char* tmp;
tmp = HeapAlloc(GetProcessHeap(), 0, 1024 + 1 + (last - in) + 1);
if (tmp && SymGetSearchPath(hProc, tmp, 1024))
WCHAR* tmp;
tmp = HeapAlloc(GetProcessHeap(), 0, (1024 + 1 + (last - in) + 1) * sizeof(WCHAR));
if (tmp && SymGetSearchPathW(hProc, tmp, 1024))
{
char* x = tmp + strlen(tmp);
WCHAR* x = tmp + lstrlenW(tmp);
*x++ = ';';
memcpy(x, in, last - in);
memcpy(x, in, (last - in) * sizeof(WCHAR));
x[last - in] = '\0';
ret = SymSetSearchPath(hProc, tmp);
ret = SymSetSearchPathW(hProc, tmp);
}
else ret = FALSE;
HeapFree(GetProcessHeap(), 0, tmp);