| 262 | } |
| 263 | |
| 264 | static void print_frame(FILE *out, void *addr) { |
| 265 | HANDLE proc = GetCurrentProcess(); |
| 266 | DWORD64 addr64 = (DWORD64)addr; |
| 267 | |
| 268 | char symbuf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)]; |
| 269 | SYMBOL_INFO *sym = (SYMBOL_INFO*)symbuf; |
| 270 | sym->SizeOfStruct = sizeof(SYMBOL_INFO); |
| 271 | sym->MaxNameLen = MAX_SYM_NAME; |
| 272 | |
| 273 | DWORD64 disp = 0; |
| 274 | bool haveSym = SymFromAddr(proc, addr64, &disp, sym) != FALSE; |
| 275 | if (!haveSym || disp >= kMaxTrustedSymbolOffset) { |
| 276 | // Distant symbol match is likely misattributed — module+offset is more useful. |
| 277 | print_module_fallback(out, proc, addr, addr64); |
| 278 | return; |
| 279 | } |
| 280 | |
| 281 | const char *name = sym->Name; |
| 282 | IMAGEHLP_LINE64 line; |
| 283 | memset(&line, 0, sizeof(line)); |
| 284 | line.SizeOfStruct = sizeof(line); |
| 285 | DWORD lineDisp = 0; |
| 286 | if (SymGetLineFromAddr64(proc, addr64, &lineDisp, &line)) { |
| 287 | fprintf(out, " %p %s+0x%llx %s:%lu\n", |
| 288 | addr, name, (unsigned long long)disp, line.FileName, (unsigned long)line.LineNumber); |
| 289 | } else { |
| 290 | fprintf(out, " %p %s+0x%llx\n", |
| 291 | addr, name, (unsigned long long)disp); |
| 292 | } |
| 293 | } |
| 294 | #else |
| 295 | static void init_symbols() {} |
| 296 |
no test coverage detected