Pyrogenesis  trunk
Classes | Macros | Typedefs | Enumerations | Functions | Variables
wdbg_sym.cpp File Reference
#include "precompiled.h"
#include "lib/sysdep/os/win/wdbg_sym.h"
#include <cstdlib>
#include <cstdio>
#include <set>
#include "lib/byte_order.h"
#include "lib/module_init.h"
#include "lib/sysdep/cpu.h"
#include "lib/debug_stl.h"
#include "lib/app_hooks.h"
#include "lib/external_libraries/dbghelp.h"
#include "lib/sysdep/os/win/wdbg.h"
#include "lib/sysdep/os/win/wutil.h"
#include "lib/sysdep/os/win/winit.h"
Include dependency graph for wdbg_sym.cpp:

Classes

struct  SYMBOL_INFO_PACKAGEW2
 
struct  TI_FINDCHILDREN_PARAMS2
 
struct  DumpState
 

Macros

#define INDENT   STMT(for(size_t i__ = 0; i__ <= state.level; i__++) out(L" ");)
 
#define UNINDENT   STMT(out_erase((state.level+1)*4);)
 
#define SUPPRESS_HANDLE(name)   if(!wcscmp(type_name, L#name L"__")) return true;
 

Typedefs

typedef Status(* DumpFunc) (DWORD typeId, const u8 *p, DumpState &state)
 

Enumerations

enum  CV_HREG_e { CV_REG_EBP = 22, CV_AMD64_RBP = 334 }
 

Functions

 WINIT_REGISTER_CRITICAL_INIT (wdbg_sym_Init)
 
static WUTIL_FUNC (pRtlCaptureContext, VOID,(PCONTEXT))
 
static Status wdbg_sym_Init ()
 
static Status InitDbghelp ()
 
static void sym_init ()
 
static STACKFRAME64 PopulateStackFrame (CONTEXT &context)
 
static IMAGEHLP_STACK_FRAME PopulateImageStackFrame (const STACKFRAME64 &sf)
 
static Status ResolveSymbol_lk (void *ptr_of_interest, wchar_t *sym_name, wchar_t *file, int *line)
 
Status debug_ResolveSymbol (void *ptr_of_interest, wchar_t *sym_name, wchar_t *file, int *line)
 read and return symbol information for the given address. More...
 
Status debug_CaptureContext (void *pcontext)
 
static Status CallStackWalk (STACKFRAME64 &sf, CONTEXT &context)
 
Status wdbg_sym_WalkStack (StackFrameCallback cb, uintptr_t cbData, CONTEXT &context, const wchar_t *lastFuncToSkip)
 Iterate over a call stack, invoking a callback for each frame encountered. More...
 
void * debug_GetCaller (void *pcontext, const wchar_t *lastFuncToSkip)
 return the caller of a certain function on the call stack. More...
 
static void out_init (wchar_t *buf, size_t max_chars)
 
static void out (const wchar_t *fmt,...)
 
static void out_erase (size_t num_chars)
 
static void out_latch_pos ()
 
static Status out_check_limit ()
 
static bool is_string (const u8 *p, size_t stride)
 
static Status dump_sym (DWORD id, const u8 *p, DumpState &state)
 
static void dump_error (Status err)
 
static Status dump_string (const u8 *p, size_t el_size)
 
static void seq_determine_formatting (size_t el_size, size_t el_count, bool *fits_on_one_line, size_t *num_elements_to_show)
 
static Status dump_sequence (DebugStlIterator el_iterator, void *internal, size_t el_count, DWORD el_type_id, size_t el_size, DumpState &state)
 
static const u8array_iterator (void *internal, size_t el_size)
 
static Status dump_array (const u8 *p, size_t el_count, DWORD el_type_id, size_t el_size, DumpState &state)
 
static Status CanHandleDataKind (DWORD dataKind)
 
static bool IsRelativeToFramePointer (DWORD flags, DWORD reg)
 
static bool IsUnretrievable (DWORD flags)
 
static Status DetermineSymbolAddress (DWORD id, const SYMBOL_INFOW *sym, const DumpState &state, const u8 **pp)
 
