我需要根据x86机器指令数来估计程序中某些热点的确切起始位置(以便稍后可以在某个仿真器/模拟器中运行).有没有办法使用gdb来计算执行到断点的机器指令的数量?
当然还有其他选择,我可以使用仿真/二进制检测工具(如Pin),并在计算指令时跟踪运行,但这需要在我工作的每个平台上安装此工具 - 并非总是可行.我需要一些可以在任何Linux机器上使用的工具.
用GDB,我想它也可以运行stepi X,直到我们遇到断点过大的进步是某种粗粒搜索,然后降低分辨率重复,但是这将是极为缓慢.还有另一种方法吗?
Mar*_*ick 17
试试这个:
set pagination off
set $count=0
while ($pc != 0xyourstoppingaddress)
stepi
set $count++
end
print $count
然后去喝杯咖啡.或者是一顿长长的午餐
这实际上只是对 Mark 解决方案可用性的一点点改进。
我们可以定义一个函数do_count:
define do_count
set $count=0
while ($pc != $arg0)
stepi
set $count=$count+1
end
print $count
end
然后可以重复使用此函数来一遍又一遍地计算步数:
set pagination off
do_count 0xaddress1
do_count 0xaddress2
甚至可以将此定义放入.gdbinit(在 Linux 上,在 Windows 上应调用gdb.ini)的主文件夹中,因此在 gdb 启动后它会自动变为可用(用于show user查看函数是否已加载)。
如果您确实想要一个周期计数(可能是已知 IPC 的指令计数的近似值),并且您在裸机 ARM 上运行,您可能能够读取周期计数器,例如参见ARM Cortex M4 上的周期计数器(或M3)?
在您的场景中,我会尝试Process Record 和 Replay来获取已用指令计数(自 GDB 7.0 起可用,之后改进):
record btrace或者record full如果前者不可用)。continue执行(直到出现断点,或使用next或其他命令单步执行)。info recordrecord stop推荐使用,因为缓冲区大小有限)。例子:
(gdb)记录 btrace (gdb) 框架 #0 __sanitizer::InitTlsSize () 在 .../lib/sanitizer_common/sanitizer_linux_libcdep.cc:220 第 220 章 (gdb)信息记录 活动记录目标:record-btrace 录音格式:Branch Trace Store。 缓冲区大小:64kB。在线程 1(线程 0xf7c92300 (LWP 20579))的 0 个函数(0 个间隙)中 记录了0 条指令。 (gdb) 下一个 226 ... (gdb)信息记录 活动记录目标:record-btrace 录音格式:Branch Trace Store。 缓冲区大小:64kB。在线程 1(线程 0xf7c92300 (LWP 20579))的 145 个函数(0 个间隙)中 记录了2859 条指令。
限制:
set record btrace pt buffer-size <size>对于上面的 BTS 格式,可以增加,请参阅其他类型的文档)。record full,并非所有指令都可以捕获。值得注意的是,SSE 和 AVX 指令不受支持,会导致 gdb 暂停执行。| 归档时间: | 
 | 
| 查看次数: | 2807 次 | 
| 最近记录: |