Skip to content

Commit

Permalink
Bugfix: dbghelp2.dll - fix 64-bit addressing scheme, stacktrace_windo…
Browse files Browse the repository at this point in the history
…ws.cpp - fix dbghelp usage from windows side. (64-bitness should use SymGetSymFromAddr64, not SymFromAddr)
  • Loading branch information
tapika committed Jun 1, 2019
1 parent cdae75a commit 3a3e9da
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 30 deletions.
17 changes: 9 additions & 8 deletions dlls/dbghelp/dbghelp_private.h
Expand Up @@ -33,6 +33,7 @@
#include "wine/list.h"
//#include "wine/unicode.h"
#include "wine/rbtree.h" //wine_rb_tree
#include <stdint.h> //uint64_t

#include "cvconst.h"

Expand Down Expand Up @@ -139,7 +140,7 @@ struct location
{
unsigned kind : 8,
reg;
unsigned long offset;
uint64_t offset;
};

struct symt
Expand All @@ -157,7 +158,7 @@ struct symt_ht
struct symt_block
{
struct symt symt;
unsigned long address;
uint64_t address;
unsigned long size;
struct symt* container; /* block, or func */
struct vector vchildren; /* sub-blocks & local variables */
Expand All @@ -166,7 +167,7 @@ struct symt_block
struct symt_compiland
{
struct symt symt;
unsigned long address;
uint64_t address;
unsigned source;
struct vector vchildren; /* global variables & functions */
};
Expand Down Expand Up @@ -207,7 +208,7 @@ struct symt_function
{
struct symt symt;
struct hash_table_elt hash_elt; /* if global symbol */
unsigned long address;
uint64_t address;
struct symt* container; /* compiland */
struct symt* type; /* points to function_signature */
unsigned long size;
Expand All @@ -229,7 +230,7 @@ struct symt_public
struct hash_table_elt hash_elt;
struct symt* container; /* compiland */
BOOL is_function;
unsigned long address;
uint64_t address;
unsigned long size;
};

Expand All @@ -238,7 +239,7 @@ struct symt_thunk
struct symt symt;
struct hash_table_elt hash_elt;
struct symt* container; /* compiland */
unsigned long address;
uint64_t address;
unsigned long size;
THUNK_ORDINAL ordinal; /* FIXME: doesn't seem to be accessible */
};
Expand Down Expand Up @@ -417,7 +418,7 @@ struct line_info
line_number;
union
{
unsigned long pc_offset; /* if is_source_file isn't set */
uint64_t pc_offset; /* if is_source_file isn't set */
unsigned source_file; /* if is_source_file is set */
} u;
};
Expand Down Expand Up @@ -740,7 +741,7 @@ extern struct symt_function*
symt_new_function(struct module* module,
struct symt_compiland* parent,
const char* name,
unsigned long addr, unsigned long size,
uint64_t addr, unsigned long size,
struct symt* type) DECLSPEC_HIDDEN;
extern BOOL symt_normalize_function(struct module* module,
const struct symt_function* func) DECLSPEC_HIDDEN;
Expand Down
6 changes: 3 additions & 3 deletions dlls/dbghelp/msc.c
Expand Up @@ -1393,7 +1393,7 @@ static BOOL codeview_parse_type_table(struct codeview_type_parse* ctp)
/*========================================================================
* Process CodeView line number information.
*/
static unsigned long codeview_get_address(const struct msc_debug_info* msc_dbg,
static uint64_t codeview_get_address(const struct msc_debug_info* msc_dbg,
unsigned seg, unsigned offset);

static void codeview_snarf_linetab(const struct msc_debug_info* msc_dbg, const BYTE* linetab,
Expand Down Expand Up @@ -1538,7 +1538,7 @@ static void codeview_snarf_linetab2(const struct msc_debug_info* msc_dbg, const
* Process CodeView symbol information.
*/

static unsigned int codeview_map_offset(const struct msc_debug_info* msc_dbg,
static uint64_t codeview_map_offset(const struct msc_debug_info* msc_dbg,
unsigned int offset)
{
int nomap = msc_dbg->nomap;
Expand All @@ -1555,7 +1555,7 @@ static unsigned int codeview_map_offset(const struct msc_debug_info* msc_dbg,
return 0;
}

static unsigned long codeview_get_address(const struct msc_debug_info* msc_dbg,
static uint64_t codeview_get_address(const struct msc_debug_info* msc_dbg,
unsigned seg, unsigned offset)
{
int nsect = msc_dbg->nsect;
Expand Down
25 changes: 15 additions & 10 deletions dlls/dbghelp/symbol.c
Expand Up @@ -271,13 +271,13 @@ struct symt_data* symt_new_global_variable(struct module* module,
struct symt_function* symt_new_function(struct module* module,
struct symt_compiland* compiland,
const char* name,
unsigned long addr, unsigned long size,
uint64_t addr, unsigned long size,
struct symt* sig_type)
{
struct symt_function* sym;
struct symt** p;

TRACE_(dbghelp_symt)("Adding global function %s:%s @%lx-%lx\n",
TRACE_(dbghelp_symt)("Adding global function %s:%s @%llx-%llx\n",
debugstr_w(module->module.ModuleName), name, addr, addr + size - 1);

assert(!sig_type || sig_type->tag == SymTagFunctionType);
Expand Down Expand Up @@ -422,7 +422,7 @@ struct symt_block* symt_close_func_block(struct module* module,
assert(func);
assert(func->symt.tag == SymTagFunction);

if (pc) block->size = func->address + pc - block->address;
if (pc) block->size = (uint32_t)(func->address + pc - block->address);
return (block->container->tag == SymTagBlock) ?
CONTAINING_RECORD(block->container, struct symt_block, symt) : NULL;
}
Expand Down Expand Up @@ -933,7 +933,7 @@ static BOOL symt_enum_locals_helper(struct module_pair* pair,
struct symt_function* func, const struct vector* v)
{
struct symt* lsym = NULL;
DWORD pc = pair->pcs->ctx_frame.InstructionOffset;
uint64_t pc = pair->pcs->ctx_frame.InstructionOffset;
unsigned int i;
WCHAR* nameW;
BOOL ret;
Expand Down Expand Up @@ -1189,7 +1189,9 @@ struct sym_enumerate
static BOOL CALLBACK sym_enumerate_cb(PSYMBOL_INFO syminfo, ULONG size, void* ctx)
{
struct sym_enumerate* se = ctx;
return (se->cb)(syminfo->Name, syminfo->Address, syminfo->Size, se->ctx);
return (se->cb)(syminfo->Name,
// Loses digits, use SymEnumerateSymbols instead.
(uint32_t)syminfo->Address, syminfo->Size, se->ctx);
}

/***********************************************************************
Expand Down Expand Up @@ -1300,8 +1302,9 @@ BOOL WINAPI SymGetSymFromAddr(HANDLE hProcess, DWORD Address,
return FALSE;

if (Displacement)
*Displacement = Displacement64;
Symbol->Address = si->Address;
// Conversion loses digits, use SymGetSymFromAddr64 instead.
*Displacement = (DWORD) Displacement64;
Symbol->Address = (DWORD) si->Address;
Symbol->Size = si->Size;
Symbol->Flags = si->Flags;
len = min(Symbol->MaxNameLength, si->MaxNameLen);
Expand Down Expand Up @@ -1442,7 +1445,8 @@ BOOL WINAPI SymGetSymFromName(HANDLE hProcess, PCSTR Name, PIMAGEHLP_SYMBOL Symb
si->MaxNameLen = MAX_SYM_NAME;
if (!SymFromName(hProcess, Name, si)) return FALSE;

Symbol->Address = si->Address;
// Conversion loses digits, use SymGetSymFromName64
Symbol->Address = (DWORD)si->Address;
Symbol->Size = si->Size;
Symbol->Flags = si->Flags;
len = min(Symbol->MaxNameLength, si->MaxNameLen);
Expand Down Expand Up @@ -1570,7 +1574,8 @@ static void copy_line_32_from_64(IMAGEHLP_LINE* l32, const IMAGEHLP_LINE64* l64)
l32->Key = l64->Key;
l32->LineNumber = l64->LineNumber;
l32->FileName = l64->FileName;
l32->Address = l64->Address;
// Conversion loses digits, use *64 functions instead.
l32->Address = (DWORD)l64->Address;
}

/******************************************************************
Expand Down Expand Up @@ -1612,7 +1617,7 @@ BOOL WINAPI SymGetLineFromAddr64(HANDLE hProcess, DWORD64 dwAddr,
if (symt->symt.tag != SymTagFunction) return FALSE;
if (!symt_fill_func_line_info(pair.effective, (struct symt_function*)symt,
dwAddr, Line)) return FALSE;
*pdwDisplacement = dwAddr - Line->Address;
*pdwDisplacement = (DWORD)(dwAddr - Line->Address);
return TRUE;
}

Expand Down
1 change: 1 addition & 0 deletions dlls/winecrt0/debug.c
Expand Up @@ -42,6 +42,7 @@ static int (__cdecl *p__wine_dbg_header)( enum __wine_debug_class cls,
static const char * const debug_classes[] = { "fixme", "err", "warn", "trace" };

static unsigned char default_flags = (1 << __WINE_DBCL_ERR) | (1 << __WINE_DBCL_FIXME);
//static unsigned char default_flags = (1 << __WINE_DBCL_TRACE);
static int nb_debug_options = -1;
static int options_size;
static struct __wine_debug_channel *debug_options;
Expand Down
30 changes: 21 additions & 9 deletions g3log/src/stacktrace_windows.cpp
Expand Up @@ -23,7 +23,7 @@
#include <mutex>
#include <g3log/g3log.hpp>

//#define DEFDBGHELP
// #define DEFDBGHELP

#if !defined(DEFDBGHELP)
#if defined(_WIN64)
Expand Down Expand Up @@ -119,22 +119,27 @@ namespace {

DWORD64 displacement64;
DWORD displacement;
char symbol_buffer[sizeof(SYMBOL_INFO) + 256];
SYMBOL_INFO *symbol = reinterpret_cast<SYMBOL_INFO *>(symbol_buffer);
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
symbol->MaxNameLen = MAX_SYM_NAME;
char symbol_buffer[sizeof(IMAGEHLP_SYMBOL64) + 256];
IMAGEHLP_SYMBOL64 *symbol = reinterpret_cast<IMAGEHLP_SYMBOL64 *>(symbol_buffer);
symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
symbol->MaxNameLength = MAX_SYM_NAME;

IMAGEHLP_LINE64 line;
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
std::string lineInformation;
std::string callInformation;
if (SymFromAddr(GetCurrentProcess(), addr, &displacement64, symbol)) {
callInformation.append(" ").append({std::string(symbol->Name), symbol->NameLen});
if (SymGetLineFromAddr64(GetCurrentProcess(), addr, &displacement, &line)) {

if (SymGetSymFromAddr64(GetCurrentProcess(), addr, &displacement64, symbol))
{
callInformation.append(" ").append(symbol->Name);

if (SymGetLineFromAddr64(GetCurrentProcess(), addr, &displacement, &line))
{
lineInformation.append("\t").append(line.FileName).append(" L: ");
lineInformation.append(std::to_string(line.LineNumber));
}
}
}

frame_dump.append(lineInformation).append(callInformation);
return frame_dump;
}
Expand All @@ -143,6 +148,13 @@ namespace {
// Retrieves all the symbols for the stack frames, fills them witin a text representation and returns it
std::string convertFramesToText(std::vector<uint64_t> &frame_pointers) {
std::string dump; // slightly more efficient than ostringstream

#ifdef DEFDBGHELP
dump += "stack using windows standard dbghelp.dll\n\n";
#else
dump += "stack using dbghelp2.dll\n\n";
#endif

const size_t kSize = frame_pointers.size();
for (size_t index = 0; index < kSize && frame_pointers[index]; ++index) {
dump += getSymbolInformation(index, frame_pointers);
Expand Down

0 comments on commit 3a3e9da

Please sign in to comment.