More specific crash messages for null pointer reads/writes on Windows and POSIX systems

This commit is contained in:
UnknownShadow200 2025-07-25 07:26:43 +10:00
parent 6f6eba3d2c
commit 663a8ef24b
4 changed files with 35 additions and 19 deletions

View File

@ -123,8 +123,8 @@ GPUCmd_PushRDP:
.func GPUCmd_MatrixLoad
GPUCmd_MatrixLoad:
#define src s6
#define dst s7
#define src t4
#define dst t5
#define vmat0_i $v02
#define vmat1_i $v03
@ -348,8 +348,8 @@ GL_TnL:
.func GPUCmd_DrawQuad
GPUCmd_DrawQuad:
#define vtx_ptr a0
#define mtx_ptr s2
#define src_ptr s3
#define mtx_ptr v0
#define src_ptr v1
#define v___ $v01

View File

@ -46,7 +46,7 @@ GL_ClipTriangle:
#define plane_flag t6
#define in_count t7
#define in_end t8
#define in_list s0
#define in_list v0
#define out_list s1
#define plane s2
#define intersection s3
@ -147,11 +147,11 @@ gl_clip_edge_loop:
#define prev_flag t4
# Check which side of the plane the two vertices are on
lhu cur_vtx, 0(cur_ptr)
lhu prev_vtx, 0(prev_ptr)
lbu cur_flag, SCREEN_VTX_CLIP_CODE(cur_vtx)
lhu cur_vtx, 0(cur_ptr)
lhu prev_vtx, 0(prev_ptr)
lbu cur_flag, SCREEN_VTX_CLIP_CODE(cur_vtx)
lbu prev_flag, SCREEN_VTX_CLIP_CODE(prev_vtx)
and cur_flag, plane_flag
and cur_flag, plane_flag
and prev_flag, plane_flag
# If they are on opposite sides, there is an intersection

View File

@ -236,6 +236,8 @@ cc_uint64 Stopwatch_ElapsedMicroseconds(cc_uint64 beg, cc_uint64 end) {
/*########################################################################################################################*
*-------------------------------------------------------Crash handling----------------------------------------------------*
*#########################################################################################################################*/
#define IsNullDerefException(info) (info->si_signo == SIGSEGV && info->si_addr == 0)
static const char* SignalDescribe(int type) {
switch (type) {
case SIGSEGV: return "SIGSEGV";
@ -268,8 +270,10 @@ static void SignalHandler(int sig, siginfo_t* info, void* ctx) {
desc = SignalDescribe(type);
String_InitArray_NT(msg, msgBuffer);
if (desc) {
String_Format3(&msg, "Unhandled signal %c (code %i) at %x", desc, &code, &addr);
if (IsNullDerefException(info)) {
String_Format1(&msg, "Unhandled NULL_POINTER_DEREF (code %i)", &code);
} else if (desc) {
String_Format3(&msg, "Unhandled %c (code %i) at %x", desc, &code, &addr);
} else {
String_Format3(&msg, "Unhandled signal %i (code %i) at %x", &type, &code, &addr);
}

View File

@ -199,8 +199,16 @@ cc_uint64 Stopwatch_Measure(void) {
/*########################################################################################################################*
*-------------------------------------------------------Crash handling----------------------------------------------------*
*#########################################################################################################################*/
static const char* ExceptionDescribe(cc_uint32 code) {
switch (code) {
/* In EXCEPTION_ACCESS_VIOLATION case, arg 1 is access type and arg 2 is virtual address */
/* https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-exception_record */
#define IsNullReadException(r) (r->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && r->ExceptionInformation[1] == 0 && r->ExceptionInformation[0] == 0)
#define IsNullWriteException(r) (r->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && r->ExceptionInformation[1] == 0 && r->ExceptionInformation[0] == 1)
static const char* ExceptionDescribe(struct _EXCEPTION_RECORD* rec) {
if (IsNullReadException(rec)) return "NULL_POINTER_READ";
if (IsNullWriteException(rec)) return "NULL_POINTER_WRITE";
switch (rec->ExceptionCode) {
case EXCEPTION_ACCESS_VIOLATION: return "ACCESS_VIOLATION";
case EXCEPTION_ILLEGAL_INSTRUCTION: return "ILLEGAL_INSTRUCTION";
case EXCEPTION_INT_DIVIDE_BY_ZERO: return "DIVIDE_BY_ZERO";
@ -210,14 +218,16 @@ static const char* ExceptionDescribe(cc_uint32 code) {
static LONG WINAPI UnhandledFilter(struct _EXCEPTION_POINTERS* info) {
cc_string msg; char msgBuffer[128 + 1];
struct _EXCEPTION_RECORD* rec;
const char* desc;
cc_uint32 code;
cc_uintptr addr;
DWORD i, numArgs;
code = (cc_uint32)info->ExceptionRecord->ExceptionCode;
addr = (cc_uintptr)info->ExceptionRecord->ExceptionAddress;
desc = ExceptionDescribe(code);
rec = info->ExceptionRecord;
code = (cc_uint32)rec->ExceptionCode;
addr = (cc_uintptr)rec->ExceptionAddress;
desc = ExceptionDescribe(rec);
String_InitArray_NT(msg, msgBuffer);
if (desc) {
@ -226,13 +236,15 @@ static LONG WINAPI UnhandledFilter(struct _EXCEPTION_POINTERS* info) {
String_Format2(&msg, "Unhandled exception 0x%h at %x", &code, &addr);
}
numArgs = info->ExceptionRecord->NumberParameters;
if (numArgs) {
numArgs = rec->NumberParameters;
if (IsNullReadException(rec) || IsNullWriteException(rec)) {
/* Pointless to log exception arguments in this case */
} else if (numArgs) {
numArgs = min(numArgs, EXCEPTION_MAXIMUM_PARAMETERS);
String_AppendConst(&msg, " [");
for (i = 0; i < numArgs; i++) {
String_Format1(&msg, "0x%x,", &info->ExceptionRecord->ExceptionInformation[i]);
String_Format1(&msg, "0x%x,", &rec->ExceptionInformation[i]);
}
String_Append(&msg, ']');
}