Linux内核调用栈无偏移接口
Linux内核中调用栈不带偏移的接口
在Linux内核中,获取调用栈信息(stack trace)时,如果只需要函数地址不带偏移量(即不显示函数内部的指令偏移),可以通过以下接口实现:
核心接口
stack_trace_save()
这是最直接的接口,用于捕获当前调用栈的纯地址列表(不带偏移)。1
2
3unsigned int stack_trace_save(unsigned long *store,
unsigned int size,
unsigned int skipnr);- 参数:
store
:存储地址的数组size
:数组大小skipnr
:跳过的栈帧数(例如设为0
捕获所有帧)
- 返回值:实际保存的地址数量
- 特点:
保存的地址是调用点的返回地址(即函数内部的指令地址),不包含符号名或偏移量。
- 参数:
手动处理
struct stack_trace
通过save_stack_trace()
获取原始地址,再自行打印:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15struct stack_trace trace;
unsigned long entries[16]; // 存储地址的数组
trace.nr_entries = 0;
trace.max_entries = ARRAY_SIZE(entries);
trace.entries = entries;
trace.skip = 0; // 跳过帧数
save_stack_trace(&trace); // 捕获栈
// 打印纯地址(不带偏移)
for (int i = 0; i < trace.nr_entries; i++) {
printk("%pS\n", (void *)trace.entries[i]); // %pS 会带符号+偏移,需避免!
printk("%lx\n", trace.entries[i]); // 直接打印地址(无符号/偏移)
}
关键说明
- 不带偏移的本质:
上述接口返回的地址是原始的指令指针(Instruction Pointer)值,即函数内部的调用点地址。若需函数入口地址(无偏移),需额外使用kallsyms_lookup()
解析(但通常不需要)。 - 避免符号解析:
不要使用%pS
(会打印函数名+偏移
),而是用%lx
直接输出地址值。 - 依赖配置:
需启用内核选项:CONFIG_STACKTRACE
CONFIG_FRAME_POINTER
(或架构相关的栈展开支持)
示例代码(捕获纯地址)
1 |
|
输出示例
1 | Address: 0xffffffff810a3d12 |
其他接口(不推荐)
dump_stack()
:会带符号+偏移(通过%pB/%pS
打印),不符合需求。print_stack_trace()
:同样会解析符号和偏移。
总结:使用
stack_trace_save()
直接获取原始地址数组,或通过save_stack_trace()
+ 遍历数组 是获取无偏移调用栈的标准方法。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Helloeuler!