LCOV - code coverage report
Current view: top level - kernel/debug/kdb - kdb_bt.c (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_qemu_modules_combined.info Lines: 0 89 0.0 %
Date: 2020-09-30 20:25:01 Functions: 0 3 0.0 %
Branches: 0 70 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Kernel Debugger Architecture Independent Stack Traceback
       3                 :            :  *
       4                 :            :  * This file is subject to the terms and conditions of the GNU General Public
       5                 :            :  * License.  See the file "COPYING" in the main directory of this archive
       6                 :            :  * for more details.
       7                 :            :  *
       8                 :            :  * Copyright (c) 1999-2004 Silicon Graphics, Inc.  All Rights Reserved.
       9                 :            :  * Copyright (c) 2009 Wind River Systems, Inc.  All Rights Reserved.
      10                 :            :  */
      11                 :            : 
      12                 :            : #include <linux/ctype.h>
      13                 :            : #include <linux/string.h>
      14                 :            : #include <linux/kernel.h>
      15                 :            : #include <linux/sched/signal.h>
      16                 :            : #include <linux/sched/debug.h>
      17                 :            : #include <linux/kdb.h>
      18                 :            : #include <linux/nmi.h>
      19                 :            : #include "kdb_private.h"
      20                 :            : 
      21                 :            : 
      22                 :          0 : static void kdb_show_stack(struct task_struct *p, void *addr)
      23                 :            : {
      24                 :          0 :         int old_lvl = console_loglevel;
      25                 :          0 :         console_loglevel = CONSOLE_LOGLEVEL_MOTORMOUTH;
      26                 :          0 :         kdb_trap_printk++;
      27                 :          0 :         kdb_set_current_task(p);
      28         [ #  # ]:          0 :         if (addr) {
      29                 :          0 :                 show_stack((struct task_struct *)p, addr);
      30         [ #  # ]:          0 :         } else if (kdb_current_regs) {
      31                 :            : #ifdef CONFIG_X86
      32                 :            :                 show_stack(p, &kdb_current_regs->sp);
      33                 :            : #else
      34                 :          0 :                 show_stack(p, NULL);
      35                 :            : #endif
      36                 :            :         } else {
      37                 :          0 :                 show_stack(p, NULL);
      38                 :            :         }
      39                 :          0 :         console_loglevel = old_lvl;
      40                 :          0 :         kdb_trap_printk--;
      41                 :          0 : }
      42                 :            : 
      43                 :            : /*
      44                 :            :  * kdb_bt
      45                 :            :  *
      46                 :            :  *      This function implements the 'bt' command.  Print a stack
      47                 :            :  *      traceback.
      48                 :            :  *
      49                 :            :  *      bt [<address-expression>] (addr-exp is for alternate stacks)
      50                 :            :  *      btp <pid>                 Kernel stack for <pid>
      51                 :            :  *      btt <address-expression>  Kernel stack for task structure at
      52                 :            :  *                                      <address-expression>
      53                 :            :  *      bta [DRSTCZEUIMA]               All useful processes, optionally
      54                 :            :  *                                      filtered by state
      55                 :            :  *      btc [<cpu>]                       The current process on one cpu,
      56                 :            :  *                                      default is all cpus
      57                 :            :  *
      58                 :            :  *      bt <address-expression> refers to a address on the stack, that location
      59                 :            :  *      is assumed to contain a return address.
      60                 :            :  *
      61                 :            :  *      btt <address-expression> refers to the address of a struct task.
      62                 :            :  *
      63                 :            :  * Inputs:
      64                 :            :  *      argc    argument count
      65                 :            :  *      argv    argument vector
      66                 :            :  * Outputs:
      67                 :            :  *      None.
      68                 :            :  * Returns:
      69                 :            :  *      zero for success, a kdb diagnostic if error
      70                 :            :  * Locking:
      71                 :            :  *      none.
      72                 :            :  * Remarks:
      73                 :            :  *      Backtrack works best when the code uses frame pointers.  But even
      74                 :            :  *      without frame pointers we should get a reasonable trace.
      75                 :            :  *
      76                 :            :  *      mds comes in handy when examining the stack to do a manual traceback or
      77                 :            :  *      to get a starting point for bt <address-expression>.
      78                 :            :  */
      79                 :            : 
      80                 :            : static int
      81                 :          0 : kdb_bt1(struct task_struct *p, unsigned long mask,
      82                 :            :         int argcount, int btaprompt)
      83                 :            : {
      84                 :            :         char buffer[2];
      85   [ #  #  #  # ]:          0 :         if (kdb_getarea(buffer[0], (unsigned long)p) ||
      86                 :          0 :             kdb_getarea(buffer[0], (unsigned long)(p+1)-1))
      87                 :            :                 return KDB_BADADDR;
      88         [ #  # ]:          0 :         if (!kdb_task_state(p, mask))
      89                 :            :                 return 0;
      90                 :          0 :         kdb_printf("Stack traceback for pid %d\n", p->pid);
      91                 :          0 :         kdb_ps1(p);
      92                 :          0 :         kdb_show_stack(p, NULL);
      93         [ #  # ]:          0 :         if (btaprompt) {
      94                 :          0 :                 kdb_getstr(buffer, sizeof(buffer),
      95                 :            :                            "Enter <q> to end, <cr> to continue:");
      96         [ #  # ]:          0 :                 if (buffer[0] == 'q') {
      97                 :          0 :                         kdb_printf("\n");
      98                 :          0 :                         return 1;
      99                 :            :                 }
     100                 :            :         }
     101                 :            :         touch_nmi_watchdog();
     102                 :            :         return 0;
     103                 :            : }
     104                 :            : 
     105                 :            : int
     106                 :          0 : kdb_bt(int argc, const char **argv)
     107                 :            : {
     108                 :            :         int diag;
     109                 :            :         int argcount = 5;
     110                 :          0 :         int btaprompt = 1;
     111                 :            :         int nextarg;
     112                 :            :         unsigned long addr;
     113                 :            :         long offset;
     114                 :            : 
     115                 :            :         /* Prompt after each proc in bta */
     116                 :          0 :         kdbgetintenv("BTAPROMPT", &btaprompt);
     117                 :            : 
     118         [ #  # ]:          0 :         if (strcmp(argv[0], "bta") == 0) {
     119                 :            :                 struct task_struct *g, *p;
     120                 :            :                 unsigned long cpu;
     121         [ #  # ]:          0 :                 unsigned long mask = kdb_task_state_string(argc ? argv[1] :
     122                 :            :                                                            NULL);
     123         [ #  # ]:          0 :                 if (argc == 0)
     124                 :          0 :                         kdb_ps_suppressed();
     125                 :            :                 /* Run the active tasks first */
     126         [ #  # ]:          0 :                 for_each_online_cpu(cpu) {
     127                 :          0 :                         p = kdb_curr_task(cpu);
     128         [ #  # ]:          0 :                         if (kdb_bt1(p, mask, argcount, btaprompt))
     129                 :            :                                 return 0;
     130                 :            :                 }
     131                 :            :                 /* Now the inactive tasks */
     132         [ #  # ]:          0 :                 kdb_do_each_thread(g, p) {
     133         [ #  # ]:          0 :                         if (KDB_FLAG(CMD_INTERRUPT))
     134                 :            :                                 return 0;
     135         [ #  # ]:          0 :                         if (task_curr(p))
     136                 :          0 :                                 continue;
     137         [ #  # ]:          0 :                         if (kdb_bt1(p, mask, argcount, btaprompt))
     138                 :            :                                 return 0;
     139         [ #  # ]:          0 :                 } kdb_while_each_thread(g, p);
     140         [ #  # ]:          0 :         } else if (strcmp(argv[0], "btp") == 0) {
     141                 :            :                 struct task_struct *p;
     142                 :            :                 unsigned long pid;
     143         [ #  # ]:          0 :                 if (argc != 1)
     144                 :            :                         return KDB_ARGCOUNT;
     145                 :          0 :                 diag = kdbgetularg((char *)argv[1], &pid);
     146         [ #  # ]:          0 :                 if (diag)
     147                 :            :                         return diag;
     148                 :          0 :                 p = find_task_by_pid_ns(pid, &init_pid_ns);
     149         [ #  # ]:          0 :                 if (p) {
     150                 :          0 :                         kdb_set_current_task(p);
     151                 :          0 :                         return kdb_bt1(p, ~0UL, argcount, 0);
     152                 :            :                 }
     153                 :          0 :                 kdb_printf("No process with pid == %ld found\n", pid);
     154                 :          0 :                 return 0;
     155         [ #  # ]:          0 :         } else if (strcmp(argv[0], "btt") == 0) {
     156         [ #  # ]:          0 :                 if (argc != 1)
     157                 :            :                         return KDB_ARGCOUNT;
     158                 :          0 :                 diag = kdbgetularg((char *)argv[1], &addr);
     159         [ #  # ]:          0 :                 if (diag)
     160                 :            :                         return diag;
     161                 :          0 :                 kdb_set_current_task((struct task_struct *)addr);
     162                 :          0 :                 return kdb_bt1((struct task_struct *)addr, ~0UL, argcount, 0);
     163         [ #  # ]:          0 :         } else if (strcmp(argv[0], "btc") == 0) {
     164                 :          0 :                 unsigned long cpu = ~0;
     165                 :          0 :                 struct task_struct *save_current_task = kdb_current_task;
     166                 :            :                 char buf[80];
     167         [ #  # ]:          0 :                 if (argc > 1)
     168                 :            :                         return KDB_ARGCOUNT;
     169         [ #  # ]:          0 :                 if (argc == 1) {
     170                 :          0 :                         diag = kdbgetularg((char *)argv[1], &cpu);
     171         [ #  # ]:          0 :                         if (diag)
     172                 :            :                                 return diag;
     173                 :            :                 }
     174                 :            :                 /* Recursive use of kdb_parse, do not use argv after
     175                 :            :                  * this point */
     176                 :            :                 argv = NULL;
     177         [ #  # ]:          0 :                 if (cpu != ~0) {
     178   [ #  #  #  # ]:          0 :                         if (cpu >= num_possible_cpus() || !cpu_online(cpu)) {
     179                 :          0 :                                 kdb_printf("no process for cpu %ld\n", cpu);
     180                 :          0 :                                 return 0;
     181                 :            :                         }
     182                 :          0 :                         sprintf(buf, "btt 0x%px\n", KDB_TSK(cpu));
     183                 :          0 :                         kdb_parse(buf);
     184                 :          0 :                         return 0;
     185                 :            :                 }
     186                 :          0 :                 kdb_printf("btc: cpu status: ");
     187                 :          0 :                 kdb_parse("cpu\n");
     188         [ #  # ]:          0 :                 for_each_online_cpu(cpu) {
     189                 :          0 :                         void *kdb_tsk = KDB_TSK(cpu);
     190                 :            : 
     191                 :            :                         /* If a CPU failed to round up we could be here */
     192         [ #  # ]:          0 :                         if (!kdb_tsk) {
     193                 :          0 :                                 kdb_printf("WARNING: no task for cpu %ld\n",
     194                 :            :                                            cpu);
     195                 :          0 :                                 continue;
     196                 :            :                         }
     197                 :            : 
     198                 :          0 :                         sprintf(buf, "btt 0x%px\n", kdb_tsk);
     199                 :          0 :                         kdb_parse(buf);
     200                 :            :                         touch_nmi_watchdog();
     201                 :            :                 }
     202                 :          0 :                 kdb_set_current_task(save_current_task);
     203                 :          0 :                 return 0;
     204                 :            :         } else {
     205         [ #  # ]:          0 :                 if (argc) {
     206                 :          0 :                         nextarg = 1;
     207                 :          0 :                         diag = kdbgetaddrarg(argc, argv, &nextarg, &addr,
     208                 :            :                                              &offset, NULL);
     209         [ #  # ]:          0 :                         if (diag)
     210                 :            :                                 return diag;
     211                 :          0 :                         kdb_show_stack(kdb_current_task, (void *)addr);
     212                 :          0 :                         return 0;
     213                 :            :                 } else {
     214                 :          0 :                         return kdb_bt1(kdb_current_task, ~0UL, argcount, 0);
     215                 :            :                 }
     216                 :            :         }
     217                 :            : 
     218                 :            :         /* NOTREACHED */
     219                 :            :         return 0;
     220                 :            : }

Generated by: LCOV version 1.14