diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2016-03-03 12:44:10 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2016-03-03 12:44:10 +0000 |
commit | 00fa6f3884b72181b98d0a34d41dfd3afb2e0e4c (patch) | |
tree | 11dffb4f64b76ad3b7e7e1b17affabecb201800f /sys/arch/i386 | |
parent | 5ccf5b177d60b86369e0fb3dd5e63075b68c9640 (diff) |
Unwind the trapframe correctly when a breakpoint is set on `syscall'.
Prevent a fault in DDB on amd64.
ok mlarkin@
Diffstat (limited to 'sys/arch/i386')
-rw-r--r-- | sys/arch/i386/i386/db_trace.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/sys/arch/i386/i386/db_trace.c b/sys/arch/i386/i386/db_trace.c index 920a38364dd..798812838a2 100644 --- a/sys/arch/i386/i386/db_trace.c +++ b/sys/arch/i386/i386/db_trace.c @@ -1,4 +1,4 @@ -/* $OpenBSD: db_trace.c,v 1.18 2016/03/01 21:35:13 mpi Exp $ */ +/* $OpenBSD: db_trace.c,v 1.19 2016/03/03 12:44:09 mpi Exp $ */ /* $NetBSD: db_trace.c,v 1.18 1996/05/03 19:42:01 christos Exp $ */ /* @@ -158,7 +158,7 @@ db_stack_trace_print(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *modif, int (*pr)(const char *, ...)) { struct callframe *frame, *lastframe; - int *argp; + int *argp, *arg0; db_addr_t callpc; int is_trap = 0; boolean_t kernel_only = TRUE; @@ -224,7 +224,7 @@ db_stack_trace_print(db_expr_t addr, boolean_t have_addr, db_expr_t count, offset = 0; } } - if (INKERNEL((int)frame) && name) { + if (INKERNEL(callpc) && name) { if (!strcmp(name, "trap")) { is_trap = TRAP; } else if (!strcmp(name, "ast")) { @@ -255,12 +255,13 @@ db_stack_trace_print(db_expr_t addr, boolean_t have_addr, db_expr_t count, * We have a breakpoint before the frame is set up * Use %esp instead */ - argp = &((struct callframe *)(ddb_regs.tf_esp-4))->f_arg0; + arg0 = + &((struct callframe *)(ddb_regs.tf_esp-4))->f_arg0; } else { - argp = &frame->f_arg0; + arg0 = &frame->f_arg0; } - while (narg) { + for (argp = arg0; narg > 0; ) { (*pr)("%x", db_get_value((int)argp, 4, FALSE)); argp++; if (--narg != 0) @@ -270,7 +271,7 @@ db_stack_trace_print(db_expr_t addr, boolean_t have_addr, db_expr_t count, db_printsym(callpc, DB_STGY_PROC, pr); (*pr)("\n"); - if (lastframe == 0 && offset == 0 && !have_addr) { + if (lastframe == 0 && offset == 0 && !have_addr && !is_trap) { /* Frame really belongs to next callpc */ lastframe = (struct callframe *)(ddb_regs.tf_esp-4); callpc = (db_addr_t) @@ -279,7 +280,7 @@ db_stack_trace_print(db_expr_t addr, boolean_t have_addr, db_expr_t count, } lastframe = frame; - db_nextframe(&frame, &callpc, &frame->f_arg0, is_trap, pr); + db_nextframe(&frame, &callpc, arg0, is_trap, pr); if (frame == 0) { /* end of chain */ |