mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 23:11:38 +00:00
Allow Sys_Error to be hooked.
This makes debugging builtins that wrap normal functions a little easier by giving a progs dump when such an error occurs.
This commit is contained in:
parent
735fcf68d5
commit
546e333a3c
3 changed files with 59 additions and 4 deletions
|
@ -63,13 +63,18 @@ int Sys_isdir (const char *path);
|
||||||
int Sys_mkdir (const char *path);
|
int Sys_mkdir (const char *path);
|
||||||
|
|
||||||
typedef void (*sys_printf_t) (const char *fmt, va_list args);
|
typedef void (*sys_printf_t) (const char *fmt, va_list args);
|
||||||
|
typedef void (*sys_error_t) (void *data);
|
||||||
|
|
||||||
void Sys_SetStdPrintf (sys_printf_t func);
|
void Sys_SetStdPrintf (sys_printf_t func);
|
||||||
void Sys_SetErrPrintf (sys_printf_t func);
|
void Sys_SetErrPrintf (sys_printf_t func);
|
||||||
|
|
||||||
|
void Sys_PushErrorHandler (sys_error_t func, void *data);
|
||||||
|
void Sys_PopErrorHandler (void);
|
||||||
|
|
||||||
void Sys_Print (FILE *stream, const char *fmt, va_list args);
|
void Sys_Print (FILE *stream, const char *fmt, va_list args);
|
||||||
void Sys_Printf (const char *fmt, ...) __attribute__((format(printf,1,2)));
|
void Sys_Printf (const char *fmt, ...) __attribute__((format(printf,1,2)));
|
||||||
void Sys_Error (const char *error, ...) __attribute__((format(printf,1,2), noreturn));
|
void Sys_Error (const char *error, ...) __attribute__((format(printf,1,2), noreturn));
|
||||||
|
void Sys_FatalError (const char *error, ...) __attribute__((format(printf,1,2), noreturn));
|
||||||
void Sys_Quit (void) __attribute__((noreturn));
|
void Sys_Quit (void) __attribute__((noreturn));
|
||||||
void Sys_Shutdown (void);
|
void Sys_Shutdown (void);
|
||||||
void Sys_RegisterShutdown (void (*func) (void));
|
void Sys_RegisterShutdown (void (*func) (void));
|
||||||
|
|
|
@ -328,6 +328,14 @@ signal_hook (int sig, void *data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
error_handler (void *data)
|
||||||
|
{
|
||||||
|
progs_t *pr = (progs_t *) data;
|
||||||
|
PR_DumpState (pr);
|
||||||
|
fflush (stdout);
|
||||||
|
}
|
||||||
|
|
||||||
VISIBLE int
|
VISIBLE int
|
||||||
PR_CallFunction (progs_t *pr, func_t fnum)
|
PR_CallFunction (progs_t *pr, func_t fnum)
|
||||||
{
|
{
|
||||||
|
@ -370,11 +378,11 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
||||||
startprofile = profile = 0;
|
startprofile = profile = 0;
|
||||||
|
|
||||||
Sys_PushSignalHook (signal_hook, pr);
|
Sys_PushSignalHook (signal_hook, pr);
|
||||||
|
Sys_PushErrorHandler (error_handler, pr);
|
||||||
|
|
||||||
if (!PR_CallFunction (pr, fnum)) {
|
if (!PR_CallFunction (pr, fnum)) {
|
||||||
// called a builtin instead of progs code
|
// called a builtin instead of progs code
|
||||||
Sys_PopSignalHook ();
|
goto exit_program;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
st = pr->pr_statements + pr->pr_xstatement;
|
st = pr->pr_statements + pr->pr_xstatement;
|
||||||
|
|
||||||
|
@ -964,8 +972,8 @@ op_call:
|
||||||
if (pr->pr_depth == exitdepth) {
|
if (pr->pr_depth == exitdepth) {
|
||||||
if (pr->pr_trace && pr->pr_depth <= pr->pr_trace_depth)
|
if (pr->pr_trace && pr->pr_depth <= pr->pr_trace_depth)
|
||||||
pr->pr_trace = false;
|
pr->pr_trace = false;
|
||||||
Sys_PopSignalHook ();
|
// all done
|
||||||
return; // all done
|
goto exit_program;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OP_STATE:
|
case OP_STATE:
|
||||||
|
@ -1116,4 +1124,7 @@ op_call:
|
||||||
PR_RunError (pr, "watchpoint hit: %d -> %d", old_val.integer_var,
|
PR_RunError (pr, "watchpoint hit: %d -> %d", old_val.integer_var,
|
||||||
watch->integer_var);
|
watch->integer_var);
|
||||||
}
|
}
|
||||||
|
exit_program:
|
||||||
|
Sys_PopErrorHandler ();
|
||||||
|
Sys_PopSignalHook ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,7 @@
|
||||||
|
|
||||||
#include "qfalloca.h"
|
#include "qfalloca.h"
|
||||||
|
|
||||||
|
#include "QF/alloc.h"
|
||||||
#include "QF/cmd.h"
|
#include "QF/cmd.h"
|
||||||
#include "QF/cvar.h"
|
#include "QF/cvar.h"
|
||||||
#include "QF/dstring.h"
|
#include "QF/dstring.h"
|
||||||
|
@ -107,8 +108,17 @@ typedef struct shutdown_list_s {
|
||||||
void (*func)(void);
|
void (*func)(void);
|
||||||
} shutdown_list_t;
|
} shutdown_list_t;
|
||||||
|
|
||||||
|
typedef struct error_handler_s {
|
||||||
|
struct error_handler_s *next;
|
||||||
|
sys_error_t func;
|
||||||
|
void *data;
|
||||||
|
} error_handler_t;
|
||||||
|
|
||||||
static shutdown_list_t *shutdown_list;
|
static shutdown_list_t *shutdown_list;
|
||||||
|
|
||||||
|
static error_handler_t *error_handler_freelist;
|
||||||
|
static error_handler_t *error_handler;
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
static int do_stdin = 1;
|
static int do_stdin = 1;
|
||||||
qboolean stdin_ready;
|
qboolean stdin_ready;
|
||||||
|
@ -493,6 +503,31 @@ Sys_Quit (void)
|
||||||
exit (0);
|
exit (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VISIBLE void
|
||||||
|
Sys_PushErrorHandler (sys_error_t func, void *data)
|
||||||
|
{
|
||||||
|
error_handler_t *eh;
|
||||||
|
ALLOC (16, error_handler_t, error_handler, eh);
|
||||||
|
eh->func = func;
|
||||||
|
eh->data = data;
|
||||||
|
eh->next = error_handler;
|
||||||
|
error_handler = eh;
|
||||||
|
}
|
||||||
|
|
||||||
|
VISIBLE void
|
||||||
|
Sys_PopErrorHandler (void)
|
||||||
|
{
|
||||||
|
error_handler_t *eh;
|
||||||
|
|
||||||
|
if (!error_handler) {
|
||||||
|
Sys_Error ("Sys_PopErrorHandler: no handler to pop");
|
||||||
|
}
|
||||||
|
eh = error_handler;
|
||||||
|
error_handler = eh->next;
|
||||||
|
FREE (error_handler, eh);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
VISIBLE void
|
VISIBLE void
|
||||||
Sys_Error (const char *error, ...)
|
Sys_Error (const char *error, ...)
|
||||||
{
|
{
|
||||||
|
@ -515,6 +550,10 @@ Sys_Error (const char *error, ...)
|
||||||
sys_err_printf_function (error, args);
|
sys_err_printf_function (error, args);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
|
|
||||||
|
if (error_handler) {
|
||||||
|
error_handler->func (error_handler->data);
|
||||||
|
}
|
||||||
|
|
||||||
Sys_Shutdown ();
|
Sys_Shutdown ();
|
||||||
|
|
||||||
if (sys_err_printf_function != Sys_ErrPrintf) {
|
if (sys_err_printf_function != Sys_ErrPrintf) {
|
||||||
|
|
Loading…
Reference in a new issue