summaryrefslogtreecommitdiffstats
path: root/sys/alpha
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2005-08-03 04:27:40 +0000
committerjeff <jeff@FreeBSD.org>2005-08-03 04:27:40 +0000
commit4a761caec7754f1fc2754466099320c54bf45abb (patch)
tree52986abea99ce3e4955fd106535de6f4e591bac2 /sys/alpha
parent24f85b0b69c29af04dc033d110270b9a40a1bcaa (diff)
downloadFreeBSD-src-4a761caec7754f1fc2754466099320c54bf45abb.zip
FreeBSD-src-4a761caec7754f1fc2754466099320c54bf45abb.tar.gz
- Add support for saving stack traces and displaying them via printf(9)
and KTR. Contributed by: Antoine Brodin <antoine.brodin@laposte.net> Concept code from: Neal Fachan <neal@isilon.com>
Diffstat (limited to 'sys/alpha')
-rw-r--r--sys/alpha/alpha/db_trace.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/sys/alpha/alpha/db_trace.c b/sys/alpha/alpha/db_trace.c
index fcee2f3..12b6af4 100644
--- a/sys/alpha/alpha/db_trace.c
+++ b/sys/alpha/alpha/db_trace.c
@@ -47,7 +47,9 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kdb.h>
+#include <sys/linker.h>
#include <sys/proc.h>
+#include <sys/stack.h>
#include <sys/sysent.h>
#include <machine/db_machdep.h>
@@ -348,6 +350,45 @@ db_trace_thread(struct thread *thr, int count)
count));
}
+void
+stack_save(struct stack *st)
+{
+ struct prologue_info pi;
+ linker_symval_t symval;
+ c_linker_sym_t sym;
+ vm_offset_t callpc, frame;
+ long offset;
+ register_t pc, sp;
+
+ stack_zero(st);
+ __asm __volatile(
+ " mov $30,%0 \n"
+ " lda %1,1f \n"
+ "1:\n"
+ : "=r" (sp), "=r" (pc));
+ callpc = (vm_offset_t)pc;
+ frame = (vm_offset_t)sp;
+ while (1) {
+ /*
+ * search_symbol/symbol_values are slow
+ */
+ if (linker_ddb_search_symbol((caddr_t)callpc, &sym, &offset) != 0)
+ break;
+ if (linker_ddb_symbol_values(sym, &symval) != 0)
+ break;
+ if (callpc < (vm_offset_t)symval.value)
+ break;
+ if (stack_put(st, callpc) == -1)
+ break;
+ if (decode_prologue(callpc, (db_addr_t)symval.value, &pi))
+ break;
+ if ((pi.pi_regmask & (1 << 26)) == 0)
+ break;
+ callpc = *(vm_offset_t *)(frame + pi.pi_reg_offset[26]);
+ frame += pi.pi_frame_size;
+ }
+}
+
int
db_md_set_watchpoint(addr, size)
db_expr_t addr;
OpenPOWER on IntegriCloud