Windows: Try to fix backtraces in crash handling always only showing one entry on Windows 9x

This commit is contained in:
UnknownShadow200 2023-09-28 22:15:08 +10:00
parent 899b66ae13
commit 000a74932b
2 changed files with 15 additions and 6 deletions

View File

@ -24,7 +24,7 @@ $(BUILD_DIR)/%.o: third_party/bearssl/src/%.c
$(TARGET).elf: $(OBJS) $(TARGET).elf: $(OBJS)
kos-cc $< -o $@ kos-cc $^ -o $@
$(TARGET).bin: $(TARGET).elf $(TARGET).bin: $(TARGET).elf
sh-elf-objcopy -R .stack -O binary $(TARGET).elf $(TARGET).bin sh-elf-objcopy -R .stack -O binary $(TARGET).elf $(TARGET).bin

View File

@ -273,10 +273,20 @@ static void DumpFrame(cc_string* trace, void* addr) {
*-------------------------------------------------------Backtracing-------------------------------------------------------* *-------------------------------------------------------Backtracing-------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
#if defined CC_BUILD_WIN #if defined CC_BUILD_WIN
/* This callback function is used so stack Walking works using StackWalk properly on Windows 9x: */
/* - on Windows 9x process ID is passed instead of process handle as the "process" argument */
/* - the SymXYZ functions expect a process ID on Windows 9x, so that works fine */
/* - if NULL is passed as the "ReadMemory" argument, the default callback using ReadProcessMemory is used */
/* - however, ReadProcessMemory expects a process handle, and so that will fail since it's given a process ID */
/* So to work around this, instead manually call ReadProcessMemory with the current process handle */
static BOOL __stdcall ReadMemCallback(HANDLE process, DWORD_PTR baseAddress, PVOID buffer, DWORD size, PDWORD numBytesRead) {
return ReadProcessMemory(GetCurrentProcess(), (LPCVOID)baseAddress, buffer, size, numBytesRead);
}
static int GetFrames(CONTEXT* ctx, cc_uintptr* addrs, int max) { static int GetFrames(CONTEXT* ctx, cc_uintptr* addrs, int max) {
STACKFRAME frame = { 0 }; STACKFRAME frame = { 0 };
HANDLE process, thread;
int count, type; int count, type;
HANDLE thread;
frame.AddrPC.Mode = AddrModeFlat; frame.AddrPC.Mode = AddrModeFlat;
frame.AddrFrame.Mode = AddrModeFlat; frame.AddrFrame.Mode = AddrModeFlat;
@ -296,12 +306,11 @@ static int GetFrames(CONTEXT* ctx, cc_uintptr* addrs, int max) {
/* Always available after XP, so use that */ /* Always available after XP, so use that */
return RtlCaptureStackBackTrace(0, max, (void**)addrs, NULL); return RtlCaptureStackBackTrace(0, max, (void**)addrs, NULL);
#endif #endif
process = GetCurrentProcess();
thread = GetCurrentThread(); thread = GetCurrentThread();
for (count = 0; count < max; count++) for (count = 0; count < max; count++)
{ {
if (!StackWalk(type, process, thread, &frame, ctx, NULL, SymFunctionTableAccess, SymGetModuleBase, NULL)) break; if (!StackWalk(type, curProcess, thread, &frame, ctx, ReadMemCallback, SymFunctionTableAccess, SymGetModuleBase, NULL)) break;
if (!frame.AddrFrame.Offset) break; if (!frame.AddrFrame.Offset) break;
addrs[count] = frame.AddrPC.Offset; addrs[count] = frame.AddrPC.Offset;
} }