Port from the Python 2.4 branch, patches for SF bug # 900092,
hotshot.stats.load.
diff --git a/Lib/test/test_trace.py b/Lib/test/test_trace.py
index f85c669..7f866fb 100644
--- a/Lib/test/test_trace.py
+++ b/Lib/test/test_trace.py
@@ -97,6 +97,7 @@
                      (-3, 'call'),
                      (-2, 'line'),
                      (-2, 'exception'),
+                     (-2, 'return'),
                      (2, 'exception'),
                      (3, 'line'),
                      (4, 'line'),
diff --git a/Misc/NEWS b/Misc/NEWS
index ecbbd97..62e6656 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@
 Core and builtins
 -----------------
 
+- SF bug #900092: When tracing (e.g. for hotshot), restore 'return' events for
+  exceptions that cause a function to exit.
+
 - The implementation of set() and frozenset() was revised to use its
   own internal data structure.  Memory consumption is reduced by 1/3
   and there are modest speed-ups as well.  The API is unchanged.
diff --git a/Python/ceval.c b/Python/ceval.c
index d311537..ee3c7bb 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -2480,14 +2480,20 @@
 
 fast_yield:
 	if (tstate->use_tracing) {
-		if (tstate->c_tracefunc
-		    && (why == WHY_RETURN || why == WHY_YIELD)) {
-			if (call_trace(tstate->c_tracefunc,
-				       tstate->c_traceobj, f,
-				       PyTrace_RETURN, retval)) {
-				Py_XDECREF(retval);
-				retval = NULL;
-				why = WHY_EXCEPTION;
+		if (tstate->c_tracefunc) {
+			if (why == WHY_RETURN || why == WHY_YIELD) {
+				if (call_trace(tstate->c_tracefunc,
+					       tstate->c_traceobj, f,
+					       PyTrace_RETURN, retval)) {
+					Py_XDECREF(retval);
+					retval = NULL;
+					why = WHY_EXCEPTION;
+				}
+			}
+			else if (why == WHY_EXCEPTION) {
+				call_trace_protected(tstate->c_tracefunc,
+						     tstate->c_traceobj, f,
+						     PyTrace_RETURN);
 			}
 		}
 		if (tstate->c_profilefunc) {