static Status dump_sym_array (DWORD type_id, const u8 *p, DumpState &state)
 
static void AppendCharacterIfPrintable (u64 data)
 
static Status dump_sym_base_type (DWORD type_id, const u8 *p, DumpState &state)
 
static Status dump_sym_base_class (DWORD type_id, const u8 *p, DumpState &state)
 
static Status dump_sym_data (DWORD id, const u8 *p, DumpState &state)
 
static Status dump_sym_enum (DWORD type_id, const u8 *p, DumpState &state)
 
static Status dump_sym_function (DWORD type_id, const u8 *p, DumpState &state)
 
static Status dump_sym_function_type (DWORD type_id, const u8 *p, DumpState &state)
 
static void ptr_reset_visited ()
 
static bool ptr_already_visited (const u8 *p)
 
static Status dump_sym_pointer (DWORD type_id, const u8 *p, DumpState &state)
 
static Status dump_sym_typedef (DWORD type_id, const u8 *p, DumpState &state)
 
static Status udt_get_child_type (const wchar_t *child_name, ULONG numChildren, const DWORD *children, const DumpState &state, DWORD *el_type_id, size_t *el_size)
 
static Status udt_dump_std (const wchar_t *type_name, const u8 *p, size_t size, DumpState &state, ULONG numChildren, const DWORD *children)
 
static bool udt_should_suppress (const wchar_t *type_name)
 
static Status udt_dump_suppressed (const wchar_t *type_name, const u8 *p, size_t size, DumpState state, ULONG numChildren, const DWORD *children)
 
static bool udt_fits_on_one_line (const wchar_t *type_name, size_t child_count, size_t total_size)
 
static Status udt_dump_normal (const wchar_t *type_name, const u8 *p, size_t size, DumpState state, ULONG numChildren, const DWORD *children)
 
static Status dump_sym_udt (DWORD type_id, const u8 *p, DumpState &state)
 
static Status dump_sym_vtable (DWORD type_id, const u8 *p, DumpState &state)
 
static Status dump_sym_unknown (DWORD type_id, const u8 *p, DumpState &state)
 
static DumpFunc DumpFuncFromTypeTag (DWORD typeTag)
 
static bool ShouldSkipSymbol (const wchar_t *name)
 
static BOOL CALLBACK dump_sym_cb (SYMBOL_INFOW *sym, ULONG size, PVOID userContext)
 
static Status dump_frame_cb (const STACKFRAME64 *sf, uintptr_t userContext)
 
Status debug_DumpStack (wchar_t *buf, size_t maxChars, void *pcontext, const wchar_t *lastFuncToSkip)
 write a complete stack trace (including values of local variables) into the specified buffer. More...
 
void wdbg_sym_WriteMinidump (EXCEPTION_POINTERS *exception_pointers)
 

Variables

static HANDLE hProcess
 
static WORD machine
 
static const size_t maxIndirection = 255
 
static const size_t maxLevel = 255
 
static size_t out_chars_left
 
static wchar_tout_pos
 
static bool out_have_warned_of_overflow
 
static wchar_tout_latched_pos
 
static bool out_have_warned_of_limit
 
static const size_t maxVisited = 1000
 
static const u8visited [maxVisited]
 
static size_t numVisited
 

Macro Definition Documentation

#define INDENT   STMT(for(size_t i__ = 0; i__ <= state.level; i__++) out(L" ");)
#define SUPPRESS_HANDLE (   name)    if(!wcscmp(type_name, L#name L"__")) return true;
#define UNINDENT   STMT(out_erase((state.level+1)*4);)

Typedef Documentation

typedef Status(* DumpFunc) (DWORD typeId, const u8 *p, DumpState &state)

Enumeration Type Documentation

enum CV_HREG_e
Enumerator
CV_REG_EBP 
CV_AMD64_RBP 

Function Documentation

