Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dynamic_debug: add support for print stack

In practical problem diagnosis, especially during the boot phase, it is
often desirable to know the call sequence. However, currently, apart from
adding print statements and recompiling the kernel, there seems to be no
good alternative. If dynamic_debug supported printing the call stack, it
would be very helpful for diagnosing issues. This patch add support '+d'
for dump stack.

Link: https://lkml.kernel.org/r/20251025080003.312536-1-yebin@huaweicloud.com
Signed-off-by: Ye Bin <yebin10@huawei.com>
Cc: Jason Baron <jbaron@akamai.com>
Cc: Jim Cromie <jim.cromie@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Ye Bin and committed by
Andrew Morton
6c2e6e2c a2b1c419

+18 -5
+3 -2
Documentation/admin-guide/dynamic-debug-howto.rst
··· 223 223 f Include the function name 224 224 s Include the source file name 225 225 l Include line number 226 + d Include call trace 226 227 227 228 For ``print_hex_dump_debug()`` and ``print_hex_dump_bytes()``, only 228 229 the ``p`` flag has meaning, other flags are ignored. 229 230 230 - Note the regexp ``^[-+=][fslmpt_]+$`` matches a flags specification. 231 - To clear all flags at once, use ``=_`` or ``-fslmpt``. 231 + Note the regexp ``^[-+=][fslmptd_]+$`` matches a flags specification. 232 + To clear all flags at once, use ``=_`` or ``-fslmptd``. 232 233 233 234 234 235 Debug messages during Boot Process
+14 -3
include/linux/dynamic_debug.h
··· 38 38 #define _DPRINTK_FLAGS_INCL_LINENO (1<<3) 39 39 #define _DPRINTK_FLAGS_INCL_TID (1<<4) 40 40 #define _DPRINTK_FLAGS_INCL_SOURCENAME (1<<5) 41 + #define _DPRINTK_FLAGS_INCL_STACK (1<<6) 41 42 42 43 #define _DPRINTK_FLAGS_INCL_ANY \ 43 44 (_DPRINTK_FLAGS_INCL_MODNAME | _DPRINTK_FLAGS_INCL_FUNCNAME |\ 44 45 _DPRINTK_FLAGS_INCL_LINENO | _DPRINTK_FLAGS_INCL_TID |\ 45 - _DPRINTK_FLAGS_INCL_SOURCENAME) 46 + _DPRINTK_FLAGS_INCL_SOURCENAME | _DPRINTK_FLAGS_INCL_STACK) 46 47 47 48 #if defined DEBUG 48 49 #define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINT ··· 161 160 const struct ib_device *ibdev, 162 161 const char *fmt, ...); 163 162 163 + #define __dynamic_dump_stack(desc) \ 164 + { \ 165 + if (desc.flags & _DPRINTK_FLAGS_INCL_STACK) \ 166 + dump_stack(); \ 167 + } 168 + 164 169 #define DEFINE_DYNAMIC_DEBUG_METADATA_CLS(name, cls, fmt) \ 165 170 static struct _ddebug __aligned(8) \ 166 171 __section("__dyndbg") name = { \ ··· 227 220 */ 228 221 #define __dynamic_func_call_cls(id, cls, fmt, func, ...) do { \ 229 222 DEFINE_DYNAMIC_DEBUG_METADATA_CLS(id, cls, fmt); \ 230 - if (DYNAMIC_DEBUG_BRANCH(id)) \ 223 + if (DYNAMIC_DEBUG_BRANCH(id)) { \ 231 224 func(&id, ##__VA_ARGS__); \ 225 + __dynamic_dump_stack(id); \ 226 + } \ 232 227 } while (0) 233 228 #define __dynamic_func_call(id, fmt, func, ...) \ 234 229 __dynamic_func_call_cls(id, _DPRINTK_CLASS_DFLT, fmt, \ ··· 238 229 239 230 #define __dynamic_func_call_cls_no_desc(id, cls, fmt, func, ...) do { \ 240 231 DEFINE_DYNAMIC_DEBUG_METADATA_CLS(id, cls, fmt); \ 241 - if (DYNAMIC_DEBUG_BRANCH(id)) \ 232 + if (DYNAMIC_DEBUG_BRANCH(id)) { \ 242 233 func(__VA_ARGS__); \ 234 + __dynamic_dump_stack(id); \ 235 + } \ 243 236 } while (0) 244 237 #define __dynamic_func_call_no_desc(id, fmt, func, ...) \ 245 238 __dynamic_func_call_cls_no_desc(id, _DPRINTK_CLASS_DFLT, \
+1
lib/dynamic_debug.c
··· 95 95 { _DPRINTK_FLAGS_INCL_SOURCENAME, 's' }, 96 96 { _DPRINTK_FLAGS_INCL_LINENO, 'l' }, 97 97 { _DPRINTK_FLAGS_INCL_TID, 't' }, 98 + { _DPRINTK_FLAGS_INCL_STACK, 'd' }, 98 99 { _DPRINTK_FLAGS_NONE, '_' }, 99 100 }; 100 101