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@
This commit is contained in:
visa 2020-01-20 15:58:23 +00:00
parent c998939536
commit c59fd4de21
10 changed files with 73 additions and 41 deletions

View File

@ -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;

View File

@ -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)

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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 *);

View File

@ -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;

View File

@ -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);
}

34
sys/sys/stacktrace.h Normal file
View File

@ -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_ */