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@xxxxxxxxxx> Suggested-by: Mateusz Guzik <mguzik@xxxxxxxxxx> --- 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 -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility