@@ -71,7 +71,9 @@ static int testbool();
7171static int assign_subscript PROTO ((object * , object * , object * ) );
7272static int assign_slice PROTO ((object * , object * , object * , object * ) );
7373static 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
7779static 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
12521277object *
0 commit comments