You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

perf报告中C++虚函数callq汇编指令显示异常的原因

perf反汇编虚函数调用显示异常的原因

该显示差异是perf 4.15版本内置反汇编器的已知实现缺陷,与C++虚函数调用逻辑、程序编译结果无关。

核心原理

x86-64架构下,通过vtable调用虚函数的指令属于内存间接调用,对应的AT&T语法格式为callq *offset(%base_reg),机器码固定组成为:

  • 1字节操作码:0xFF
  • 1字节ModR/M寻址描述字节:标记基址寄存器、寻址模式
  • 1/4字节偏移量:对应目标虚函数在vtable中的条目偏移

perf 4.15版本的内置反汇编逻辑在解析这类0xFF操作码组的间接调用指令时,存在字段解析遗漏:没有正确输出ModR/M字节描述的基址寄存器信息,仅提取了指令末尾的偏移量字段直接打印,最终输出callq *38、callq *10这类不符合AT&T汇编语法的结果,很容易被误判为直接调用绝对地址的指令。

对应关系验证

直接对比两边的机器码即可确认对应关系:

  • 第一组案例中,异常显示的callq *38对应objdump输出的callq *0x38(%rax):
    该指令机器码为ff 50 38,其中50是ModR/M字节,指定基址寄存器为rax、偏移为0x38,perf仅打印了偏移值0x38(十进制38),漏掉了基址寄存器(%rax)部分。
  • 可复现测试用例中,异常显示的callq *10对应objdump输出的callq *0x10(%rdx):
    该指令机器码为ff 52 10,其中52是ModR/M字节,指定基址寄存器为rdx、偏移为0x10,perf仅打印了偏移值0x10(十进制10),漏掉了基址寄存器(%rdx)部分。

修复方式

该反汇编打印缺陷在perf 4.19及之后版本中已被修复,升级perf版本后,反汇编输出会与objdump保持一致,正确显示完整的间接寻址操作数,不会再出现仅打印偏移的异常显示。


内容的提问来源于stack exchange,提问作者konchy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 12:19:50