diff --git a/include/QF/progs.h b/include/QF/progs.h index 779b6a7d8..670945923 100644 --- a/include/QF/progs.h +++ b/include/QF/progs.h @@ -187,6 +187,8 @@ pr_lineno_t *PR_Find_Lineno (progs_t *pr, unsigned long addr); const char *PR_Get_Source_File (progs_t *pr, pr_lineno_t *lineno); const char *PR_Get_Source_Line (progs_t *pr, unsigned long addr); ddef_t *PR_Get_Local_Def (progs_t *pr, int offs); +void PR_DumpState (progs_t *pr); +void PR_StackTrace (progs_t * pr); extern struct cvar_s *pr_debug; diff --git a/libs/gamecode/engine/pr_debug.c b/libs/gamecode/engine/pr_debug.c index 1a3ace4cc..231fedb62 100644 --- a/libs/gamecode/engine/pr_debug.c +++ b/libs/gamecode/engine/pr_debug.c @@ -68,6 +68,37 @@ cvar_t *pr_source_path; static hashtab_t *file_hash; +static const char * +file_get_key (void *_f, void *unused) +{ + return ((file_t*)_f)->name; +} + +static void +file_free (void *_f, void *unused) +{ + file_t *f = (file_t*)_f; + free (f->lines); + free (f->text); + free (f->name); + free (f); +} + +void +PR_Debug_Init (void) +{ + file_hash = Hash_NewTable (1024, file_get_key, file_free, 0); +} + +void +PR_Debug_Init_Cvars (void) +{ + pr_debug = Cvar_Get ("pr_debug", "0", CVAR_NONE, NULL, + "enable progs debugging"); + pr_source_path = Cvar_Get ("pr_source_path", ".", CVAR_NONE, NULL, "where " + "to look (within gamedir) for source files"); +} + file_t * PR_Load_Source_File (progs_t *pr, const char *fname) { @@ -333,33 +364,17 @@ PR_Get_Local_Def (progs_t *pr, int offs) return 0; } -static const char * -file_get_key (void *_f, void *unused) -{ - return ((file_t*)_f)->name; -} - -static void -file_free (void *_f, void *unused) -{ - file_t *f = (file_t*)_f; - free (f->lines); - free (f->text); - free (f->name); - free (f); -} - void -PR_Debug_Init (void) +PR_DumpState (progs_t *pr) { - file_hash = Hash_NewTable (1024, file_get_key, file_free, 0); -} + if (pr_debug->int_val && pr->debug) { + int addr = pr->pr_xstatement; -void -PR_Debug_Init_Cvars (void) -{ - pr_debug = Cvar_Get ("pr_debug", "0", CVAR_NONE, NULL, - "enable progs debugging"); - pr_source_path = Cvar_Get ("pr_source_path", ".", CVAR_NONE, NULL, "where " - "to look (within gamedir) for source files"); + while (!PR_Get_Source_Line (pr, addr)) + addr--; + while (addr != pr->pr_xstatement) + PR_PrintStatement (pr, pr->pr_statements + addr++); + } + PR_PrintStatement (pr, pr->pr_statements + pr->pr_xstatement); + PR_StackTrace (pr); } diff --git a/libs/gamecode/engine/pr_edict.c b/libs/gamecode/engine/pr_edict.c index e78b0e54a..7f48448b2 100644 --- a/libs/gamecode/engine/pr_edict.c +++ b/libs/gamecode/engine/pr_edict.c @@ -1461,6 +1461,7 @@ EDICT_NUM (progs_t * pr, int n) int offs = n * pr->pr_edict_size; if (offs < 0 || n >= pr->pr_edictareasize) PR_RunError (pr, "EDICT_NUM: bad number %i", n); + return PROG_TO_EDICT (pr, offs); } diff --git a/libs/gamecode/engine/pr_exec.c b/libs/gamecode/engine/pr_exec.c index dbe0bbb0a..e1a92ea47 100644 --- a/libs/gamecode/engine/pr_exec.c +++ b/libs/gamecode/engine/pr_exec.c @@ -157,20 +157,12 @@ PR_RunError (progs_t * pr, const char *error, ...) vsnprintf (string, sizeof (string), error, argptr); va_end (argptr); - if (pr_debug->int_val && pr->debug) { - int addr = pr->pr_xstatement; - - while (!PR_Get_Source_Line (pr, addr)) - addr--; - while (addr != pr->pr_xstatement) - PR_PrintStatement (pr, pr->pr_statements + addr++); - } - PR_PrintStatement (pr, pr->pr_statements + pr->pr_xstatement); - PR_StackTrace (pr); + PR_DumpState (pr); + Sys_Printf ("%s\n", string); - pr->pr_depth = 0; // dump the stack so PR_Error can - // shutdown functions + // dump the stack so PR_Error can shutdown functions + pr->pr_depth = 0; PR_Error (pr, "Program error"); } diff --git a/qw/source/sv_progs.c b/qw/source/sv_progs.c index 765b2b8bc..7e2069c1b 100644 --- a/qw/source/sv_progs.c +++ b/qw/source/sv_progs.c @@ -166,7 +166,7 @@ static void seg_fault_handler(int whatever) { if (sv_pr_state.pr_xfunction) - PR_RunError (&sv_pr_state, "Segmentation Fault\n"); + PR_DumpState (&sv_pr_state); signal (SIGSEGV, old_seg_handler); }