Last active
November 8, 2019 07:08
-
-
Save lazalong/4356a996feabc693c0fdc775090ec80b to your computer and use it in GitHub Desktop.
MSVC Stacktrace test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ------------ 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