Add trace_frame. Fixes #534864. Backported to 2.2.
diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c
index d259998..fc419b1 100644
--- a/Modules/pyexpat.c
+++ b/Modules/pyexpat.c
@@ -264,6 +264,33 @@
     return NULL;
 }
 
+static int
+trace_frame(PyThreadState *tstate, PyFrameObject *f, int code, PyObject *val)
+{
+    int result = 0;
+    if (!tstate->use_tracing || tstate->tracing)
+	return 0;
+    if (tstate->c_profilefunc != NULL) {
+	tstate->tracing++;
+	result = tstate->c_profilefunc(tstate->c_profileobj,
+				       f, code , val);
+	tstate->use_tracing = ((tstate->c_tracefunc != NULL)
+			       || (tstate->c_profilefunc != NULL));
+	tstate->tracing--;
+	if (result)
+	    return result;
+    }
+    if (tstate->c_tracefunc != NULL) {
+	tstate->tracing++;
+	result = tstate->c_tracefunc(tstate->c_traceobj,
+				     f, code , val);
+	tstate->use_tracing = ((tstate->c_tracefunc != NULL)
+			       || (tstate->c_profilefunc != NULL));
+	tstate->tracing--;
+    }	
+    return result;
+}
+
 static PyObject*
 call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args)
 {
@@ -273,6 +300,7 @@
 
     if (c == NULL)
         return NULL;
+    
     f = PyFrame_New(
                     tstate,			/*back*/
                     c,				/*code*/
@@ -282,9 +310,19 @@
     if (f == NULL)
         return NULL;
     tstate->frame = f;
+    if (trace_frame(tstate, f, PyTrace_CALL, Py_None)) {
+	Py_DECREF(f);
+	return NULL;
+    }
     res = PyEval_CallObject(func, args);
     if (res == NULL && tstate->curexc_traceback == NULL)
         PyTraceBack_Here(f);
+    else {
+	if (trace_frame(tstate, f, PyTrace_RETURN, res)) {
+	    Py_XDECREF(res);
+	    res = NULL;
+	}
+    }
     tstate->frame = f->f_back;
     Py_DECREF(f);
     return res;