Skip to content

Commit f330bde

Browse files
mmozeikoNikitaSmith057
authored andcommitted
better callstack for null calls
This improves callstack in win32 unhandled exception handler when indirect call to NULL happens. Before no call stack was printed at all, so it was hard to know what happened. Now call stack explicitly will print out [NULL] stack entry + rest of call stack entries. This is done by manually looking up return address from call stack when possible. Also fixes wine compatibility for os_commit function. Wine does not support RIO buffer functions.
1 parent 3abfb80 commit f330bde

File tree

1 file changed

+43
-15
lines changed

1 file changed

+43
-15
lines changed

src/os/core/win32/os_core_win32.c

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,11 @@ internal B32
208208
os_commit(void *ptr, U64 size)
209209
{
210210
B32 result = (VirtualAlloc(ptr, size, MEM_COMMIT, PAGE_READWRITE) != 0);
211-
w32_rio_functions.RIODeregisterBuffer(w32_rio_functions.RIORegisterBuffer(ptr, size));
211+
if (w32_rio_functions.RIORegisterBuffer)
212+
{
213+
// wine does not implement these functions
214+
w32_rio_functions.RIODeregisterBuffer(w32_rio_functions.RIORegisterBuffer(ptr, size));
215+
}
212216
return result;
213217
}
214218

@@ -1565,7 +1569,43 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs)
15651569
#else
15661570
# error Arch not supported!
15671571
#endif
1568-
1572+
1573+
#if BUILD_CONSOLE_INTERFACE
1574+
buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, L"\nCreate a new issue with this report at %S.\n\n", BUILD_ISSUES_LINK_STRING_LITERAL);
1575+
#else
1576+
buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen,
1577+
L"\nPress Ctrl+C to copy this text to clipboard, then create a new issue at\n"
1578+
L"<a href=\"%S\">%S</a>\n\n", BUILD_ISSUES_LINK_STRING_LITERAL, BUILD_ISSUES_LINK_STRING_LITERAL);
1579+
#endif
1580+
buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, L"Call stack:\n");
1581+
1582+
U64 frame_offset = 0;
1583+
1584+
if (frame.AddrPC.Offset == 0)
1585+
{
1586+
// if IP address is 0 then most likely we have called indirectly on NULL function pointer
1587+
// which means no useful stack unwinding will happen, because there's no unwind info for address 0
1588+
// but we can try reading 8 bytes of return address from stack, and start unwinding there
1589+
1590+
ULONG_PTR hi, lo;
1591+
GetCurrentThreadStackLimits(&lo, &hi);
1592+
if (frame.AddrStack.Offset >= lo && frame.AddrStack.Offset <= hi - sizeof(void*))
1593+
{
1594+
frame.AddrPC.Offset = *(DWORD64*)frame.AddrStack.Offset - 1;
1595+
frame.AddrStack.Offset += sizeof(void*);
1596+
#if defined(_M_AMD64)
1597+
context->Rip = frame.AddrPC.Offset;
1598+
context->Rsp = frame.AddrStack.Offset;
1599+
#elif defined(_M_ARM64)
1600+
context->Pc = frame.AddrPC.Offset;
1601+
context->Sp = frame.AddrStack.Offset;
1602+
#endif
1603+
}
1604+
1605+
buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, L"1. [NULL]\n");
1606+
frame_offset = 1;
1607+
}
1608+
15691609
for(U32 idx=0; ;idx++)
15701610
{
15711611
const U32 max_frames = 32;
@@ -1586,19 +1626,7 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs)
15861626
break;
15871627
}
15881628

1589-
if(idx==0)
1590-
{
1591-
#if BUILD_CONSOLE_INTERFACE
1592-
buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, L"\nCreate a new issue with this report at %S.\n\n", BUILD_ISSUES_LINK_STRING_LITERAL);
1593-
#else
1594-
buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen,
1595-
L"\nPress Ctrl+C to copy this text to clipboard, then create a new issue at\n"
1596-
L"<a href=\"%S\">%S</a>\n\n", BUILD_ISSUES_LINK_STRING_LITERAL, BUILD_ISSUES_LINK_STRING_LITERAL);
1597-
#endif
1598-
buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, L"Call stack:\n");
1599-
}
1600-
1601-
buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, L"%u. [0x%I64x]", idx + 1, address);
1629+
buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, L"%u. [0x%I64x]", frame_offset + idx + 1, address);
16021630

16031631
struct {
16041632
SYMBOL_INFOW info;

0 commit comments

Comments
 (0)