diff options
author | Visa Hankala <visa@cvs.openbsd.org> | 2020-01-20 15:58:24 +0000 |
---|---|---|
committer | Visa Hankala <visa@cvs.openbsd.org> | 2020-01-20 15:58:24 +0000 |
commit | 8dedb348f34b6ea68a8e7b1e905784762677b359 (patch) | |
tree | be188db04b4562a8245c9d11553406df9fced9f5 | |
parent | 562bc692fe4670bfd2a4b5ec728fb5f5f41bbc00 (diff) |
Separate the stack trace saving interface from ddb. The saving does not
require the debugger on most architectures, and the separation makes the
code easier to use from other subsystems.
The function definitions are still conditional to DDB. However, that
should not matter for now.
OK deraadt@, mpi@
-rw-r--r-- | sys/arch/amd64/amd64/db_trace.c | 7 | ||||
-rw-r--r-- | sys/arch/arm64/arm64/db_trace.c | 7 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/db_interface.c | 7 | ||||
-rw-r--r-- | sys/arch/i386/i386/db_trace.c | 7 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/trap.c | 7 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/db_trace.c | 7 | ||||
-rw-r--r-- | sys/ddb/db_access.h | 12 | ||||
-rw-r--r-- | sys/ddb/db_output.c | 5 | ||||
-rw-r--r-- | sys/kern/subr_witness.c | 21 | ||||
-rw-r--r-- | sys/sys/stacktrace.h | 34 |
10 files changed, 73 insertions, 41 deletions
diff --git a/sys/arch/amd64/amd64/db_trace.c b/sys/arch/amd64/amd64/db_trace.c index e5195c9e3a7..c4169b44374 100644 --- a/sys/arch/amd64/amd64/db_trace.c +++ b/sys/arch/amd64/amd64/db_trace.c @@ -1,4 +1,4 @@ -/* $OpenBSD: db_trace.c,v 1.48 2020/01/09 15:18:58 bluhm Exp $ */ +/* $OpenBSD: db_trace.c,v 1.49 2020/01/20 15:58:23 visa Exp $ */ /* $NetBSD: db_trace.c,v 1.1 2003/04/26 18:39:27 fvdl Exp $ */ /* @@ -30,6 +30,7 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/proc.h> +#include <sys/stacktrace.h> #include <sys/user.h> #include <machine/db_machdep.h> @@ -255,13 +256,13 @@ db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count, } void -db_save_stack_trace(struct db_stack_trace *st) +stacktrace_save(struct stacktrace *st) { struct callframe *frame, *lastframe; frame = __builtin_frame_address(0); st->st_count = 0; - while (st->st_count < DB_STACK_TRACE_MAX) { + while (st->st_count < STACKTRACE_MAX) { st->st_pc[st->st_count++] = frame->f_retaddr; lastframe = frame; diff --git a/sys/arch/arm64/arm64/db_trace.c b/sys/arch/arm64/arm64/db_trace.c index 113f79e3217..46c49fcfa52 100644 --- a/sys/arch/arm64/arm64/db_trace.c +++ b/sys/arch/arm64/arm64/db_trace.c @@ -1,4 +1,4 @@ -/* $OpenBSD: db_trace.c,v 1.8 2019/11/07 14:44:52 mpi Exp $ */ +/* $OpenBSD: db_trace.c,v 1.9 2020/01/20 15:58:23 visa Exp $ */ /* $NetBSD: db_trace.c,v 1.8 2003/01/17 22:28:48 thorpej Exp $ */ /* @@ -33,6 +33,7 @@ #include <sys/param.h> #include <sys/proc.h> +#include <sys/stacktrace.h> #include <sys/user.h> #include <arm64/armreg.h> #include <machine/db_machdep.h> @@ -149,13 +150,13 @@ db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count, } void -db_save_stack_trace(struct db_stack_trace *st) +stacktrace_save(struct stacktrace *st) { struct callframe *frame; frame = __builtin_frame_address(0); st->st_count = 0; - while (st->st_count < DB_STACK_TRACE_MAX) { + while (st->st_count < STACKTRACE_MAX) { st->st_pc[st->st_count++] = frame->f_lr; if (!INKERNEL(frame->f_frame) || frame->f_frame <= frame) diff --git a/sys/arch/hppa/hppa/db_interface.c b/sys/arch/hppa/hppa/db_interface.c index 7afa81ed858..53449e93713 100644 --- a/sys/arch/hppa/hppa/db_interface.c +++ b/sys/arch/hppa/hppa/db_interface.c @@ -1,4 +1,4 @@ -/* $OpenBSD: db_interface.c,v 1.46 2019/11/10 10:03:33 mpi Exp $ */ +/* $OpenBSD: db_interface.c,v 1.47 2020/01/20 15:58:23 visa Exp $ */ /* * Copyright (c) 1999-2003 Michael Shalayeff @@ -30,6 +30,7 @@ #include <sys/param.h> #include <sys/systm.h> +#include <sys/stacktrace.h> #include <machine/db_machdep.h> #include <machine/frame.h> @@ -315,7 +316,7 @@ db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count, } void -db_save_stack_trace(struct db_stack_trace *st) +stacktrace_save(struct stacktrace *st) { register_t *fp, pc, rp; int i; @@ -325,7 +326,7 @@ db_save_stack_trace(struct db_stack_trace *st) rp = fp[-5]; st->st_count = 0; - for (i = 0; i < DB_STACK_TRACE_MAX; i++) { + for (i = 0; i < STACKTRACE_MAX; i++) { st->st_pc[st->st_count++] = rp; /* next frame */ diff --git a/sys/arch/i386/i386/db_trace.c b/sys/arch/i386/i386/db_trace.c index 603a3071462..5078722d255 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.37 2019/11/07 14:44:53 mpi Exp $ */ +/* $OpenBSD: db_trace.c,v 1.38 2020/01/20 15:58:23 visa Exp $ */ /* $NetBSD: db_trace.c,v 1.18 1996/05/03 19:42:01 christos Exp $ */ /* @@ -30,6 +30,7 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/proc.h> +#include <sys/stacktrace.h> #include <sys/user.h> #include <machine/db_machdep.h> @@ -260,13 +261,13 @@ db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count, } void -db_save_stack_trace(struct db_stack_trace *st) +stacktrace_save(struct stacktrace *st) { struct callframe *frame, *lastframe; frame = __builtin_frame_address(0); st->st_count = 0; - while (st->st_count < DB_STACK_TRACE_MAX) { + while (st->st_count < STACKTRACE_MAX) { st->st_pc[st->st_count++] = frame->f_retaddr; lastframe = frame; diff --git a/sys/arch/mips64/mips64/trap.c b/sys/arch/mips64/mips64/trap.c index e2d59a34c4f..371fba749d4 100644 --- a/sys/arch/mips64/mips64/trap.c +++ b/sys/arch/mips64/mips64/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.142 2019/09/06 16:22:40 visa Exp $ */ +/* $OpenBSD: trap.c,v 1.143 2020/01/20 15:58:23 visa Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -50,6 +50,7 @@ #include <sys/kernel.h> #include <sys/signalvar.h> #include <sys/user.h> +#include <sys/stacktrace.h> #include <sys/syscall.h> #include <sys/syscall_mi.h> #include <sys/buf.h> @@ -1476,7 +1477,7 @@ end: #ifdef DDB void -db_save_stack_trace(struct db_stack_trace *st) +stacktrace_save(struct stacktrace *st) { extern char k_general[]; extern char u_general[]; @@ -1498,7 +1499,7 @@ db_save_stack_trace(struct db_stack_trace *st) sp = (vaddr_t)__builtin_frame_address(0); st->st_count = 0; - while (st->st_count < DB_STACK_TRACE_MAX && pc != 0) { + while (st->st_count < STACKTRACE_MAX && pc != 0) { if (!VALID_ADDRESS(pc) || !VALID_ADDRESS(sp)) break; diff --git a/sys/arch/sparc64/sparc64/db_trace.c b/sys/arch/sparc64/sparc64/db_trace.c index 1181c7bb2bf..376b9392c2e 100644 --- a/sys/arch/sparc64/sparc64/db_trace.c +++ b/sys/arch/sparc64/sparc64/db_trace.c @@ -1,4 +1,4 @@ -/* $OpenBSD: db_trace.c,v 1.19 2019/11/07 14:44:53 mpi Exp $ */ +/* $OpenBSD: db_trace.c,v 1.20 2020/01/20 15:58:23 visa Exp $ */ /* $NetBSD: db_trace.c,v 1.23 2001/07/10 06:06:16 eeh Exp $ */ /* @@ -30,6 +30,7 @@ #include <sys/param.h> #include <sys/proc.h> #include <sys/systm.h> +#include <sys/stacktrace.h> #include <sys/user.h> #include <machine/db_machdep.h> #include <machine/ctlreg.h> @@ -154,7 +155,7 @@ db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count, } void -db_save_stack_trace(struct db_stack_trace *st) +stacktrace_save(struct stacktrace *st) { struct frame64 *f64; vaddr_t pc; @@ -167,7 +168,7 @@ db_save_stack_trace(struct db_stack_trace *st) return; st->st_count = 0; - while (st->st_count < DB_STACK_TRACE_MAX) { + while (st->st_count < STACKTRACE_MAX) { f64 = (struct frame64 *)(frame + BIAS); pc = (vaddr_t)KLOAD(f64->fr_pc); diff --git a/sys/ddb/db_access.h b/sys/ddb/db_access.h index fc57b75b3b7..7a352079828 100644 --- a/sys/ddb/db_access.h +++ b/sys/ddb/db_access.h @@ -1,4 +1,4 @@ -/* $OpenBSD: db_access.h,v 1.10 2019/11/07 13:16:25 mpi Exp $ */ +/* $OpenBSD: db_access.h,v 1.11 2020/01/20 15:58:23 visa Exp $ */ /* $NetBSD: db_access.h,v 1.6 1994/10/09 08:29:57 mycroft Exp $ */ /* @@ -38,13 +38,3 @@ void db_put_value(vaddr_t, size_t, db_expr_t); void db_read_bytes(vaddr_t, size_t, char *); void db_write_bytes(vaddr_t, size_t, char *); - -#define DB_STACK_TRACE_MAX 19 - -struct db_stack_trace { - unsigned int st_count; - vaddr_t st_pc[DB_STACK_TRACE_MAX]; -}; - -void db_print_stack_trace(struct db_stack_trace *, int (*)(const char *, ...)); -void db_save_stack_trace(struct db_stack_trace *); diff --git a/sys/ddb/db_output.c b/sys/ddb/db_output.c index d0b9538b619..e92c8041450 100644 --- a/sys/ddb/db_output.c +++ b/sys/ddb/db_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: db_output.c,v 1.33 2019/11/06 07:30:08 mpi Exp $ */ +/* $OpenBSD: db_output.c,v 1.34 2020/01/20 15:58:23 visa Exp $ */ /* $NetBSD: db_output.c,v 1.13 1996/04/01 17:27:14 christos Exp $ */ /* @@ -33,6 +33,7 @@ #include <sys/param.h> #include <sys/stdarg.h> #include <sys/systm.h> +#include <sys/stacktrace.h> #include <dev/cons.h> @@ -245,7 +246,7 @@ db_stack_dump(void) } void -db_print_stack_trace(struct db_stack_trace *st, int (*pr)(const char *, ...)) +stacktrace_print(struct stacktrace *st, int (*pr)(const char *, ...)) { unsigned int i; diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c index 2481cf1b15c..39ef16b3775 100644 --- a/sys/kern/subr_witness.c +++ b/sys/kern/subr_witness.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_witness.c,v 1.35 2019/11/15 15:50:14 visa Exp $ */ +/* $OpenBSD: subr_witness.c,v 1.36 2020/01/20 15:58:23 visa Exp $ */ /*- * Copyright (c) 2008 Isilon Systems, Inc. @@ -97,6 +97,7 @@ #include <sys/percpu.h> #include <sys/proc.h> #include <sys/sched.h> +#include <sys/stacktrace.h> #include <sys/stdint.h> #include <sys/sysctl.h> #include <sys/syslog.h> @@ -187,7 +188,7 @@ struct lock_class { union lock_stack { union lock_stack *ls_next; - struct db_stack_trace ls_stack; + struct stacktrace ls_stack; }; #define LC_SLEEPLOCK 0x00000001 /* Sleep lock. */ @@ -267,7 +268,7 @@ struct witness_lock_order_key { }; struct witness_lock_order_data { - struct db_stack_trace wlod_stack; + struct stacktrace wlod_stack; struct witness_lock_order_key wlod_key; struct witness_lock_order_data *wlod_next; }; @@ -1069,7 +1070,7 @@ witness_checkorder(struct lock_object *lock, int flags, w->w_class->lc_name, w1->w_type->lt_name, w1->w_class->lc_name); - db_print_stack_trace( + stacktrace_print( &wlod1->wlod_stack, printf); } if (wlod2 != NULL) { @@ -1079,7 +1080,7 @@ witness_checkorder(struct lock_object *lock, int flags, w1->w_class->lc_name, w->w_type->lt_name, w->w_class->lc_name); - db_print_stack_trace( + stacktrace_print( &wlod2->wlod_stack, printf); } } @@ -1160,7 +1161,7 @@ witness_lock(struct lock_object *lock, int flags) if (witness_locktrace) { instance->li_stack = witness_lock_stack_get(); if (instance->li_stack != NULL) - db_save_stack_trace(&instance->li_stack->ls_stack); + stacktrace_save(&instance->li_stack->ls_stack); } out: splx(s); @@ -1872,7 +1873,7 @@ witness_list_lock(struct lock_instance *instance, "exclusive" : "shared", LOCK_CLASS(lock)->lc_name, lock->lo_name); prnt(" r = %d (%p)\n", instance->li_flags & LI_RECURSEMASK, lock); if (instance->li_stack != NULL) - db_print_stack_trace(&instance->li_stack->ls_stack, prnt); + stacktrace_print(&instance->li_stack->ls_stack, prnt); } #ifdef DDB @@ -2213,7 +2214,7 @@ restart: tmp_w1.w_class->lc_name, tmp_w2.w_type->lt_name, tmp_w2.w_class->lc_name); - db_print_stack_trace(&tmp_data1.wlod_stack, + stacktrace_print(&tmp_data1.wlod_stack, db_printf); db_printf("\n"); } @@ -2224,7 +2225,7 @@ restart: tmp_w2.w_class->lc_name, tmp_w1.w_type->lt_name, tmp_w1.w_class->lc_name); - db_print_stack_trace(&tmp_data2.wlod_stack, + stacktrace_print(&tmp_data2.wlod_stack, db_printf); db_printf("\n"); } @@ -2474,7 +2475,7 @@ witness_lock_order_add(struct witness *parent, struct witness *child) data->wlod_key = key; w_lohash.wloh_array[hash] = data; w_lohash.wloh_count++; - db_save_stack_trace(&data->wlod_stack); + stacktrace_save(&data->wlod_stack); return (1); } diff --git a/sys/sys/stacktrace.h b/sys/sys/stacktrace.h new file mode 100644 index 00000000000..33132973ccf --- /dev/null +++ b/sys/sys/stacktrace.h @@ -0,0 +1,34 @@ +/* $OpenBSD: stacktrace.h,v 1.1 2020/01/20 15:58:23 visa Exp $ */ + +/* + * Copyright (c) 2017 Visa Hankala + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _SYS_STACKTRACE_H_ +#define _SYS_STACKTRACE_H_ + +#define STACKTRACE_MAX 19 + +struct stacktrace { + unsigned int st_count; + unsigned long st_pc[STACKTRACE_MAX]; +}; + +#ifdef _KERNEL +void stacktrace_print(struct stacktrace *, int (*)(const char *, ...)); +void stacktrace_save(struct stacktrace *); +#endif + +#endif /* _SYS_STACKTRACE_H_ */ |