Skip to content

Commit

Permalink
Fix DDB to unwind across exception frames.
Browse files Browse the repository at this point in the history
While here, add an extra line of information for exceptions and
interrupts and compress the per-frame line down to one line to match
other architectures.

Reviewed by:	mhorne, br
MFC after:	1 week
Sponsored by:	DARPA
Differential Revision:	https://reviews.freebsd.org/D23508
  • Loading branch information
bsdjhb committed Feb 6, 2020
1 parent a4964a5 commit ecafbba
Showing 1 changed file with 32 additions and 10 deletions.
42 changes: 32 additions & 10 deletions sys/riscv/riscv/db_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Copyright (c) 2015 The FreeBSD Foundation
* Copyright (c) 2016 Ruslan Bukin <[email protected]>
* All rights reserved.
* Copyright (c) 2020 John Baldwin <[email protected]>
*
* Portions of this software were developed by Semihalf under
* the sponsorship of the FreeBSD Foundation.
Expand Down Expand Up @@ -38,15 +39,18 @@

#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");

#include <sys/param.h>
#include <sys/proc.h>
#include <sys/kdb.h>
#include <machine/pcb.h>
#include <sys/proc.h>

#include <ddb/ddb.h>
#include <ddb/db_sym.h>

#include <machine/pcb.h>
#include <machine/riscvreg.h>
#include <machine/stack.h>
#include <machine/vmparam.h>

void
db_md_list_watchpoints()
Expand Down Expand Up @@ -80,9 +84,6 @@ db_stack_trace_cmd(struct unwind_state *frame)
while (1) {
pc = frame->pc;

if (unwind_frame(frame) < 0)
break;

sym = db_search_symbol(pc, DB_STGY_ANY, &offset);
if (sym == C_DB_SYM_NULL) {
value = 0;
Expand All @@ -94,11 +95,32 @@ db_stack_trace_cmd(struct unwind_state *frame)
db_printsym(frame->pc, DB_STGY_PROC);
db_printf("\n");

db_printf("\t pc = 0x%016lx ra = 0x%016lx\n",
pc, frame->pc);
db_printf("\t sp = 0x%016lx fp = 0x%016lx\n",
frame->sp, frame->fp);
db_printf("\n");
if (strcmp(name, "cpu_exception_handler_supervisor") == 0 ||
strcmp(name, "cpu_exception_handler_user") == 0) {
struct trapframe *tf;

tf = (struct trapframe *)(uintptr_t)frame->sp;

if (tf->tf_scause & EXCP_INTR)
db_printf("--- interrupt %ld\n",
tf->tf_scause & EXCP_MASK);
else
db_printf("--- exception %ld, tval = %#lx\n",
tf->tf_scause & EXCP_MASK,
tf->tf_stval);
frame->sp = (uint64_t)tf->tf_sp;
frame->fp = (uint64_t)tf->tf_s[0];
frame->pc = (uint64_t)tf->tf_sepc;
if (!INKERNEL(frame->fp))
break;
continue;
}

if (strcmp(name, "fork_trampoline") == 0)
break;

if (unwind_frame(frame) < 0)
break;
}
}

Expand Down

0 comments on commit ecafbba

Please sign in to comment.