diff options
author | kib <kib@FreeBSD.org> | 2006-11-02 11:47:38 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2006-11-02 11:47:38 +0000 |
commit | cab0eda108dcab7fcb29349eb102624a4218bace (patch) | |
tree | 2b2a0faaebab8167ddc9d6da7ed4e7b404afec2d /sys/ddb | |
parent | 8ea2c97d7358430fe599562f2beb76834eedcf84 (diff) | |
download | FreeBSD-src-cab0eda108dcab7fcb29349eb102624a4218bace.zip FreeBSD-src-cab0eda108dcab7fcb29349eb102624a4218bace.tar.gz |
On trap while inside ddb, the trap handler calls kdb_reenter(), that
longjmp to the default context. As result, "alltrace" command may
be prematurely terminated (without error message). This is happens,
for instance, when system is low on memory and referenced page in
kernel-mode thread stack is swapped out.
Protect "alltrace" against termination on trap by setting temporary
kdb_jmpbuf context.
Submitted by: Peter Holm
Diffstat (limited to 'sys/ddb')
-rw-r--r-- | sys/ddb/db_command.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/sys/ddb/db_command.c b/sys/ddb/db_command.c index 98fd39a..3614e48 100644 --- a/sys/ddb/db_command.c +++ b/sys/ddb/db_command.c @@ -690,14 +690,22 @@ db_stack_trace_all(db_expr_t dummy, boolean_t dummy2, db_expr_t dummy3, { struct proc *p; struct thread *td; + jmp_buf jb; + void *prev_jb; LIST_FOREACH(p, &allproc, p_list) { - FOREACH_THREAD_IN_PROC(p, td) { - db_printf("\nTracing command %s pid %d tid %ld td %p\n", - p->p_comm, p->p_pid, (long)td->td_tid, td); - db_trace_thread(td, -1); - if (db_pager_quit) - return; + prev_jb = kdb_jmpbuf(jb); + if (setjmp(jb) == 0) { + FOREACH_THREAD_IN_PROC(p, td) { + db_printf("\nTracing command %s pid %d tid %ld td %p\n", + p->p_comm, p->p_pid, (long)td->td_tid, td); + db_trace_thread(td, -1); + if (db_pager_quit) { + kdb_jmpbuf(prev_jb); + return; + } + } } + kdb_jmpbuf(prev_jb); } } |