debugging.rst 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. ==============================
  2. Using the tracer for debugging
  3. ==============================
  4. Copyright 2024 Google LLC.
  5. :Author: Steven Rostedt <rostedt@goodmis.org>
  6. :License: The GNU Free Documentation License, Version 1.2
  7. (dual licensed under the GPL v2)
  8. - Written for: 6.12
  9. Introduction
  10. ------------
  11. The tracing infrastructure can be very useful for debugging the Linux
  12. kernel. This document is a place to add various methods of using the tracer
  13. for debugging.
  14. First, make sure that the tracefs file system is mounted::
  15. $ sudo mount -t tracefs tracefs /sys/kernel/tracing
  16. Using trace_printk()
  17. --------------------
  18. trace_printk() is a very lightweight utility that can be used in any context
  19. inside the kernel, with the exception of "noinstr" sections. It can be used
  20. in normal, softirq, interrupt and even NMI context. The trace data is
  21. written to the tracing ring buffer in a lockless way. To make it even
  22. lighter weight, when possible, it will only record the pointer to the format
  23. string, and save the raw arguments into the buffer. The format and the
  24. arguments will be post processed when the ring buffer is read. This way the
  25. trace_printk() format conversions are not done during the hot path, where
  26. the trace is being recorded.
  27. trace_printk() is meant only for debugging, and should never be added into
  28. a subsystem of the kernel. If you need debugging traces, add trace events
  29. instead. If a trace_printk() is found in the kernel, the following will
  30. appear in the dmesg::
  31. **********************************************************
  32. ** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **
  33. ** **
  34. ** trace_printk() being used. Allocating extra memory. **
  35. ** **
  36. ** This means that this is a DEBUG kernel and it is **
  37. ** unsafe for production use. **
  38. ** **
  39. ** If you see this message and you are not debugging **
  40. ** the kernel, report this immediately to your vendor! **
  41. ** **
  42. ** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **
  43. **********************************************************
  44. Debugging kernel crashes
  45. ------------------------
  46. There is various methods of acquiring the state of the system when a kernel
  47. crash occurs. This could be from the oops message in printk, or one could
  48. use kexec/kdump. But these just show what happened at the time of the crash.
  49. It can be very useful in knowing what happened up to the point of the crash.
  50. The tracing ring buffer, by default, is a circular buffer than will
  51. overwrite older events with newer ones. When a crash happens, the content of
  52. the ring buffer will be all the events that lead up to the crash.
  53. There are several kernel command line parameters that can be used to help in
  54. this. The first is "ftrace_dump_on_oops". This will dump the tracing ring
  55. buffer when a oops occurs to the console. This can be useful if the console
  56. is being logged somewhere. If a serial console is used, it may be prudent to
  57. make sure the ring buffer is relatively small, otherwise the dumping of the
  58. ring buffer may take several minutes to hours to finish. Here's an example
  59. of the kernel command line::
  60. ftrace_dump_on_oops trace_buf_size=50K
  61. Note, the tracing buffer is made up of per CPU buffers where each of these
  62. buffers is broken up into sub-buffers that are by default PAGE_SIZE. The
  63. above trace_buf_size option above sets each of the per CPU buffers to 50K,
  64. so, on a machine with 8 CPUs, that's actually 400K total.
  65. Persistent buffers across boots
  66. -------------------------------
  67. If the system memory allows it, the tracing ring buffer can be specified at
  68. a specific location in memory. If the location is the same across boots and
  69. the memory is not modified, the tracing buffer can be retrieved from the
  70. following boot. There's two ways to reserve memory for the use of the ring
  71. buffer.
  72. The more reliable way (on x86) is to reserve memory with the "memmap" kernel
  73. command line option and then use that memory for the trace_instance. This
  74. requires a bit of knowledge of the physical memory layout of the system. The
  75. advantage of using this method, is that the memory for the ring buffer will
  76. always be the same::
  77. memmap==12M$0x284500000 trace_instance=boot_map@0x284500000:12M
  78. The memmap above reserves 12 megabytes of memory at the physical memory
  79. location 0x284500000. Then the trace_instance option will create a trace
  80. instance "boot_map" at that same location with the same amount of memory
  81. reserved. As the ring buffer is broke up into per CPU buffers, the 12
  82. megabytes will be broken up evenly between those CPUs. If you have 8 CPUs,
  83. each per CPU ring buffer will be 1.5 megabytes in size. Note, that also
  84. includes meta data, so the amount of memory actually used by the ring buffer
  85. will be slightly smaller.
  86. Another more generic but less robust way to allocate a ring buffer mapping
  87. at boot is with the "reserve_mem" option::
  88. reserve_mem=12M:4096:trace trace_instance=boot_map@trace
  89. The reserve_mem option above will find 12 megabytes that are available at
  90. boot up, and align it by 4096 bytes. It will label this memory as "trace"
  91. that can be used by later command line options.
  92. The trace_instance option creates a "boot_map" instance and will use the
  93. memory reserved by reserve_mem that was labeled as "trace". This method is
  94. more generic but may not be as reliable. Due to KASLR, the memory reserved
  95. by reserve_mem may not be located at the same location. If this happens,
  96. then the ring buffer will not be from the previous boot and will be reset.
  97. Sometimes, by using a larger alignment, it can keep KASLR from moving things
  98. around in such a way that it will move the location of the reserve_mem. By
  99. using a larger alignment, you may find better that the buffer is more
  100. consistent to where it is placed::
  101. reserve_mem=12M:0x2000000:trace trace_instance=boot_map@trace
  102. On boot up, the memory reserved for the ring buffer is validated. It will go
  103. through a series of tests to make sure that the ring buffer contains valid
  104. data. If it is, it will then set it up to be available to read from the
  105. instance. If it fails any of the tests, it will clear the entire ring buffer
  106. and initialize it as new.
  107. The layout of this mapped memory may not be consistent from kernel to
  108. kernel, so only the same kernel is guaranteed to work if the mapping is
  109. preserved. Switching to a different kernel version may find a different
  110. layout and mark the buffer as invalid.
  111. Using trace_printk() in the boot instance
  112. -----------------------------------------
  113. By default, the content of trace_printk() goes into the top level tracing
  114. instance. But this instance is never preserved across boots. To have the
  115. trace_printk() content, and some other internal tracing go to the preserved
  116. buffer (like dump stacks), either set the instance to be the trace_printk()
  117. destination from the kernel command line, or set it after boot up via the
  118. trace_printk_dest option.
  119. After boot up::
  120. echo 1 > /sys/kernel/tracing/instances/boot_map/options/trace_printk_dest
  121. From the kernel command line::
  122. reserve_mem=12M:4096:trace trace_instance=boot_map^traceprintk^traceoff@trace
  123. If setting it from the kernel command line, it is recommended to also
  124. disable tracing with the "traceoff" flag, and enable tracing after boot up.
  125. Otherwise the trace from the most recent boot will be mixed with the trace
  126. from the previous boot, and may make it confusing to read.