我正在研究testbench环境,我需要在调用pli例程的rtl模拟期间调试分段错误。此pli例程在.so
文件中定义routines.so
,该文件链接到vcs编译设计和测试平台环境后生成的模拟可执行文件。我说模拟器可执行文件名为simv
。假设我要在C side
处断开的函数是badfunction()
,这在verilog端被称为$badfunction()
。我已经使用调试支持编译了routines.so
。
我已将gdb附加到运行我的模拟的vcs simv
模拟器可执行文件中,我确实看到routines.so
已加载并从中读取符号。我通过运行info shared
来检查这一点。
现在我查找符号badfunction
,就像这样info address badfunction
。我收到这样的消息。
Symbol "badfunction" is at 0x156bea0 in a file compiled without debugging
这让我觉得把断点放在badfunction
可能不会让我纠正错误。所以我检查它引用的badfunction
info symbol 0x156bea0
。这给了我badfunction in section .text of /home/simulations/rtl/build/simv
的消息。所以它指的是badfunction
中的simv
。
我需要确保将断点放在正确的位置,因为模拟需要大约10个小时才能达到故障点。如何将断点放在badfunction
的{{1}}处?
函数名routines.so
未受损。我可以在拆解时看到符号badfunction
。我如何告诉gdb在routines.so
中查找该函数?
答案 0 :(得分:0)
从gdb 7.4开始,为响应break function
,gdb将在所有匹配的函数中设置断点。所以,break badfunction
应该做你想做的事。
但是,由于到达您想调试的地点需要10个小时,因此您可以先做几件事来确保正确的事情发生。
首先,确保你的.so有debuginfo。最可靠的方法是使用objdump
或readelf
直接检查将要加载的.so(即,如果已安装在某处,请检查已安装的副本,而不是开发副本)。我通常只做readelf -wi whatever.so
;如果它转储了很多东西,那么你有debuginfo。
接下来,您可以检查以验证是否正确设置了断点。如果.so链接到可执行文件,那么这很容易:
$ gdb whatever
(gdb) break badfunction
(gdb) start
此时,所有已链接的共享库都已加载,您可以执行此操作:
(gdb) info break
...并检查由此产生的断点以获得理智。我想,根据你上面所说的,badfunction
应设置两个位置。
如果.so没有链接到生成的可执行文件(听起来那样但我真的不知道),那么它有点复杂了。一种方法是执行catch load
,然后continue
,直到到达加载所需库的位置,并在gdb中重新解析断点。然后按上面的方法检查它们。