pr_xstatement now always reflects the currently executing statement making

debugging easier in the event of a segfault
This commit is contained in:
Bill Currie 2002-10-22 15:07:54 +00:00
parent 567b905590
commit 80e85226b9
3 changed files with 51 additions and 44 deletions

View file

@ -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);

View file

@ -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);
} }
} }

View file

@ -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);
} }
} }