static void AppendCharacterIfPrintable ( u64  data)
static
static const u8* array_iterator ( void *  internal,
size_t  el_size 
)
static
static Status CallStackWalk ( STACKFRAME64 &  sf,
CONTEXT &  context 
)
static
static Status CanHandleDataKind ( DWORD  dataKind)
static
Status debug_CaptureContext ( void *  context)
Parameters
contextmust point to an instance of the platform-specific type (e.g. CONTEXT) or CACHE_ALIGNED storage of DEBUG_CONTEXT_SIZE bytes.
Status debug_DumpStack ( wchar_t buf,
size_t  maxChars,
void *  context,
const wchar_t lastFuncToSkip 
)

write a complete stack trace (including values of local variables) into the specified buffer.

Parameters
bufTarget buffer.
maxCharsMax chars of buffer (should be several thousand).
contextPlatform-specific representation of execution state (e.g. Win32 CONTEXT). either specify an SEH exception's context record or use debug_CaptureContext to retrieve the current state. Rationale: intermediates such as debug_DisplayError change the context, so it should be captured as soon as possible.
lastFuncToSkipIs used for omitting error-reporting functions like debug_OnAssertionFailure from the stack trace. It is either 0 (skip nothing) or a substring of a function's name (this allows platform-independent matching of stdcall-decorated names). Rationale: this is safer than specifying a fixed number of frames, which can be incorrect due to inlining.
Returns
Status; ERR::REENTERED if reentered via recursion or multithreading (not allowed since static data is used).
void* debug_GetCaller ( void *  context,
const wchar_t lastFuncToSkip 
)

return the caller of a certain function on the call stack.

this function is useful for recording (partial) stack traces for memory allocation tracking, etc.

Parameters
context,lastFuncToSkip- see debug_DumpStack
Returns
address of the caller
Status debug_ResolveSymbol ( void *  ptr_of_interest,
wchar_t sym_name,
wchar_t file,
int *  line 
)

read and return symbol information for the given address.

NOTE: the PDB implementation is rather slow (~500 us).

Parameters
ptr_of_interestaddress of symbol (e.g. function, variable)
sym_nameoptional out; holds at least DEBUG_SYMBOL_CHARS; receives symbol name returned via debug info.
fileoptional out; holds at least DEBUG_FILE_CHARS; receives base name only (no path; see rationale in wdbg_sym) of source file containing the symbol.
lineoptional out; receives source file line number of symbol.

note: all of the output parameters are optional; we pass back as much information as is available and desired.

