Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9c8d70d

Browse files
committed
New trace implementation; and profile (in a similat vein).
1 parent cb9d66d commit 9c8d70d

1 file changed

Lines changed: 109 additions & 84 deletions

File tree

Python/ceval.c

Lines changed: 109 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,9 @@ static int testbool();
7171
static int assign_subscript PROTO((object *, object *, object *));
7272
static int assign_slice PROTO((object *, object *, object *, object *));
7373
static int import_from PROTO((object *, object *, object *));
74-
static object *call_trace PROTO((object *, frameobject *, char *, object *));
74+
static void call_exc_trace PROTO((object **, object**, frameobject *));
75+
static int call_trace
76+
PROTO((object **, object **, frameobject *, char *, object *));
7577

7678

7779
static frameobject *current_frame;
@@ -109,7 +111,7 @@ eval_code(co, globals, locals, arg)
109111
register object *u;
110112
register object *t;
111113
register frameobject *f; /* Current frame */
112-
object *trace; /* Trace function or NULL */
114+
object *trace = NULL; /* Trace function or NULL */
113115
object *retval; /* Return value iff why == WHY_RETURN */
114116
char *name; /* Name used by some instructions */
115117
FILE *fp; /* Used by print operations */
@@ -157,13 +159,8 @@ eval_code(co, globals, locals, arg)
157159

158160
current_frame = f;
159161

