dqn: Start mocking up stack trace lib
This commit is contained in:
parent
76cc1f278c
commit
0028e9ca62
@ -1847,10 +1847,110 @@ static void Dqn_Test_RunSuite()
|
|||||||
dqn_library->log_callback = prev_log_callback;
|
dqn_library->log_callback = prev_log_callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <TlHelp32.h>
|
||||||
|
#include <DbgHelp.h> // STACKFRAME64, ...
|
||||||
|
#include <winnt.h> // CONTEXT
|
||||||
|
#pragma comment(lib, "DbgHelp.lib")
|
||||||
|
|
||||||
|
// extern "C"
|
||||||
|
// {
|
||||||
|
// /*HANDLE*/ void * __stdcall GetCurrentProcess(void);
|
||||||
|
// /*HANDLE*/ void * __stdcall GetCurrentThread(void);
|
||||||
|
// }
|
||||||
|
|
||||||
|
void DumpStackTrace()
|
||||||
|
{
|
||||||
|
#if !defined(_M_X64)
|
||||||
|
#error "Platform is not implemented"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CONTEXT context;
|
||||||
|
RtlCaptureContext(&context);
|
||||||
|
|
||||||
|
STACKFRAME64 frame = {};
|
||||||
|
frame.AddrPC.Offset = context.Rip;
|
||||||
|
frame.AddrPC.Mode = AddrModeFlat;
|
||||||
|
frame.AddrFrame.Offset = context.Rbp;
|
||||||
|
frame.AddrFrame.Mode = AddrModeFlat;
|
||||||
|
frame.AddrStack.Offset = context.Rsp;
|
||||||
|
frame.AddrStack.Mode = AddrModeFlat;
|
||||||
|
|
||||||
|
void *thread = GetCurrentThread();
|
||||||
|
static Dqn_TicketMutex mutex = {};
|
||||||
|
Dqn_TicketMutex_Begin(&mutex);
|
||||||
|
|
||||||
|
void *process = GetCurrentProcess();
|
||||||
|
static bool init = false;
|
||||||
|
if (!init) {
|
||||||
|
SymInitialize(process, nullptr /*UserSearchPath*/, true /*fInvadeProcess*/);
|
||||||
|
SymSetOptions(SYMOPT_LOAD_LINES);
|
||||||
|
init = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (!StackWalk64(IMAGE_FILE_MACHINE_AMD64,
|
||||||
|
process,
|
||||||
|
thread,
|
||||||
|
&frame,
|
||||||
|
&context,
|
||||||
|
nullptr /*ReadMemoryRoutine*/,
|
||||||
|
SymFunctionTableAccess64,
|
||||||
|
SymGetModuleBase64,
|
||||||
|
nullptr /*TrnaslateAddress*/)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame.AddrPC.Offset == frame.AddrReturn.Offset) {
|
||||||
|
// TODO(doyle): Recursion
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame.AddrPC.Offset == 0) {
|
||||||
|
break;
|
||||||
|
// TODO(doyle): Invalid program counter
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// NOTE: Get file+line =================================================================
|
||||||
|
|
||||||
|
IMAGEHLP_LINE64 line = {};
|
||||||
|
line.SizeOfStruct = sizeof(line);
|
||||||
|
DWORD line_displacement = 0;
|
||||||
|
|
||||||
|
if (SymGetLineFromAddr64(process, frame.AddrPC.Offset, &line_displacement, &line)) {
|
||||||
|
printf("%s(%lu): ", line.FileName, line.LineNumber);
|
||||||
|
} else {
|
||||||
|
DWORD error = GetLastError();
|
||||||
|
printf("SymFromAddr returned error : %lu\n", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Get function name ============================================================
|
||||||
|
|
||||||
|
char buffer[sizeof(SYMBOL_INFO) + 1024] = {};
|
||||||
|
SYMBOL_INFO *symbol = new (buffer) SYMBOL_INFO;
|
||||||
|
symbol->SizeOfStruct = sizeof(*symbol);
|
||||||
|
symbol->MaxNameLen = 1024;
|
||||||
|
uint64_t symbol_displacement = 0; // Offset to the beginning of the symbol to the address
|
||||||
|
|
||||||
|
if (SymFromAddr(process, frame.AddrPC.Offset, &symbol_displacement, symbol)) {
|
||||||
|
printf("%.*s\n", DQN_CAST(int)symbol->NameLen, symbol->Name);
|
||||||
|
} else {
|
||||||
|
DWORD error = GetLastError();
|
||||||
|
printf("SymFromAddr returned error : %lu\n", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Dqn_TicketMutex_End(&mutex);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(DQN_TEST_WITH_MAIN)
|
#if defined(DQN_TEST_WITH_MAIN)
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
(void)argv; (void)argc;
|
(void)argv; (void)argc;
|
||||||
|
printf("%s\n\n", b_stacktrace_get_string());
|
||||||
|
DumpStackTrace();
|
||||||
|
return 1;
|
||||||
|
|
||||||
Dqn_Test_RunSuite();
|
Dqn_Test_RunSuite();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ pushd Build
|
|||||||
REM Z7 Combine multi-debug files to one debug file
|
REM Z7 Combine multi-debug files to one debug file
|
||||||
set common_flags=-D DQN_TEST_WITH_MAIN -I %script_dir% %script_dir%\Misc\dqn_unit_tests.cpp
|
set common_flags=-D DQN_TEST_WITH_MAIN -I %script_dir% %script_dir%\Misc\dqn_unit_tests.cpp
|
||||||
|
|
||||||
set msvc_driver_flags=%common_flags% -MT -EHa -GR- -Od -Oi -Z7 -wd4201 -W4 -WX -nologo
|
set msvc_driver_flags=%common_flags% -MT -EHa -GR- -Od -Oi -Z7 -wd4201 -W4 -nologo
|
||||||
|
|
||||||
REM Optionally pass `-analyze` to `msvc_compile_flags` for more checks, but,
|
REM Optionally pass `-analyze` to `msvc_compile_flags` for more checks, but,
|
||||||
REM it slows down compilation by around 5s on my old laptop.
|
REM it slows down compilation by around 5s on my old laptop.
|
||||||
|
Loading…
Reference in New Issue
Block a user