Returns
Status; INFO::OK iff any information was successfully retrieved and stored.
static Status DetermineSymbolAddress ( DWORD  id,
const SYMBOL_INFOW *  sym,
const DumpState state,
const u8 **  pp 
)
static
static Status dump_array ( const u8 p,
size_t  el_count,
DWORD  el_type_id,
size_t  el_size,
DumpState state 
)
static
static void dump_error ( Status  err)
static
static Status dump_frame_cb ( const STACKFRAME64 *  sf,
uintptr_t  userContext 
)
static
static Status dump_sequence ( DebugStlIterator  el_iterator,
void *  internal,
size_t  el_count,
DWORD  el_type_id,
size_t  el_size,
DumpState state 
)
static
static Status dump_string ( const u8 p,
size_t  el_size 
)
static
static Status dump_sym ( DWORD  id,
const u8 p,
DumpState state 
)
static
static Status dump_sym_array ( DWORD  type_id,
const u8 p,
DumpState state 
)
static
static Status dump_sym_base_class ( DWORD  type_id,
const u8 p,
DumpState state 
)
static
static Status dump_sym_base_type ( DWORD  type_id,
const u8 p,
DumpState state 
)
static
static BOOL CALLBACK dump_sym_cb ( SYMBOL_INFOW *  sym,
ULONG  size,
PVOID  userContext 
)
static
static Status dump_sym_data ( DWORD  id,
const u8 p,
DumpState state 
)
static
static Status dump_sym_enum ( DWORD  type_id,
const u8 p,
DumpState state 
)
static
static Status dump_sym_function ( DWORD  type_id,
const u8 p,
DumpState state 
)
static
static Status dump_sym_function_type ( DWORD  type_id,
const u8 p,
DumpState state 
)
static
static Status dump_sym_pointer ( DWORD  type_id,
const u8 p,
DumpState state 
)
static
static Status dump_sym_typedef ( DWORD  type_id,
const u8 p,
DumpState state 
)
static
static Status dump_sym_udt ( DWORD  type_id,
const u8 p,
DumpState state 
)
static
static Status dump_sym_unknown ( DWORD  type_id,
const u8 p,
DumpState state 
)
static
static Status dump_sym_vtable ( DWORD  type_id,
const u8 p,
DumpState state 
)
static
static DumpFunc DumpFuncFromTypeTag ( DWORD  typeTag)
static
static Status InitDbghelp ( )
static
static bool is_string ( const u8 p,
size_t  stride 
)
static
static bool IsRelativeToFramePointer ( DWORD  flags,
DWORD  reg 
)
static
static bool IsUnretrievable ( DWORD  flags)
static
static void out ( const wchar_t fmt,
  ... 
)
static
static Status out_check_limit ( )
static
static void out_erase ( size_t  num_chars)
static
static void out_init ( wchar_t buf,
size_t  max_chars 
)
static
static void out_latch_pos ( )
static
static IMAGEHLP_STACK_FRAME PopulateImageStackFrame ( const STACKFRAME64 &  sf)
static
static STACKFRAME64 PopulateStackFrame ( CONTEXT &  context)
static
static bool ptr_already_visited ( const u8 p)
static
static void ptr_reset_visited ( )
static
static Status ResolveSymbol_lk ( void *  ptr_of_interest,
wchar_t sym_name,
wchar_t file,
int *  line 
)
static
static void seq_determine_formatting ( size_t  el_size,
size_t  el_count,
bool *  fits_on_one_line,
size_t *  num_elements_to_show 
)
static
static bool ShouldSkipSymbol ( const wchar_t name)
static
static void sym_init ( )
static
static Status udt_dump_normal ( const wchar_t type_name,
const u8 p,
size_t  size,
DumpState  state,
ULONG  numChildren,
const DWORD children 
)
static
static Status udt_dump_std ( const wchar_t type_name,
const u8 p,
size_t  size,
DumpState state,
ULONG  numChildren,
const DWORD children 
)
static
static Status udt_dump_suppressed ( const wchar_t type_name,
const u8 p,
size_t  size,
DumpState  state,
ULONG  numChildren,
const DWORD children 
)
static
static bool udt_fits_on_one_line ( const wchar_t type_name,
size_t  child_count,
size_t  total_size 
)
static
static Status udt_get_child_type ( const wchar_t child_name,
ULONG  numChildren,
const DWORD children,
const DumpState state,
DWORD el_type_id,
size_t *  el_size 
)
static
static bool udt_should_suppress ( const wchar_t type_name)
static
static Status wdbg_sym_Init ( )
static
Status wdbg_sym_WalkStack ( StackFrameCallback  cb,
uintptr_t  cbData,
CONTEXT &  context,
const wchar_t lastFuncToSkip = 0 
)

Iterate over a call stack, invoking a callback for each frame encountered.

Parameters
cb
cbData
contextProcessor context from which to start (taken from an exception record or debug_CaptureContext).
lastFuncToSkip
Note
It is safe to use ENSURE/debug_warn/WARN_RETURN_STATUS_IF_ERR even during a stack trace (which is triggered by ENSURE et al. in app code) because nested stack traces are ignored and only the error is displayed.
void wdbg_sym_WriteMinidump ( EXCEPTION_POINTERS *  exception_pointers)
WINIT_REGISTER_CRITICAL_INIT ( wdbg_sym_Init  )
static WUTIL_FUNC ( pRtlCaptureContext  ,
VOID  ,
(PCONTEXT)   
)
static

Variable Documentation

HANDLE hProcess
static
WORD machine
static
const size_t maxIndirection = 255
static
const size_t maxLevel = 255
static
const size_t maxVisited = 1000
static
size_t numVisited
static
size_t out_chars_left
static
bool out_have_warned_of_limit
static
bool out_have_warned_of_overflow
static
wchar_t* out_latched_pos
static
wchar_t* out_pos
static
const u8* visited[maxVisited]
static