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:
parent
c998939536
commit
c59fd4de21
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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_ */
|
Loading…
Reference in New Issue