Currently 'bt -a' displays the stack traces of the active task on each
CPU. This patch makes it possible to specify a CPU as an argument.
Multiple CPU arguments may be specified. If no argument is given
the default behaviour is maintained.
For example:
Display the stack trace of the active task on CPU 0 and 1:
crash> bt -a 0 1
PID: 0 TASK: ffffffff81a8d020 CPU: 0 COMMAND: "swapper"
#0 [ffff880002207e90] crash_nmi_callback at ffffffff8102fee6
#1 [ffff880002207ea0] notifier_call_chain at ffffffff8152d525
#2 [ffff880002207ee0] atomic_notifier_call_chain at ffffffff8152d58a
#3 [ffff880002207ef0] notify_die at ffffffff810a155e
#4 [ffff880002207f20] do_nmi at ffffffff8152b1eb
#5 [ffff880002207f50] nmi at ffffffff8152aab0
[exception RIP: native_safe_halt+0xb]
RIP: ffffffff8103eacb RSP: ffffffff81a01ea8 RFLAGS: 00000296
RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffffffff81de5228
RBP: ffffffff81a01ea8 R8: 0000000000000000 R9: 0000000000000000
R10: 0012099429a6bea3 R11: 0000000000000000 R12: ffffffff81c066c0
R13: 0000000000000000 R14: ffffffffffffffff R15: ffffffff81de1000
ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
--- <NMI exception stack> ---
#6 [ffffffff81a01ea8] native_safe_halt at ffffffff8103eacb
#7 [ffffffff81a01eb0] default_idle at ffffffff810167bd
#8 [ffffffff81a01ed0] cpu_idle at ffffffff81009fc6
PID: 38 TASK: ffff88003eaae040 CPU: 1 COMMAND: "khungtaskd"
#0 [ffff88003ad97ce8] machine_kexec at ffffffff81038f3b
#1 [ffff88003ad97d48] crash_kexec at ffffffff810c5da2
#2 [ffff88003ad97e18] panic at ffffffff8152721a
#3 [ffff88003ad97e98] watchdog at ffffffff810e6346
#4 [ffff88003ad97ee8] kthread at ffffffff8109af06
#5 [ffff88003ad97f48] kernel_thread at ffffffff8100c20a
Signed-off-by: Aaron Tomlin <atomlin(a)redhat.com>
---
help.c | 37 ++++++++++++++++++++++++++++++++++---
kernel.c | 26 +++++++++++++++++++++++---
2 files changed, 57 insertions(+), 6 deletions(-)
diff --git a/help.c b/help.c
index 91f22c3..62af23a 100644
--- a/help.c
+++ b/help.c
@@ -1704,11 +1704,13 @@ NULL
char *help_bt[] = {
"bt",
"backtrace",
-"[-a|-g|-r|-t|-T|-l|-e|-E|-f|-F|-o|-O] [-R ref] [-s [-x|d]] [-I ip] [-S sp]"
+"[-a [cpu]|-g|-r|-t|-T|-l|-e|-E|-f|-F|-o|-O] [-R ref] [-s [-x|d]] [-I ip] [-S
sp]"
"\n [pid | task]",
" Display a kernel stack backtrace. If no arguments are given, the stack",
" trace of the current context will be displayed.\n",
-" -a displays the stack traces of the active task on each CPU.",
+" -a display the stack trace of the active task on a given CPU.",
+" Multiple CPU arguments may be specified. If no arguments are
given",
+" the stack trace of the active task on each CPU is shown.",
" (only applicable to crash dumps)",
#ifdef GDB_5_3
" -g use gdb stack trace code. (alpha only)",
@@ -1766,7 +1768,36 @@ char *help_bt[] = {
" or display a stale frame reference. When in doubt as to the accuracy of
a",
" backtrace, the -t or -T options may help fill in the blanks.\n",
"EXAMPLES",
-" Display the stack trace of the active task(s) when the kernel panicked:\n",
+" Display the stack trace of the active task on CPU 0 and 1:\n",
+" %s> bt -a 0 1",
+" PID: 0 TASK: ffffffff81a8d020 CPU: 0 COMMAND:
\"swapper\"",
+" #0 [ffff880002207e90] crash_nmi_callback at ffffffff8102fee6",
+" #1 [ffff880002207ea0] notifier_call_chain at ffffffff8152d525",
+" #2 [ffff880002207ee0] atomic_notifier_call_chain at ffffffff8152d58a",
+" #3 [ffff880002207ef0] notify_die at ffffffff810a155e",
+" #4 [ffff880002207f20] do_nmi at ffffffff8152b1eb",
+" #5 [ffff880002207f50] nmi at ffffffff8152aab0",
+" [exception RIP: native_safe_halt+0xb]",
+" RIP: ffffffff8103eacb RSP: ffffffff81a01ea8 RFLAGS: 00000296",
+" RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000",
+" RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffffffff81de5228",
+" RBP: ffffffff81a01ea8 R8: 0000000000000000 R9: 0000000000000000",
+" R10: 0012099429a6bea3 R11: 0000000000000000 R12: ffffffff81c066c0",
+" R13: 0000000000000000 R14: ffffffffffffffff R15: ffffffff81de1000",
+" ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018",
+" --- <NMI exception stack> ---",
+" #6 [ffffffff81a01ea8] native_safe_halt at ffffffff8103eacb",
+" #7 [ffffffff81a01eb0] default_idle at ffffffff810167bd",
+" #8 [ffffffff81a01ed0] cpu_idle at ffffffff81009fc6",
+" ",
+" PID: 38 TASK: ffff88003eaae040 CPU: 1 COMMAND:
\"khungtaskd\"",
+" #0 [ffff88003ad97ce8] machine_kexec at ffffffff81038f3b",
+" #1 [ffff88003ad97d48] crash_kexec at ffffffff810c5da2",
+" #2 [ffff88003ad97e18] panic at ffffffff8152721a",
+" #3 [ffff88003ad97e98] watchdog at ffffffff810e6346",
+" #4 [ffff88003ad97ee8] kthread at ffffffff8109af06",
+" #5 [ffff88003ad97f48] kernel_thread at ffffffff8100c20a",
+"\n Display the stack trace of the active task(s) when the kernel
panicked:\n",
" %s> bt -a",
" PID: 286 TASK: c0b3a000 CPU: 0 COMMAND: \"in.rlogind\"",
" #0 [c0b3be90] crash_save_current_state at c011aed0",
diff --git a/kernel.c b/kernel.c
index cdc53eb..6b3e25b 100644
--- a/kernel.c
+++ b/kernel.c
@@ -1972,15 +1972,15 @@ cmd_bt(void)
int i, c;
ulong value;
struct task_context *tc;
- int count, subsequent, active;
+ int count, subsequent, active, cpu;
struct stack_hook hook;
struct bt_info bt_info, bt_setup, *bt;
struct reference reference;
char *refptr;
- ulong tgid;
+ ulong tgid, task;
tc = NULL;
- subsequent = active = count = 0;
+ subsequent = active = count = cpu = 0;
hook.eip = hook.esp = 0;
refptr = 0;
bt = &bt_info;
@@ -2232,6 +2232,26 @@ cmd_bt(void)
error(FATAL,
"-a option cannot be used with the -g option\n");
+ while (args[optind]) {
+ cpu = dtoi(args[optind], FAULT_ON_ERROR, NULL);
+ if (cpu >= kt->cpus) {
+ error(FATAL, "invalid cpu number: system has only %d cpu%s\n",
+ kt->cpus, kt->cpus > 1 ? "s" : "");
+ return;
+ }
+ if ((task = get_active_task(cpu)))
+ tc = task_to_context(task);
+ else {
+ error(FATAL, "cannot determine active task on cpu %ld\n", cpu);
+ return;
+ }
+ DO_TASK_BACKTRACE();
+
+ optind++;
+ if (!args[optind])
+ return;
+ }
+
for (c = 0; c < NR_CPUS; c++) {
if (setjmp(pc->foreach_loop_env)) {
pc->flags &= ~IN_FOREACH;
--
1.9.0