dump_stack.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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 UID: %u PID: %d Comm: %.20s %s%s %s %.*s %s " BUILD_ID_FMT "\n",
  52. log_lvl, raw_smp_processor_id(),
  53. __kuid_val(current_real_cred()->euid),
  54. current->pid, current->comm,
  55. kexec_crash_loaded() ? "Kdump: loaded " : "",
  56. print_tainted(),
  57. init_utsname()->release,
  58. (int)strcspn(init_utsname()->version, " "),
  59. init_utsname()->version, preempt_model_str(), BUILD_ID_VAL);
  60. if (get_taint())
  61. printk("%s%s\n", log_lvl, print_tainted_verbose());
  62. if (dump_stack_arch_desc_str[0] != '\0')
  63. printk("%sHardware name: %s\n",
  64. log_lvl, dump_stack_arch_desc_str);
  65. print_worker_info(log_lvl, current);
  66. print_stop_info(log_lvl, current);
  67. print_scx_info(log_lvl, current);
  68. }
  69. /**
  70. * show_regs_print_info - print generic debug info for show_regs()
  71. * @log_lvl: log level
  72. *
  73. * show_regs() implementations can use this function to print out generic
  74. * debug information.
  75. */
  76. void show_regs_print_info(const char *log_lvl)
  77. {
  78. dump_stack_print_info(log_lvl);
  79. }
  80. static void __dump_stack(const char *log_lvl)
  81. {
  82. dump_stack_print_info(log_lvl);
  83. show_stack(NULL, NULL, log_lvl);
  84. }
  85. /**
  86. * dump_stack_lvl - dump the current task information and its stack trace
  87. * @log_lvl: log level
  88. *
  89. * Architectures can override this implementation by implementing its own.
  90. */
  91. asmlinkage __visible void dump_stack_lvl(const char *log_lvl)
  92. {
  93. bool in_panic = panic_on_this_cpu();
  94. unsigned long flags;
  95. /*
  96. * Permit this cpu to perform nested stack dumps while serialising
  97. * against other CPUs, unless this CPU is in panic.
  98. *
  99. * When in panic, non-panic CPUs are not permitted to store new
  100. * printk messages so there is no need to synchronize the output.
  101. * This avoids potential deadlock in panic() if another CPU is
  102. * holding and unable to release the printk_cpu_sync.
  103. */
  104. if (!in_panic)
  105. printk_cpu_sync_get_irqsave(flags);
  106. __dump_stack(log_lvl);
  107. if (!in_panic)
  108. printk_cpu_sync_put_irqrestore(flags);
  109. }
  110. EXPORT_SYMBOL(dump_stack_lvl);
  111. asmlinkage __visible void dump_stack(void)
  112. {
  113. dump_stack_lvl(KERN_DEFAULT);
  114. }
  115. EXPORT_SYMBOL(dump_stack);