Implemented a new "bt -c cpu(s)" option to display the backtrace

of the active task on one or more cpus.  The cpus must be specified
in a comma- and/or dash-separated list; for examples ""3", "1,8,9",
"1-23", or "1,8,9-14".  Similar to "bt -a", the option is only
applicable with crash dumps.
(atomlin@redhat.com)
This commit is contained in:
Dave Anderson 2014-04-28 10:41:01 -04:00
parent 3cb7e5a66f
commit a91e410866
2 changed files with 76 additions and 7 deletions

36
help.c
View File

@ -1704,12 +1704,15 @@ 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]"
"\n [pid | task]",
"[-a|-c cpu(s)|-g|-r|-t|-T|-l|-e|-E|-f|-F|-o|-O] [-R ref] [-s [-x|d]]"
"\n [-I ip] [-S sp] [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 one or more CPUs,",
" which can be specified using the format \"3\", \"1,8,9\", \"1-23\",",
" or \"1,8,9-14\". (only applicable to crash dumps)",
#ifdef GDB_5_3
" -g use gdb stack trace code. (alpha only)",
#else
@ -1785,6 +1788,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\"",

View File

@ -1970,17 +1970,18 @@ void
cmd_bt(void)
{
int i, c;
ulong value;
ulong value, *cpus;
struct task_context *tc;
int count, 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 = count = 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,30 @@ cmd_bt(void)
#endif
}
if (choose_cpu) {
if (LIVE())
error(FATAL,
"-c option not supported on a live system or live dump\n");
if (bt->flags & BT_THREAD_GROUP)
error(FATAL,
"-c option cannot be used with the -g option\n");
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,