c++ - 使用 --call-stack fp 的 perf 记录无法展开主函数
问题描述
我有一个 C++ 测试程序让 CPU 保持忙碌:
#include <cstdint>
#include <iostream>
// Linear-feedback shift register
uint64_t lfsr1(uint64_t max_ix)
{
uint64_t start_state = 0xACE1u; /* Any nonzero start state will work. */
uint64_t lfsr = start_state;
uint64_t bit; /* Must be 16-bit to allow bit<<15 later in the code */
for (uint64_t ix = 0; ix < max_ix; ++ix)
{ /* taps: 16 14 13 11; feedback polynomial: x^16 + x^14 + x^13 + x^11 + 1 */
bit = ((lfsr >> 0) ^ (lfsr >> 1) ^ (lfsr >> 3) ^ (lfsr >> 4)) & 1 /* & 1u */;
lfsr = (lfsr >> 1) | (bit << 15);
}
return lfsr;
}
int main() {
std::cout << lfsr1(1717986914ull) << "\n";
}
我用 编译它,然后用和g++ -g -O3 -fno-omit-frame-pointer cpu.cpp -o cpu.bin
运行它,而不是用.perf record -F 100 --call-graph fp -- ./cpu.bin
dwarf
fp
在perf script
输出中fp
,我可以看到
cpu.bin 23435 1535437.021156: 42706947 cycles:
5617daf4b7a1 main+0x31 (…/cpu.bin)
7f9a95088bf7 __libc_start_main+0xe7 (/lib/x86_64-linux-gnu/libc-2.27.so)
3fe258d4c544155 [unknown] ([unknown])
而对于dwarf
,它是
cpu.bin 23443 1535441.101859: 42952079 cycles:
55a3b4ffd7a1 lfsr1+0x31 (inlined)
55a3b4ffd7a1 main+0x31 (…/cpu.bin)
7f00bcc8ebf6 __libc_start_main+0xe6 (/lib/x86_64-linux-gnu/libc-2.27.so)
55a3b4ffd829 _start+0x29 (…/cpu.bin)
似乎可能fp
是一个字节的关闭,__libc_start_main
这导致它错过了最后一个展开步骤。如何解决这个问题?
解决方案
就像 Peter 在他的评论中所说的那样,当使用带有帧指针的 glibc 版本时,问题就会自行解决。在 Ubuntu 20.04 上,有一个带有这样一个 glibc 的包。
sudo apt install libc6-prof
# To use this library:
env LD_LIBRARY_PATH=/lib/libc6-prof/x86_64-linux-gnu perf record …
然后,按预期[unknown]
解决。_start
来源:https ://bugs.launchpad.net/ubuntu/+source/glibc/+bug/1908307
推荐阅读
- javascript - 如何在放大时平移背景图像?
- python - 创建混淆矩阵
- python - Python argparse:当需要位置参数时如何包含“-v/--version”参数?
- vb.net - 声明一个图片框数组
- ios - iOS touchesMoved 仅由 UIButton 转发一次
- java - Spring Cloud Contracts 使用提供者状态
- svelte - 如何使用 Svelte 中的每个块打印对象键和值?
- r - 按组显示的反应性GGplot箱线图问题
- abap - ABAP SQ01 生成报告中的错误(选择屏幕太大) 消息编号 AQ366
- vba - 如何插入在 Access 中链接在一起的两个不同表中