dump_stack.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Provide a default dump_stack() function for architectures
  4. * which don't implement their own.
  5. */
  6. #include <linux/kernel.h>
  7. #include <linux/buildid.h>
  8. #include <linux/export.h>
  9. #include <linux/sched.h>
  10. #include <linux/sched/debug.h>
  11. #include <linux/smp.h>
  12. #include <linux/atomic.h>
  13. #include <linux/kexec.h>
  14. #include <linux/utsname.h>
  15. #include <linux/stop_machine.h>
  16. static char dump_stack_arch_desc_str[128];
  17. /**
  18. * dump_stack_set_arch_desc - set arch-specific str to show with task dumps
  19. * @fmt: printf-style format string
  20. * @...: arguments for the format string
  21. *
  22. * The configured string will be printed right after utsname during task
  23. * dumps. Usually used to add arch-specific system identifiers. If an
  24. * arch wants to make use of such an ID string, it should initialize this
  25. * as soon as possible during boot.
  26. */
  27. void __init dump_stack_set_arch_desc(const char *fmt, ...)
  28. {
  29. va_list args;
  30. va_start(args, fmt);
  31. vsnprintf(dump_stack_arch_desc_str, sizeof(dump_stack_arch_desc_str),
  32. fmt, args);
  33. va_end(args);
  34. }
  35. #if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID)
  36. #define BUILD_ID_FMT " %20phN"
  37. #define BUILD_ID_VAL vmlinux_build_id
  38. #else
  39. #define BUILD_ID_FMT "%s"
  40. #define BUILD_ID_VAL ""
  41. #endif
  42. /**
  43. * dump_stack_print_info - print generic debug info for dump_stack()
  44. * @log_lvl: log level
  45. *
  46. * Arch-specific dump_stack() implementations can use this function to
  47. * print out the same debug information as the generic dump_stack().
  48. */
  49. void dump_stack_print_info(const char *log_lvl)
  50. {
  51. printk("%sCPU: %d PID: %d Comm: %.20s %s%s %s %.*s" BUILD_ID_FMT "\n",
  52. log_lvl, raw_smp_processor_id(), current->pid, current->comm,
  53. kexec_crash_loaded() ? "Kdump: loaded " : "",
  54. print_tainted(),
  55. init_utsname()->release,
  56. (int)strcspn(init_utsname()->version, " "),
  57. init_utsname()->version, BUILD_ID_VAL);
  58. if (dump_stack_arch_desc_str[0] != '\0')
  59. printk("%sHardware name: %s\n",
  60. log_lvl, dump_stack_arch_desc_str);
  61. print_worker_info(log_lvl, current);
  62. print_stop_info(log_lvl, current);
  63. }
  64. /**
  65. * show_regs_print_info - print generic debug info for show_regs()
  66. * @log_lvl: log level
  67. *
  68. * show_regs() implementations can use this function to print out generic
  69. * debug information.
  70. */
  71. void show_regs_print_info(const char *log_lvl)
  72. {
  73. dump_stack_print_info(log_lvl);
  74. }
  75. static void __dump_stack(const char *log_lvl)
  76. {
  77. dump_stack_print_info(log_lvl);
  78. show_stack(NULL, NULL, log_lvl);
  79. }
  80. /**
  81. * dump_stack_lvl - dump the current task information and its stack trace
  82. * @log_lvl: log level
  83. *
  84. * Architectures can override this implementation by implementing its own.
  85. */
  86. asmlinkage __visible void dump_stack_lvl(const char *log_lvl)
  87. {
  88. unsigned long flags;
  89. /*
  90. * Permit this cpu to perform nested stack dumps while serialising
  91. * against other CPUs
  92. */
  93. printk_cpu_sync_get_irqsave(flags);
  94. __dump_stack(log_lvl);
  95. printk_cpu_sync_put_irqrestore(flags);
  96. }
  97. EXPORT_SYMBOL(dump_stack_lvl);
  98. asmlinkage __visible void dump_stack(void)
  99. {
  100. dump_stack_lvl(KERN_DEFAULT);
  101. }
  102. EXPORT_SYMBOL(dump_stack);