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 .func GPUCmd_MatrixLoad
GPUCmd_MatrixLoad: GPUCmd_MatrixLoad:
#define src s6 #define src t4
#define dst s7 #define dst t5
#define vmat0_i $v02 #define vmat0_i $v02
#define vmat1_i $v03 #define vmat1_i $v03
@ -348,8 +348,8 @@ GL_TnL:
.func GPUCmd_DrawQuad .func GPUCmd_DrawQuad
GPUCmd_DrawQuad: GPUCmd_DrawQuad:
#define vtx_ptr a0 #define vtx_ptr a0
#define mtx_ptr s2 #define mtx_ptr v0
#define src_ptr s3 #define src_ptr v1
#define v___ $v01 #define v___ $v01

View File

@ -46,7 +46,7 @@ GL_ClipTriangle:
#define plane_flag t6 #define plane_flag t6
#define in_count t7 #define in_count t7
#define in_end t8 #define in_end t8
#define in_list s0 #define in_list v0
#define out_list s1 #define out_list s1
#define plane s2 #define plane s2
#define intersection s3 #define intersection s3
@ -147,11 +147,11 @@ gl_clip_edge_loop:
#define prev_flag t4 #define prev_flag t4
# Check which side of the plane the two vertices are on # Check which side of the plane the two vertices are on
lhu cur_vtx, 0(cur_ptr) lhu cur_vtx, 0(cur_ptr)
lhu prev_vtx, 0(prev_ptr) lhu prev_vtx, 0(prev_ptr)
lbu cur_flag, SCREEN_VTX_CLIP_CODE(cur_vtx) lbu cur_flag, SCREEN_VTX_CLIP_CODE(cur_vtx)
lbu prev_flag, SCREEN_VTX_CLIP_CODE(prev_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 and prev_flag, plane_flag
# If they are on opposite sides, there is an intersection # 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----------------------------------------------------* *-------------------------------------------------------Crash handling----------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
#define IsNullDerefException(info) (info->si_signo == SIGSEGV && info->si_addr == 0)
static const char* SignalDescribe(int type) { static const char* SignalDescribe(int type) {
switch (type) { switch (type) {
case SIGSEGV: return "SIGSEGV"; case SIGSEGV: return "SIGSEGV";
@ -268,8 +270,10 @@ static void SignalHandler(int sig, siginfo_t* info, void* ctx) {
desc = SignalDescribe(type); desc = SignalDescribe(type);
String_InitArray_NT(msg, msgBuffer); String_InitArray_NT(msg, msgBuffer);
if (desc) { if (IsNullDerefException(info)) {
String_Format3(&msg, "Unhandled signal %c (code %i) at %x", desc, &code, &addr); 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 { } else {
String_Format3(&msg, "Unhandled signal %i (code %i) at %x", &type, &code, &addr); 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----------------------------------------------------* *-------------------------------------------------------Crash handling----------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
static const char* ExceptionDescribe(cc_uint32 code) { /* In EXCEPTION_ACCESS_VIOLATION case, arg 1 is access type and arg 2 is virtual address */
switch (code) { /* 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_ACCESS_VIOLATION: return "ACCESS_VIOLATION";
case EXCEPTION_ILLEGAL_INSTRUCTION: return "ILLEGAL_INSTRUCTION"; case EXCEPTION_ILLEGAL_INSTRUCTION: return "ILLEGAL_INSTRUCTION";
case EXCEPTION_INT_DIVIDE_BY_ZERO: return "DIVIDE_BY_ZERO"; 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) { static LONG WINAPI UnhandledFilter(struct _EXCEPTION_POINTERS* info) {
cc_string msg; char msgBuffer[128 + 1]; cc_string msg; char msgBuffer[128 + 1];
struct _EXCEPTION_RECORD* rec;
const char* desc; const char* desc;
cc_uint32 code; cc_uint32 code;
cc_uintptr addr; cc_uintptr addr;
DWORD i, numArgs; DWORD i, numArgs;
code = (cc_uint32)info->ExceptionRecord->ExceptionCode; rec = info->ExceptionRecord;
addr = (cc_uintptr)info->ExceptionRecord->ExceptionAddress; code = (cc_uint32)rec->ExceptionCode;
desc = ExceptionDescribe(code); addr = (cc_uintptr)rec->ExceptionAddress;
desc = ExceptionDescribe(rec);
String_InitArray_NT(msg, msgBuffer); String_InitArray_NT(msg, msgBuffer);
if (desc) { 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); String_Format2(&msg, "Unhandled exception 0x%h at %x", &code, &addr);
} }
numArgs = info->ExceptionRecord->NumberParameters; numArgs = rec->NumberParameters;
if (numArgs) { if (IsNullReadException(rec) || IsNullWriteException(rec)) {
/* Pointless to log exception arguments in this case */
} else if (numArgs) {
numArgs = min(numArgs, EXCEPTION_MAXIMUM_PARAMETERS); numArgs = min(numArgs, EXCEPTION_MAXIMUM_PARAMETERS);
String_AppendConst(&msg, " ["); String_AppendConst(&msg, " [");
for (i = 0; i < numArgs; i++) { 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, ']'); String_Append(&msg, ']');
} }