Date: Thu, 12 Apr 2012 17:43:59 +0000 (UTC) From: John Baldwin <jhb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r234190 - in head/sys: kern sys Message-ID: <201204121743.q3CHhxQA039333@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Thu Apr 12 17:43:59 2012 New Revision: 234190 URL: http://svn.freebsd.org/changeset/base/234190 Log: - Extend the KDB interface to add a per-debugger callback to print a backtrace for an arbitrary thread (rather than the calling thread). A kdb_backtrace_thread() wrapper function uses the configured debugger if possible, otherwise it falls back to using stack(9) if that is available. - Replace a direct call to db_trace_thread() in propagate_priority() with a call to kdb_backtrace_thread() instead. MFC after: 1 week Modified: head/sys/kern/subr_kdb.c head/sys/kern/subr_turnstile.c head/sys/sys/kdb.h Modified: head/sys/kern/subr_kdb.c ============================================================================== --- head/sys/kern/subr_kdb.c Thu Apr 12 16:55:48 2012 (r234189) +++ head/sys/kern/subr_kdb.c Thu Apr 12 17:43:59 2012 (r234190) @@ -73,7 +73,7 @@ struct trapframe *kdb_frame = NULL; static int kdb_break_to_debugger = KDB_BREAK_TO_DEBUGGER; static int kdb_alt_break_to_debugger = KDB_ALT_BREAK_TO_DEBUGGER; -KDB_BACKEND(null, NULL, NULL, NULL); +KDB_BACKEND(null, NULL, NULL, NULL, NULL); SET_DECLARE(kdb_dbbe_set, struct kdb_dbbe); static int kdb_sysctl_available(SYSCTL_HANDLER_ARGS); @@ -376,6 +376,7 @@ kdb_backtrace(void) struct stack st; printf("KDB: stack backtrace:\n"); + stack_zero(&st); stack_save(&st); stack_print_ddb(&st); } @@ -383,6 +384,30 @@ kdb_backtrace(void) } /* + * Similar to kdb_backtrace() except that it prints a backtrace of an + * arbitrary thread rather than the calling thread. + */ +void +kdb_backtrace_thread(struct thread *td) +{ + + if (kdb_dbbe != NULL && kdb_dbbe->dbbe_trace_thread != NULL) { + printf("KDB: stack backtrace of thread %d:\n", td->td_tid); + kdb_dbbe->dbbe_trace_thread(td); + } +#ifdef STACK + else { + struct stack st; + + printf("KDB: stack backtrace of thread %d:\n", td->td_tid); + stack_zero(&st); + stack_save_td(&st, td); + stack_print_ddb(&st); + } +#endif +} + +/* * Set/change the current backend. */ Modified: head/sys/kern/subr_turnstile.c ============================================================================== --- head/sys/kern/subr_turnstile.c Thu Apr 12 16:55:48 2012 (r234189) +++ head/sys/kern/subr_turnstile.c Thu Apr 12 17:43:59 2012 (r234190) @@ -217,9 +217,7 @@ propagate_priority(struct thread *td) printf( "Sleeping thread (tid %d, pid %d) owns a non-sleepable lock\n", td->td_tid, td->td_proc->p_pid); -#ifdef DDB - db_trace_thread(td, -1); -#endif + kdb_backtrace_thread(td); panic("sleeping thread"); } Modified: head/sys/sys/kdb.h ============================================================================== --- head/sys/sys/kdb.h Thu Apr 12 16:55:48 2012 (r234189) +++ head/sys/sys/kdb.h Thu Apr 12 17:43:59 2012 (r234190) @@ -31,31 +31,34 @@ #include <machine/setjmp.h> +struct pcb; +struct thread; +struct trapframe; + typedef int dbbe_init_f(void); typedef void dbbe_trace_f(void); +typedef void dbbe_trace_thread_f(struct thread *); typedef int dbbe_trap_f(int, int); struct kdb_dbbe { const char *dbbe_name; dbbe_init_f *dbbe_init; dbbe_trace_f *dbbe_trace; + dbbe_trace_thread_f *dbbe_trace_thread; dbbe_trap_f *dbbe_trap; int dbbe_active; }; -#define KDB_BACKEND(name, init, trace, trap) \ +#define KDB_BACKEND(name, init, trace, trace_thread, trap) \ static struct kdb_dbbe name##_dbbe = { \ .dbbe_name = #name, \ .dbbe_init = init, \ .dbbe_trace = trace, \ + .dbbe_trace_thread = trace_thread, \ .dbbe_trap = trap \ }; \ DATA_SET(kdb_dbbe_set, name##_dbbe) -struct pcb; -struct thread; -struct trapframe; - extern int kdb_active; /* Non-zero while in debugger. */ extern int debugger_on_panic; /* enter the debugger on panic. */ extern struct kdb_dbbe *kdb_dbbe; /* Default debugger backend or NULL. */ @@ -67,6 +70,7 @@ int kdb_alt_break(int, int *); int kdb_alt_break_gdb(int, int *); int kdb_break(void); void kdb_backtrace(void); +void kdb_backtrace_thread(struct thread *); int kdb_dbbe_select(const char *); void kdb_enter(const char *, const char *); void kdb_init(void);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201204121743.q3CHhxQA039333>