Skip to content

Instantly share code, notes, and snippets.

@lazalong
Last active November 8, 2019 07:08
Show Gist options
  • Save lazalong/4356a996feabc693c0fdc775090ec80b to your computer and use it in GitHub Desktop.
Save lazalong/4356a996feabc693c0fdc775090ec80b to your computer and use it in GitHub Desktop.
MSVC Stacktrace test
// ------------ test.v ---------------------
fn main() {
test()
}
fn test() {
print_backtrace() // Note 10 frames returned by CaptureStackBackTrace in a C program
}
// ------------------- os_windows.v line 40 -----------------------
// win: _SYMBOL_INFO (for DbgHelp.h)
// https://docs.microsoft.com/en-us/windows/win32/api/dbghelp/ns-dbghelp-symbol_info
pub struct SymbolInfo {
pub mut:
SizeOfStruct u16
TypeIndex u16 // Type Index of symbol
Reserved [2]u64
Index u16
Size u16
ModBase u64 // Base Address of module comtaining this symbol
Flags u16
Value u64 // Value of symbol, ValuePresent should be 1
Address u64 // Address of symbol including base address of module
Register u16 // register holding value or pointer to value
Scope u16 // scope of the symbol
Tag u16 // pdb classification
NameLen u16 // Actual length of name
MaxNameLen u16
Name []string // CHAR[] Name of symbol
}
// ------------- builtin.v line 104 --------------------
$if windows {
println('print_backtrace window\n')
stack := [100]byteptr
mut handle := C.GetCurrentProcess() // same result with (*voidptr)(C.GetCurrentProcess())
mut success := C.SymInitialize(handle, 0, 1)
println('Success= ${int(success)} handle= ${handle}')
if (success != 1) {
println('Failed getting process: Aborting backtrace.\n')
return
}
frames := C.CaptureStackBackTrace(0, 100, stack, 0)
println('frames= ${int(frames)}')
for i:=0; i < frames; i++
{
test := u32(stack[i])
println(' i= ${i.str()} - ${u32(test)}')
mut symbol_info := os.SymbolInfo{}
symbol_info.SizeOfStruct = sizeof(os.SymbolInfo)
symbol_info.MaxNameLen = 255
symbol_info.Name = ([]string)(calloc(256))
success = C.SymFromAddr(handle, stack[i], 0, &symbol_info) // same with u64(stack[i])
println(' success: ${int(success)} Name: ${symbol_info.Name.str()} SizeOfStruct: ${symbol_info.SizeOfStruct} Address: $symbol_info.Address \n')
}
return
}
// ----------------- test.cpp --------------------------
void printStack(void);
void printStack(void)
{
unsigned int i;
void* stack[100];
unsigned short frames;
SYMBOL_INFO* symbol;
HANDLE process;
process = GetCurrentProcess();
printf("Process: %i \n", process);
SymInitialize(process, NULL, TRUE);
frames = CaptureStackBackTrace(0, 100, stack, NULL);
symbol = (SYMBOL_INFO*)calloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char), 1);
symbol->MaxNameLen = 255;
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
printf("Frames %i \n", frames);
for (i = 0; i < frames; i++)
{
SymFromAddr(process, (DWORD64)(stack[i]), 0, symbol);
printf("%i: %s - 0x%0X\n", frames - i - 1, symbol->Name, symbol->Address);
}
free(symbol);
}
int fct()
{
printStack();
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
printf("\n\n\nShow an object:\n\n\n");
fct();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment