Currently 'bt -a' displays the stack traces of the active task on each
CPU. Sometimes it is preferred to display a specified CPU or CPU set.
This patch introduces the '-c' option to the 'bt' command to display the
stack
trace of the active task on the specified CPU[s]; CPU can be specified as
"1,8,9", "1-23", "1,8,9-14", "all", or
"a" (shortcut for "all").
Similar to the 'bt -a' option, it is only applicable to crash dumps.
For example:
Display the stack trace (symbol name plus its offses) of the active task on
CPU 0 and 1:
crash> bt -c 0,1 -s
PID: 0 TASK: ffffffff81a8d020 CPU: 0 COMMAND: "swapper"
#0 [ffff880002207e90] crash_nmi_callback+0x46 at ffffffff8102fee6
#1 [ffff880002207ea0] notifier_call_chain+0x55 at ffffffff8152d525
#2 [ffff880002207ee0] atomic_notifier_call_chain+0x1a at ffffffff8152d58a
#3 [ffff880002207ef0] notify_die+0x2e at ffffffff810a155e
#4 [ffff880002207f20] do_nmi+0x1bb at ffffffff8152b1eb
#5 [ffff880002207f50] nmi+0x20 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+0xb at ffffffff8103eacb
#7 [ffffffff81a01eb0] default_idle+0x4d at ffffffff810167bd
#8 [ffffffff81a01ed0] cpu_idle+0xb6 at ffffffff81009fc6
PID: 38 TASK: ffff88003eaae040 CPU: 1 COMMAND: "khungtaskd"
#0 [ffff88003ad97ce8] machine_kexec+0x18b at ffffffff81038f3b
#1 [ffff88003ad97d48] crash_kexec+0x72 at ffffffff810c5da2
#2 [ffff88003ad97e18] panic+0xae at ffffffff8152721a
#3 [ffff88003ad97e98] watchdog+0x246 at ffffffff810e6346
#4 [ffff88003ad97ee8] kthread+0x96 at ffffffff8109af06
#5 [ffff88003ad97f48] child_rip+0xa at ffffffff8100c20a
Signed-off-by: Aaron Tomlin <atomlin(a)redhat.com>
Suggested-by: Mateusz Guzik <mguzik(a)redhat.com>
---
help.c | 35 ++++++++++++++++++++++++++++++++++-
kernel.c | 40 +++++++++++++++++++++++++++++++++++-----
2 files changed, 69 insertions(+), 6 deletions(-)
diff --git a/help.c b/help.c
index 91f22c3..90a4e48 100644
--- a/help.c
+++ b/help.c
@@ -1704,12 +1704,16 @@ 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|c [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.",
" (only applicable to crash dumps)",
+" -c cpu display the stack trace of the active task on the specified",
+" CPU[s]; CPU can be specified as \"1,8,9\", \"1-23\",
\"1,8,9-14\",",
+" \"all\", or \"a\" (shortcut for
\"all\").",
+" (only applicable to crash dumps)",
#ifdef GDB_5_3
" -g use gdb stack trace code. (alpha only)",
#else
@@ -1785,6 +1789,35 @@ char *help_bt[] = {
" DS: 002b ESI: bfffc8a0 ES: 002b EDI: 00000000 ",
" SS: 002b ESP: bfffc82c EBP: bfffd224 ",
" CS: 0023 EIP: 400d032e ERR: 0000008e EFLAGS: 00000246 ",
+"\n Display the stack trace of the active task on CPU 0 and 1:\n",
+" %s> bt -c 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 traces of task f2814000 and PID 1592:\n",
" %s> bt f2814000 1592",
" PID: 1018 TASK: f2814000 CPU: 1 COMMAND: \"java\"",
diff --git a/kernel.c b/kernel.c
index 4dd7e5f..57cf69a 100644
--- a/kernel.c
+++ b/kernel.c
@@ -1970,17 +1970,18 @@ void
cmd_bt(void)
{
int i, c;
- ulong value;
+ ulong value, *cpus;
struct task_context *tc;
- int subsequent, active;
+ int subsequent, active, choose_cpu;
struct stack_hook hook;
struct bt_info bt_info, bt_setup, *bt;
struct reference reference;
char *refptr;
- ulong tgid;
+ ulong tgid, task;
+ char arg_buf[BUFSIZE];
tc = NULL;
- subsequent = active = 0;
+ subsequent = active = choose_cpu = 0;
hook.eip = hook.esp = 0;
refptr = 0;
bt = &bt_info;
@@ -1989,7 +1990,7 @@ cmd_bt(void)
if (kt->flags & USE_OLD_BT)
bt->flags |= BT_OLD_BACK_TRACE;
- while ((c = getopt(argcnt, args, "D:fFI:S:aloreEgstTdxR:O")) != EOF) {
+ while ((c = getopt(argcnt, args, "D:fFI:S:c:aloreEgstTdxR:O")) != EOF)
{
switch (c)
{
case 'f':
@@ -2132,6 +2133,18 @@ cmd_bt(void)
"invalid stack address for this task: 0\n");
break;
+ case 'c':
+ if (choose_cpu) {
+ error(INFO, "only one -c option allowed\n");
+ argerrs++;
+ } else {
+ choose_cpu = 1;
+ BZERO(arg_buf, BUFSIZE);
+ strncpy(arg_buf, optarg, strlen(optarg));
+ cpus = get_cpumask_buf();
+ }
+ break;
+
case 'a':
active++;
break;
@@ -2223,6 +2236,23 @@ cmd_bt(void)
#endif
}
+ if (choose_cpu) {
+ make_cpumask(arg_buf, cpus, FAULT_ON_ERROR, NULL);
+
+ for (i = 0; i < kt->cpus; i++) {
+ if (NUM_IN_BITMAP(cpus, i)) {
+ if ((task = get_active_task(i)))
+ tc = task_to_context(task);
+ else
+ error(FATAL, "cannot determine active task
on cpu %ld\n", i);
+
+ DO_TASK_BACKTRACE();
+ }
+ }
+ FREEBUF(cpus);
+ return;
+ }
+
if (active) {
if (LIVE())
error(FATAL,
--
1.9.0