X86 使用gdb的计数机指令
我需要根据x86机器指令计数估计程序中某个热点的确切起始位置(以便以后可以在某些模拟器/模拟器中运行)。有没有一种方法可以使用gdb计算断点前执行的机器指令数 当然,还有其他选择,我可以使用仿真/二进制指令插入工具(如Pin),并在计算指令时跟踪运行,但这需要在我工作的每个平台上安装此工具—并非总是可能的。我需要一些几乎可以在任何linux机器上使用的工具 使用gdb,我想也可以大步运行X86 使用gdb的计数机指令,x86,gdb,trace,X86,Gdb,Trace,我需要根据x86机器指令计数估计程序中某个热点的确切起始位置(以便以后可以在某些模拟器/模拟器中运行)。有没有一种方法可以使用gdb计算断点前执行的机器指令数 当然,还有其他选择,我可以使用仿真/二进制指令插入工具(如Pin),并在计算指令时跟踪运行,但这需要在我工作的每个平台上安装此工具—并非总是可能的。我需要一些几乎可以在任何linux机器上使用的工具 使用gdb,我想也可以大步运行stepix,作为某种粗粒度搜索,直到我们到达断点,然后以降低的分辨率重复,但速度会非常慢。还有别的办法吗 试
stepix
,作为某种粗粒度搜索,直到我们到达断点,然后以降低的分辨率重复,但速度会非常慢。还有别的办法吗 试试这个:
set pagination off
set $count = 0
while $pc != 0xyourstoppingaddress
stepi
set $count++
end
print $count
然后去喝杯咖啡。或者是一顿长长的午餐。这实际上只是对Mark解决方案可用性的一点小小改进 我们可以定义一个函数
do\u 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上运行,那么您可能能够读取周期计数器,请参阅示例
在您的场景中,我将尝试获取已用指令计数(自GDB 7.0起可用,并在以后改进):
记录btrace
(或者记录完整的
,如果前者不可用)继续执行
执行(直到出现断点,或使用next
或其他命令单步执行)信息记录
记录停止
(建议使用缓冲区,因为缓冲区大小有限)- 记录缓冲区的大小有限(可通过
增加此大小。对于上述BTS格式,请参阅以了解其他类型)set record btrace pt buffer size
- 使用
,并非所有指令都能被捕获。值得注意的是,SSE和AVX指令不受支持,将导致gdb暂停执行记录完整
- 记录每条指令(尤其是完整格式的指令)时会有一些开销。尽管它不应该像其他答案中描述的gdb步骤方法那样糟糕(每次都必须通过ptrace)
ptrace
在调试器中运行程序会改变程序状态,这可能对性能至关重要(缓存状态、TLB未命中等)。在调试器中运行程序时得到的结果仅适用于这种情况。为什么要计算机器指令数?如果这是关于评测的,那么这不是一个非常有用的度量。@pentadecagon,就像我说的-我需要在模拟器中运行某个部分(例如gem5),它可以被触发以给定的指令计数开始回答不错,但是为什么要提到周期计数呢?这个问题是关于确切的指令数,IPC是可变的,这取决于许多微体系结构因素,包括来自其他内核的内存/缓存争用,因此对于相同的代码,它甚至不完全是可重复的。对于x86,这可能是真的,但如果您使用单个内核运行裸机ARM,它们将是相同的。这正是我需要解决的问题。如果您的ARM没有缓存或分支预测,可能是热的,也可能不是热的,并且没有来自DMA的可能争用,那么请确定。e、 g.Cortex-M3。但是更快的ARM CPU不一定是确定性的,因为缓存的局部性不同,不同的输入数据可能会产生不同的IPC。实际上,并非Cortex-M3上的所有指令都需要相同的周期(重新加载管道需要额外的分支成本),因此读取周期计时器仍然不能回答这里的问题。当我想等待segfault或程序中存在的任何其他信号时,如何使用它?@124312344123411234123尝试更改,而$pc!=0xyourstoppingaddress
到而$pc!=0xyourstoppingaddress&$\u siginfo.si\u signo!=11
运行循环,直到收到SIGSEGV。stepi
命令将导致程序获得SIGTRAP信号(5),因此如果您想在SIGTRAP以外的任何信号上停止,请尝试while$pc!=0xyourstoppingaddress&&$\u siginfo.si\u signo==5
当($pc!=$arg0)如此时,我们如何更改条件