mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-17 22:50:51 +00:00
pr_xstatement now always reflects the currently executing statement making
debugging easier in the event of a segfault
This commit is contained in:
parent
567b905590
commit
80e85226b9
3 changed files with 51 additions and 44 deletions
|
@ -65,7 +65,7 @@ void PR_Init (void);
|
||||||
void PR_Init_Cvars (void);
|
void PR_Init_Cvars (void);
|
||||||
|
|
||||||
void PR_PrintStatement (progs_t * pr, dstatement_t *s);
|
void PR_PrintStatement (progs_t * pr, dstatement_t *s);
|
||||||
int PR_EnterFunction (progs_t * pr, dfunction_t *f);
|
void PR_EnterFunction (progs_t * pr, dfunction_t *f);
|
||||||
void PR_ExecuteProgram (progs_t *pr, func_t fnum);
|
void PR_ExecuteProgram (progs_t *pr, func_t fnum);
|
||||||
void PR_LoadProgsFile (progs_t * pr, QFile *file, int size, int edicts,
|
void PR_LoadProgsFile (progs_t * pr, QFile *file, int size, int edicts,
|
||||||
int zone);
|
int zone);
|
||||||
|
|
|
@ -136,6 +136,7 @@ PR_StackTrace (progs_t * pr)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pr->pr_stack[pr->pr_depth].s = pr->pr_xstatement;
|
||||||
pr->pr_stack[pr->pr_depth].f = pr->pr_xfunction;
|
pr->pr_stack[pr->pr_depth].f = pr->pr_xfunction;
|
||||||
for (i = pr->pr_depth; i >= 0; i--) {
|
for (i = pr->pr_depth; i >= 0; i--) {
|
||||||
f = pr->pr_stack[i].f;
|
f = pr->pr_stack[i].f;
|
||||||
|
@ -143,8 +144,8 @@ PR_StackTrace (progs_t * pr)
|
||||||
if (!f) {
|
if (!f) {
|
||||||
Sys_Printf ("<NO FUNCTION>\n");
|
Sys_Printf ("<NO FUNCTION>\n");
|
||||||
} else
|
} else
|
||||||
Sys_Printf ("%12s : %s\n", PR_GetString (pr, f->s_file),
|
Sys_Printf ("%12s : %s: %x\n", PR_GetString (pr, f->s_file),
|
||||||
PR_GetString (pr, f->s_name));
|
PR_GetString (pr, f->s_name), pr->pr_stack[i].s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +206,7 @@ PR_RunError (progs_t * pr, const char *error, ...)
|
||||||
|
|
||||||
Returns the new program statement counter
|
Returns the new program statement counter
|
||||||
*/
|
*/
|
||||||
int
|
void
|
||||||
PR_EnterFunction (progs_t * pr, dfunction_t *f)
|
PR_EnterFunction (progs_t * pr, dfunction_t *f)
|
||||||
{
|
{
|
||||||
int i, j, c, o;
|
int i, j, c, o;
|
||||||
|
@ -215,7 +216,7 @@ PR_EnterFunction (progs_t * pr, dfunction_t *f)
|
||||||
pr->pr_stack[pr->pr_depth].s = pr->pr_xstatement;
|
pr->pr_stack[pr->pr_depth].s = pr->pr_xstatement;
|
||||||
pr->pr_stack[pr->pr_depth].f = pr->pr_xfunction;
|
pr->pr_stack[pr->pr_depth].f = pr->pr_xfunction;
|
||||||
pr->pr_depth++;
|
pr->pr_depth++;
|
||||||
if (pr->pr_depth >= MAX_STACK_DEPTH)
|
if (pr->pr_depth >= MAX_STACK_DEPTH - 1)
|
||||||
PR_RunError (pr, "stack overflow");
|
PR_RunError (pr, "stack overflow");
|
||||||
|
|
||||||
// save off any locals that the new function steps on
|
// save off any locals that the new function steps on
|
||||||
|
@ -266,10 +267,11 @@ PR_EnterFunction (progs_t * pr, dfunction_t *f)
|
||||||
}
|
}
|
||||||
|
|
||||||
pr->pr_xfunction = f;
|
pr->pr_xfunction = f;
|
||||||
return f->first_statement - 1; // offset the s++
|
pr->pr_xstatement = f->first_statement - 1; // offset the s++
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
PR_LeaveFunction (progs_t * pr)
|
PR_LeaveFunction (progs_t * pr)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
@ -290,7 +292,7 @@ PR_LeaveFunction (progs_t * pr)
|
||||||
// up stack
|
// up stack
|
||||||
pr->pr_depth--;
|
pr->pr_depth--;
|
||||||
pr->pr_xfunction = pr->pr_stack[pr->pr_depth].f;
|
pr->pr_xfunction = pr->pr_stack[pr->pr_depth].f;
|
||||||
return pr->pr_stack[pr->pr_depth].s;
|
pr->pr_xstatement = pr->pr_stack[pr->pr_depth].s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -340,7 +342,8 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
||||||
// make a stack frame
|
// make a stack frame
|
||||||
exitdepth = pr->pr_depth;
|
exitdepth = pr->pr_depth;
|
||||||
|
|
||||||
st = &pr->pr_statements[PR_EnterFunction (pr, f)];
|
PR_EnterFunction (pr, f);
|
||||||
|
st = pr->pr_statements + pr->pr_xstatement;
|
||||||
startprofile = profile = 0;
|
startprofile = profile = 0;
|
||||||
|
|
||||||
Sys_PushSignalHook (signal_hook, pr);
|
Sys_PushSignalHook (signal_hook, pr);
|
||||||
|
@ -349,8 +352,10 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
||||||
pr_type_t *op_a, *op_b, *op_c;
|
pr_type_t *op_a, *op_b, *op_c;
|
||||||
|
|
||||||
st++;
|
st++;
|
||||||
|
++pr->pr_xstatement;
|
||||||
|
if (pr->pr_xstatement != st - pr->pr_statements)
|
||||||
|
PR_RunError (pr, "internal error");
|
||||||
if (++profile > 1000000 && !pr->no_exec_limit) {
|
if (++profile > 1000000 && !pr->no_exec_limit) {
|
||||||
pr->pr_xstatement = st - pr->pr_statements;
|
|
||||||
PR_RunError (pr, "runaway loop error");
|
PR_RunError (pr, "runaway loop error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,19 +547,16 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
||||||
if (pr_boundscheck->int_val
|
if (pr_boundscheck->int_val
|
||||||
&& (OPA.entity_var < 0 || OPA.entity_var >=
|
&& (OPA.entity_var < 0 || OPA.entity_var >=
|
||||||
pr->pr_edictareasize)) {
|
pr->pr_edictareasize)) {
|
||||||
pr->pr_xstatement = st - pr->pr_statements;
|
|
||||||
PR_RunError (pr, "Progs attempted to address an out of "
|
PR_RunError (pr, "Progs attempted to address an out of "
|
||||||
"bounds edict");
|
"bounds edict");
|
||||||
}
|
}
|
||||||
if (pr_boundscheck->int_val
|
if (pr_boundscheck->int_val
|
||||||
&& (OPA.entity_var == 0 && pr->null_bad)) {
|
&& (OPA.entity_var == 0 && pr->null_bad)) {
|
||||||
pr->pr_xstatement = st - pr->pr_statements;
|
|
||||||
PR_RunError (pr, "assignment to world entity");
|
PR_RunError (pr, "assignment to world entity");
|
||||||
}
|
}
|
||||||
if (pr_boundscheck->int_val
|
if (pr_boundscheck->int_val
|
||||||
&& (OPB.integer_var < 0 || OPB.integer_var >=
|
&& (OPB.integer_var < 0 || OPB.integer_var >=
|
||||||
pr->progs->entityfields)) {
|
pr->progs->entityfields)) {
|
||||||
pr->pr_xstatement = st - pr->pr_statements;
|
|
||||||
PR_RunError (pr, "Progs attempted to address an invalid "
|
PR_RunError (pr, "Progs attempted to address an invalid "
|
||||||
"field in an edict");
|
"field in an edict");
|
||||||
}
|
}
|
||||||
|
@ -582,14 +584,12 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
||||||
if (pr_boundscheck->int_val
|
if (pr_boundscheck->int_val
|
||||||
&& (OPA.entity_var < 0 || OPA.entity_var >=
|
&& (OPA.entity_var < 0 || OPA.entity_var >=
|
||||||
pr->pr_edictareasize)) {
|
pr->pr_edictareasize)) {
|
||||||
pr->pr_xstatement = st - pr->pr_statements;
|
|
||||||
PR_RunError (pr, "Progs attempted to read an out of "
|
PR_RunError (pr, "Progs attempted to read an out of "
|
||||||
"bounds edict number");
|
"bounds edict number");
|
||||||
}
|
}
|
||||||
if (pr_boundscheck->int_val
|
if (pr_boundscheck->int_val
|
||||||
&& (OPB.integer_var < 0 || OPB.integer_var >=
|
&& (OPB.integer_var < 0 || OPB.integer_var >=
|
||||||
pr->progs->entityfields)) {
|
pr->progs->entityfields)) {
|
||||||
pr->pr_xstatement = st - pr->pr_statements;
|
|
||||||
PR_RunError (pr, "Progs attempted to read an invalid "
|
PR_RunError (pr, "Progs attempted to read an invalid "
|
||||||
"field in an edict");
|
"field in an edict");
|
||||||
}
|
}
|
||||||
|
@ -600,14 +600,12 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
||||||
if (pr_boundscheck->int_val
|
if (pr_boundscheck->int_val
|
||||||
&& (OPA.entity_var < 0 || OPA.entity_var >=
|
&& (OPA.entity_var < 0 || OPA.entity_var >=
|
||||||
pr->pr_edictareasize)) {
|
pr->pr_edictareasize)) {
|
||||||
pr->pr_xstatement = st - pr->pr_statements;
|
|
||||||
PR_RunError (pr, "Progs attempted to read an out of "
|
PR_RunError (pr, "Progs attempted to read an out of "
|
||||||
"bounds edict number");
|
"bounds edict number");
|
||||||
}
|
}
|
||||||
if (pr_boundscheck->int_val
|
if (pr_boundscheck->int_val
|
||||||
&& (OPB.integer_var < 0
|
&& (OPB.integer_var < 0
|
||||||
|| OPB.integer_var + 2 >= pr->progs->entityfields)) {
|
|| OPB.integer_var + 2 >= pr->progs->entityfields)) {
|
||||||
pr->pr_xstatement = st - pr->pr_statements;
|
|
||||||
PR_RunError (pr, "Progs attempted to read an invalid "
|
PR_RunError (pr, "Progs attempted to read an invalid "
|
||||||
"field in an edict");
|
"field in an edict");
|
||||||
}
|
}
|
||||||
|
@ -703,39 +701,52 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
||||||
|
|
||||||
// ==================
|
// ==================
|
||||||
case OP_IFNOT:
|
case OP_IFNOT:
|
||||||
if (!OPA.integer_var)
|
if (!OPA.integer_var) {
|
||||||
st += (short)st->b - 1; // offset the s++
|
pr->pr_xstatement += (short)st->b - 1; // offset the s++
|
||||||
|
st = pr->pr_statements + pr->pr_xstatement;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OP_IF:
|
case OP_IF:
|
||||||
if (OPA.integer_var)
|
if (OPA.integer_var) {
|
||||||
st += (short)st->b - 1; // offset the s++
|
pr->pr_xstatement += (short)st->b - 1; // offset the s++
|
||||||
|
st = pr->pr_statements + pr->pr_xstatement;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OP_IFBE:
|
case OP_IFBE:
|
||||||
if (OPA.integer_var <= 0)
|
if (OPA.integer_var <= 0) {
|
||||||
st += (short)st->b - 1; // offset the s++
|
pr->pr_xstatement += (short)st->b - 1; // offset the s++
|
||||||
|
st = pr->pr_statements + pr->pr_xstatement;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OP_IFB:
|
case OP_IFB:
|
||||||
if (OPA.integer_var < 0)
|
if (OPA.integer_var < 0) {
|
||||||
st += (short)st->b - 1; // offset the s++
|
pr->pr_xstatement += (short)st->b - 1; // offset the s++
|
||||||
|
st = pr->pr_statements + pr->pr_xstatement;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OP_IFAE:
|
case OP_IFAE:
|
||||||
if (OPA.integer_var >= 0)
|
if (OPA.integer_var >= 0) {
|
||||||
st += (short)st->b - 1; // offset the s++
|
pr->pr_xstatement += (short)st->b - 1; // offset the s++
|
||||||
|
st = pr->pr_statements + pr->pr_xstatement;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OP_IFA:
|
case OP_IFA:
|
||||||
if (OPA.integer_var > 0)
|
if (OPA.integer_var > 0) {
|
||||||
st += (short)st->b - 1; // offset the s++
|
pr->pr_xstatement += (short)st->b - 1; // offset the s++
|
||||||
|
st = pr->pr_statements + pr->pr_xstatement;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OP_GOTO:
|
case OP_GOTO:
|
||||||
st += (short)st->a - 1; // offset the s++
|
pr->pr_xstatement += (short)st->a - 1; // offset the s++
|
||||||
|
st = pr->pr_statements + pr->pr_xstatement;
|
||||||
break;
|
break;
|
||||||
case OP_JUMP:
|
case OP_JUMP:
|
||||||
if (pr_boundscheck->int_val
|
if (pr_boundscheck->int_val
|
||||||
&& (OPA.uinteger_var >= pr->progs->numstatements)) {
|
&& (OPA.uinteger_var >= pr->progs->numstatements)) {
|
||||||
pr->pr_xstatement = st - pr->pr_statements;
|
|
||||||
PR_RunError (pr, "Invalid jump destination");
|
PR_RunError (pr, "Invalid jump destination");
|
||||||
}
|
}
|
||||||
st = &pr->pr_statements[OPA.uinteger_var];
|
pr->pr_xstatement = OPA.uinteger_var;
|
||||||
|
st = pr->pr_statements + pr->pr_xstatement;
|
||||||
break;
|
break;
|
||||||
case OP_JUMPB:
|
case OP_JUMPB:
|
||||||
//FIXME put bounds checking in
|
//FIXME put bounds checking in
|
||||||
|
@ -744,10 +755,10 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
||||||
pointer = ptr->integer_var;
|
pointer = ptr->integer_var;
|
||||||
if (pr_boundscheck->int_val
|
if (pr_boundscheck->int_val
|
||||||
&& (pointer >= pr->progs->numstatements)) {
|
&& (pointer >= pr->progs->numstatements)) {
|
||||||
pr->pr_xstatement = st - pr->pr_statements;
|
|
||||||
PR_RunError (pr, "Invalid jump destination");
|
PR_RunError (pr, "Invalid jump destination");
|
||||||
}
|
}
|
||||||
st = &pr->pr_statements[pointer];
|
pr->pr_xstatement = pointer;
|
||||||
|
st = pr->pr_statements + pr->pr_xstatement;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_CALL0:
|
case OP_CALL0:
|
||||||
|
@ -761,7 +772,6 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
||||||
case OP_CALL8:
|
case OP_CALL8:
|
||||||
pr->pr_xfunction->profile += profile - startprofile;
|
pr->pr_xfunction->profile += profile - startprofile;
|
||||||
startprofile = profile;
|
startprofile = profile;
|
||||||
pr->pr_xstatement = st - pr->pr_statements;
|
|
||||||
pr->pr_argc = st->op - OP_CALL0;
|
pr->pr_argc = st->op - OP_CALL0;
|
||||||
if (!OPA.func_var)
|
if (!OPA.func_var)
|
||||||
PR_RunError (pr, "NULL function");
|
PR_RunError (pr, "NULL function");
|
||||||
|
@ -774,18 +784,17 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
||||||
|| !pr->builtins[i]->proc)
|
|| !pr->builtins[i]->proc)
|
||||||
PR_RunError (pr, "Bad builtin call number");
|
PR_RunError (pr, "Bad builtin call number");
|
||||||
pr->builtins[i]->proc (pr);
|
pr->builtins[i]->proc (pr);
|
||||||
st = pr->pr_statements + pr->pr_xstatement;
|
} else {
|
||||||
break;
|
PR_EnterFunction (pr, newf);
|
||||||
}
|
}
|
||||||
|
st = pr->pr_statements + pr->pr_xstatement;
|
||||||
st = &pr->pr_statements[PR_EnterFunction (pr, newf)];
|
|
||||||
break;
|
break;
|
||||||
case OP_DONE:
|
case OP_DONE:
|
||||||
case OP_RETURN:
|
case OP_RETURN:
|
||||||
memcpy (&pr->pr_globals[OFS_RETURN], &OPA, 3 * sizeof (OPA));
|
memcpy (&pr->pr_globals[OFS_RETURN], &OPA, 3 * sizeof (OPA));
|
||||||
st = &pr->pr_statements[PR_LeaveFunction (pr)];
|
PR_LeaveFunction (pr);
|
||||||
|
st = pr->pr_statements + pr->pr_xstatement;
|
||||||
if (pr->pr_depth == exitdepth) {
|
if (pr->pr_depth == exitdepth) {
|
||||||
pr->pr_xstatement = st - pr->pr_statements;
|
|
||||||
Sys_PopSignalHook ();
|
Sys_PopSignalHook ();
|
||||||
return; // all done
|
return; // all done
|
||||||
}
|
}
|
||||||
|
@ -903,7 +912,6 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
||||||
/*
|
/*
|
||||||
case OP_BOUNDCHECK:
|
case OP_BOUNDCHECK:
|
||||||
if (OPA.integer_var < 0 || OPA.integer_var >= st->b) {
|
if (OPA.integer_var < 0 || OPA.integer_var >= st->b) {
|
||||||
pr->pr_xstatement = st - pr->pr_statements;
|
|
||||||
PR_RunError (pr, "Progs boundcheck failed at line number "
|
PR_RunError (pr, "Progs boundcheck failed at line number "
|
||||||
"%d, value is < 0 or >= %d", st->b, st->c);
|
"%d, value is < 0 or >= %d", st->b, st->c);
|
||||||
}
|
}
|
||||||
|
@ -911,7 +919,6 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
default:
|
default:
|
||||||
pr->pr_xstatement = st - pr->pr_statements;
|
|
||||||
PR_RunError (pr, "Bad opcode %i", st->op);
|
PR_RunError (pr, "Bad opcode %i", st->op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ call_function (progs_t *pr, func_t func)
|
||||||
PR_RunError (pr, "Bad builtin call number");
|
PR_RunError (pr, "Bad builtin call number");
|
||||||
pr->builtins[i]->proc (pr);
|
pr->builtins[i]->proc (pr);
|
||||||
} else {
|
} else {
|
||||||
pr->pr_xstatement = PR_EnterFunction (pr, newf);
|
PR_EnterFunction (pr, newf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue