diff --git a/ldb/backtrace.c b/ldb/backtrace.c
index 09ccf0a6ebb44d73f27640904f90992556e91724..14d5c16ba8839b4b48d1069f30fcef2a75bb46a6 100644
--- a/ldb/backtrace.c
+++ b/ldb/backtrace.c
@@ -1,11 +1,15 @@
-/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/ldb/Attic/backtrace.c,v 1.1 1990/04/04 18:26:27 ch Exp $
+/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/ldb/Attic/backtrace.c,v 1.2 1990/04/05 00:45:06 wlott Exp $
  *
  * Simple backtrace facility.  More or less from Rob's lisp version.
  */
 
 #include <stdio.h>
+#include <signal.h>
+#include "ldb.h"
 #include "lisp.h"
 #include "globals.h"
+#include "interrupt.h"
+#include "lispregs.h"
 
 /* Sigh ... I know what the call frame looks like and it had
    better not change. */
@@ -16,6 +20,13 @@ struct call_frame {
 	lispobj other_state[6];
 };
 
+struct call_info {
+    struct call_frame *frame;
+    struct code *code;
+    lispobj lra;
+    int pc; /* Note: this is the trace file offset, not the actual pc. */
+};
+
 #define HEADER_LENGTH(header) ((header)>>8)
 
 static struct code *
@@ -23,7 +34,7 @@ code_pointer(object)
 lispobj object;
 {
 	lispobj *headerp, header;
-	int type;
+	int type, len;
 
 	headerp = (lispobj *) PTR(object);
 	header = *headerp;
@@ -35,10 +46,14 @@ lispobj object;
 	case type_ReturnPcHeader:
 	case type_FunctionHeader:
 	case type_ClosureFunctionHeader:
-		headerp -= HEADER_LENGTH(header);
+		len = HEADER_LENGTH(header);
+        	if (len == 0)
+                	headerp = NULL;
+		else
+			headerp -= len;
 		break;
 	default:
-		return (struct code *) 0;
+        	headerp = NULL;
 	}
 
 	return (struct code *) headerp;
@@ -48,7 +63,23 @@ static
 struct call_frame *
 current_cont()
 {
-	return ((struct call_frame *) current_control_stack_pointer) - 1;
+        int free;
+
+	free = SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX)>>2;
+	
+        if (free == 0)
+            return NULL;
+        else {
+            struct sigcontext *csp;
+            struct call_frame *cont;
+
+            csp = lisp_interrupt_contexts[free-1];
+            cont = (struct call_frame *)csp->sc_regs[CONT];
+            if ((lispobj *)cont == current_control_stack_pointer)
+                /* We were attempting to call an undefined function. */
+                ;
+            return cont;
+        }
 }
 
 static
@@ -59,71 +90,114 @@ struct call_frame *pointer;
 		((char *) pointer < (char *) current_control_stack_pointer));
 }
 
+static void
+info_from_sigcontext(info, csp)
+struct call_info *info;
+struct sigcontext *csp;
+{
+    unsigned long pc;
+
+    if (csp->sc_regs[CONT] == csp->sc_regs[CSP]) {
+        /* We were attempting to call an undefined function. */
+        info->frame = (struct call_frame *)csp->sc_regs[OLDCONT];
+        info->lra = (lispobj)csp->sc_regs[LRA];
+        info->code = code_pointer(info->lra);
+        pc = (unsigned long)PTR(info->lra);
+    }
+    else {
+        info->frame = (struct call_frame *)csp->sc_regs[CONT];
+        info->code = code_pointer(csp->sc_regs[CODE]);
+        info->lra = 0;
+        pc = csp->sc_pc;
+    }
+    info->pc = (pc - (unsigned long) info->code) / sizeof(lispobj) - HEADER_LENGTH(info->code->header);
+}
+
+static int
+previous_info(info)
+struct call_info *info;
+{
+    if (!cs_valid_pointer_p(info->frame)) {
+        printf("Bogus callee value (0x%08x).\n", (unsigned long)info->frame);
+        return 0;
+    }
+
+    info->lra = info->frame->saved_lra;
+    info->frame = info->frame->old_cont;
+
+    if (info->frame == NULL)
+        return 0;
+
+    info->code = code_pointer(info->lra);
+    info->pc = ((unsigned long)PTR(info->lra) - (unsigned long) info->code) / sizeof(lispobj) - HEADER_LENGTH(info->code->header);
+
+    return 1;
+}
+
 void
 backtrace(nframes)
 int nframes;
 {
-	struct call_frame *callee;
-
-	callee = current_cont();
-	while ((callee != (struct call_frame *) 0) && (nframes-- > 0)) {
-		struct call_frame *caller;
-		lispobj lra;
-		struct code *code;
-		
-		if (!cs_valid_pointer_p(callee)) {
-			printf("Bogus callee value (0x%08x).\n",
-			       (unsigned long) callee);
-			return;
-		}
-
-		if (callee->old_cont == (struct call_frame *) 0)
-			return;
-
-		lra = callee->saved_lra;
-		code = code_pointer(lra);
-
-		printf("<Frame 0x%08x, CODE: 0x%08x, ",
-		       (unsigned long) callee, (unsigned long) code);
-		if (code != (struct code *) 0) {
-			lispobj function;
-
-			function = code->entry_points;
-			while (function != NIL) {
-				struct function_header *header;
-				lispobj name;
-
-				header = (struct function_header *) PTR(function);
-				name = header->name;
-
-				if (LowtagOf(name) == type_OtherPointer) {
-					lispobj *object;
-
-					object = (lispobj *) PTR(name);
-
-					if (TypeOf(*object) == type_SymbolHeader) {
-						struct symbol *symbol;
-
-						symbol = (struct symbol *) object;
-						object = (lispobj *) PTR(symbol->name);
-					}
-					if (TypeOf(*object) == type_SimpleString) {
-						struct vector *string;
-						
-						string = (struct vector *) object;
-						printf("%s, ", (char *) string->data);
-					} else
-						printf("(Not simple string???), ");
-				} else
-					printf("(Not other pointer???), ");
-
-
-				function = header->next;
-			}
-		}
-		printf("LRA: 0x%08x, PC: 0x%04x>\n",
-		       lra, (PTR(lra) - (lispobj) code) / sizeof(lispobj));
-
-		callee = callee->old_cont;
-	}
+    struct call_info info;
+    int free;
+
+    free = SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX)>>2;
+	
+    if (free == 0) {
+        printf("Nothing to backtrace.\n");
+        return;
+    }
+
+    info_from_sigcontext(&info, lisp_interrupt_contexts[free-1]);
+
+    do {
+        printf("<Frame 0x%08x, CODE: 0x%08x, ",
+               (unsigned long) info.frame,
+               (unsigned long) info.code);
+
+        if (info.code != (struct code *) 0) {
+            lispobj function;
+
+            function = info.code->entry_points;
+            while (function != NIL) {
+                struct function_header *header;
+                lispobj name;
+
+                header = (struct function_header *) PTR(function);
+                name = header->name;
+
+                if (LowtagOf(name) == type_OtherPointer) {
+                    lispobj *object;
+
+                    object = (lispobj *) PTR(name);
+
+                    if (TypeOf(*object) == type_SymbolHeader) {
+                        struct symbol *symbol;
+
+                        symbol = (struct symbol *) object;
+                        object = (lispobj *) PTR(symbol->name);
+                    }
+                    if (TypeOf(*object) == type_SimpleString) {
+                        struct vector *string;
+
+                        string = (struct vector *) object;
+                        printf("%s, ", (char *) string->data);
+                    } else
+                        printf("(Not simple string???), ");
+                } else
+                    printf("(Not other pointer???), ");
+
+
+                function = header->next;
+            }
+        }
+
+        if (info.lra != 0)
+            printf("LRA: 0x%08x, ", (unsigned long)info.lra);
+        else
+            printf("<no LRA>, ");
+
+        printf("PC: %d\n", info.pc);
+
+    } while (--nframes > 0 && previous_info(&info));
 }