160-
trace = sysget("trace");
161-
if (trace != NULL) {
162-
if (trace == None) {
163-
trace = NULL;
164-
}
165-
else {
166-
/* sys.trace, if defined, is a function that will
162+
if (sys_trace != NULL) {
163+
/* sys_trace, if defined, is a function that will
167164
be called on *every* entry to a code block.
168165
Its return value, if not None, is a function that
169166
will be called at the start of each executed line
@@ -175,20 +172,22 @@ eval_code(co, globals, locals, arg)
175172
depends on the situation. The global trace function
176173
(sys.trace) is also called whenever an exception
177174
is detected. */
178-
trace = call_trace(trace, f, "call", arg);
179-
if (trace == NULL) {
175+
if (call_trace(&sys_trace, &trace, f, "call", arg)) {
180176
/* Trace function raised an error */
181-
sysset("trace", (object *)NULL);
182177
current_frame = f->f_back;
183178
DECREF(f);
184179
return NULL;
185180
}
186-
if (trace == None) {
187-
/* No need to trace this code block */
188-
DECREF(trace);
189-
trace = NULL;
181+
}
182+
183+
if (sys_profile != NULL) {
184+
/* Similar for sys_profile, except it needn't return
185+
itself and isn't called for "line" events */
186+
if (call_trace(&sys_profile, (object**)0, f, "call", arg)) {
187+
current_frame = f->f_back;
188+
DECREF(f);
189+
return NULL;
190190
}
191-
}
192191
}
193192

194193
next_instr = GETUSTRINGVALUE(f->f_code->co_code);
@@ -1005,16 +1004,8 @@ eval_code(co, globals, locals, arg)
10051004
if (trace != NULL) {
10061005
/* Trace each line of code reached */
10071006
f->f_lasti = INSTR_OFFSET();
1008-
x = call_trace(trace, f, "line", None);
1009-
/* The trace function must return itself
1010-
in order to continue tracing */
1011-
DECREF(trace);
1012-
if (x == None) {
1013-
DECREF(x);
1014-
trace = NULL;
1015-
}
1016-
else
1017-
trace = x;
1007+
err = call_trace(&trace, &trace,
1008+
f, "line", None);
10181009
}
10191010
break;
10201011

@@ -1066,40 +1057,10 @@ eval_code(co, globals, locals, arg)
10661057
f->f_lasti -= 2;
10671058
tb_here(f);
10681059

1069-
if (trace) {
1070-
object *type, *value, *traceback, *arg;
1071-
err_get(&type, &value);
1072-
traceback = tb_fetch();
1073-
arg = newtupleobject(3);
1074-
if (arg == NULL)
1075-
err_clear();
1076-
else {
1077-
settupleitem(arg, 0, type);
1078-
settupleitem(arg, 1, value);
1079-
settupleitem(arg, 2, traceback);
1080-
}
1081-
v = call_trace(trace, f, "exception", arg);
1082-
if (v == NULL) {
1083-
/* Trace function raised error */
1084-
tb_here(f);
1085-
sysset("trace", (object *)NULL);
1086-
XDECREF(trace);
1087-
trace = NULL;
1088-
}
1089-
else {
1090-
/* Restore original exception */
1091-
err_setval(type, value);
1092-
tb_store(traceback);
1093-
if (v == None)
1094-
DECREF(v);
1095-
else {
1096-
/* Set trace function */
1097-
XDECREF(trace);
1098-
trace = v;
1099-
}
1100-
}
1101-
XDECREF(arg);
1102-
}
1060+
if (trace)
1061+
call_exc_trace(&trace, &trace, f);
1062+
if (sys_profile)
1063+
call_exc_trace(&sys_profile, (object**)0, f);
11031064
}
11041065

11051066
/* For the rest, treat WHY_RERAISE as WHY_EXCEPTION */
@@ -1177,15 +1138,22 @@ eval_code(co, globals, locals, arg)
11771138

11781139
if (trace) {
11791140
if (why == WHY_RETURN) {
1180-
x = call_trace(trace, f, "return", retval);
1181-
if (x == NULL) {
1141+
if (call_trace(&trace, &trace, f, "return", retval)) {
11821142
XDECREF(retval);
11831143
retval = NULL;
1144+
why = WHY_EXCEPTION;
11841145
}
1185-
else
1186-
DECREF(x);
11871146
}
1188-
DECREF(trace);
1147+
XDECREF(trace);
1148+
}
1149+
1150+
if (sys_profile && why == WHY_RETURN) {
1151+
if (call_trace(&sys_profile, (object**)0,
1152+
f, "return", retval)) {
1153+
XDECREF(retval);
1154+
retval = NULL;
1155+
why = WHY_EXCEPTION;
1156+
}
11891157
}
11901158

11911159
/* Restore previous frame and release the current one */
@@ -1209,44 +1177,101 @@ prtrace(v, str)
12091177
}
12101178
#endif
12111179

1212-
static object *
1213-
call_trace(trace, f, msg, arg)
1214-
object *trace;
1180+
static void
1181+
call_exc_trace(p_trace, p_newtrace, f)
1182+
object **p_trace, **p_newtrace;
1183+
frameobject *f;
1184+
{
1185+
object *type, *value, *traceback, *arg;
1186+
int err;
1187+
err_get(&type, &value);
1188+
traceback = tb_fetch();
1189+
arg = newtupleobject(3);
1190+
if (arg == NULL) {
1191+
err = -1;
1192+
goto cleanup;
1193+
}
1194+
settupleitem(arg, 0, type);
1195+
settupleitem(arg, 1, value);
1196+
settupleitem(arg, 2, traceback);
1197+
err = call_trace(p_trace, p_newtrace, f, "exception", arg);
1198+
XDECREF(arg);
1199+
cleanup:
1200+
if (!err) {
1201+
/* Restore original exception */
1202+
err_setval(type, value);
1203+
tb_store(traceback);
1204+
}
1205+
}
1206+
1207+
static int
1208+
call_trace(p_trace, p_newtrace, f, msg, arg)
1209+
object **p_trace; /* in/out; may not be NULL;
1210+
may not point to NULL variable initially */
1211+
object **p_newtrace; /* in/out; may be NULL;
1212+
may point to NULL variable;
1213+
may be same variable as p_newtrace */
12151214
frameobject *f;
12161215
char *msg;
12171216
object *arg;
12181217
{
1219-
object *arglist, *what, *res;
1218+
object *arglist, *what;
1219+
object *res = NULL;
12201220
static int tracing = 0;
12211221

12221222
if (tracing) {
1223-
/* Don't trace the trace code! */
1224-
INCREF(None);
1225-
return None;
1223+
/* Don't do recursive traces */
1224+
if (p_newtrace) {
1225+
XDECREF(*p_newtrace);
1226+
*p_newtrace = NULL;
1227+
}
1228+
return 0;
12261229
}
12271230

12281231
arglist = newtupleobject(3);
12291232
if (arglist == NULL)
1230-
return NULL;
1233+
goto cleanup;
12311234
what = newstringobject(msg);
1232-
if (what == NULL) {
1233-
DECREF(arglist);
1234-
return NULL;
1235-
}
1235+
if (what == NULL)
1236+
goto cleanup;
12361237
INCREF(f);
1238+
settupleitem(arglist, 0, (object *)f);
1239+
settupleitem(arglist, 1, what);
12371240
if (arg == NULL)
12381241
arg = None;
12391242
INCREF(arg);
1240-
settupleitem(arglist, 0, (object *)f);
1241-
settupleitem(arglist, 1, what);
12421243
settupleitem(arglist, 2, arg);
12431244
tracing++;
1244-
res = call_object(trace, arglist);
1245+
res = call_object(*p_trace, arglist);
12451246
tracing--;
1246-
if (res == NULL)
1247+
cleanup:
1248+
XDECREF(arglist);
1249+
if (res == NULL) {
1250+
/* The trace proc raised an exception */
12471251
tb_here(f);
1248-
DECREF(arglist);
1249-
return res;
1252+
XDECREF(*p_trace);
1253+
*p_trace = NULL;
1254+
if (p_newtrace) {
1255+
XDECREF(*p_newtrace);
1256+
*p_newtrace = NULL;
1257+
}
1258+
}
1259+
else {
1260+
if (p_newtrace) {
1261+
XDECREF(*p_newtrace);
1262+
if (res == None)
1263+
*p_newtrace = NULL;
1264+
else {
1265+
INCREF(res);
1266+
*p_newtrace = res;
1267+
}
1268+
}
1269+
DECREF(res);
1270+
}
1271+
if (res == NULL)
1272+
return -1;
1273+
else
1274+
return 0;
12501275
}
12511276

12521277
object *

0 commit comments

Comments
 (0)