简体   繁体   English

用gdb自动调试

[英]automatic debugging with gdb

I am dealing with a large code base with tons of globals.我正在处理一个包含大量全局变量的大型代码库。 Under some peculiar set of data it produces the wrong result.在某些特殊的数据集下,它会产生错误的结果。 I wanted to automatically run few scenarios with gdb in automatic step-by-step execution and periodical dumping of some values and recording the tracing in some file.我想用 gdb 自动运行几个场景,自动逐步执行和定期转储一些值并在一些文件中记录跟踪。 Doing it manually will ruin my sight and my brain.手动操作会毁了我的视力和大脑。 I speculate that there is some globals mess-up.我推测有一些全局混乱。 How to do this automatically?如何自动执行此操作? Use some scripting.使用一些脚本。 All this is in RH linux.所有这些都在 RH linux 中。 Thanks in advance.提前致谢。

tried to do this manually using conditional breaks, but gave up after a while尝试使用条件中断手动执行此操作,但一段时间后放弃了

I wanted to automatically run few scenarios with gdb in automatic step-by-step execution and periodical dumping of some values and recording the tracing in some file.我想用 gdb 自动运行几个场景,自动逐步执行和定期转储一些值并在一些文件中记录跟踪。

It may be significantly more effective to run the program under reverse debugger (such as rr ), and trace the wrong result back to its source.在反向调试器(例如rr )下运行程序可能会更有效,并将错误的结果追溯到其源。

How to do this automatically?如何自动执行此操作?

You can't do automatically what you can't express as an algorithm, and you haven't described an algorithm you want to use.你不能自动地做你不能用算法表达的事情,你还没有描述你想要使用的算法。 If it's something like "stop every 100 times foo is called and print the values of these 500 globals", than that's trivially automatable with GDB.如果它类似于“每调用 100 次foo就停止并打印这 500 个全局变量的值”,那么使用 GDB 可以轻松实现自动化。

More complicated algorithms are possible with the use of embedded Python.使用嵌入式 Python 可以实现更复杂的算法。

In the .gdbinit file in your home folder add在主文件夹中的.gdbinit文件中添加

add-auto-load-safe-path /path_to_the_folder_containing_your_executable/

Now you can create another .gdbinit file in the same folder where your executable is that will be loaded when you start gdb from there (the .gdbinit file in your home that is also read - useful if you have nice stuff there such as loading pretty printers).现在,您可以在您的可执行文件所在的同一文件夹中创建另一个.gdbinit文件,当您从那里启动 gdb 时将加载该文件(您家中的.gdbinit文件也已读取 - 如果您有不错的东西,例如加载漂亮的打印机)。

In this .gdbinit file, add the code below在这个.gdbinit文件中,添加以下代码

file your_executable_name
start

# Optional
set args "<any command line parameters you program might need>"

# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Add gdb commands below to set breakpoints, print variable values, etc

# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

run

Gdb is very powerful and I'll list a few things that might help this automation. Gdb 非常强大,我将列出一些可能有助于实现自动化的东西。

  • You can set breakpoints with b filename.ext:line_number or b function_name您可以使用b filename.ext:line_numberb function_name设置断点
  • You can use commands breakpoint_number (see here ) and then list commands that should be run after this breakpoint is hit.您可以使用commands breakpoint_number (请参见此处),然后列出在命中此断点后应运行的命令。 Use end to finish the commands使用end完成命令
    • You know the breakpoint number, since they are created sequencially (note that the start will count as a breakpoint and thus the first one you add will be breakpoint 2)您知道断点编号,因为它们是按顺序创建的(请注意, start将计为断点,因此您添加的第一个断点将是断点 2)
  • You can use convenience variables to store useful things such as the address of an important object您可以使用便利变量来存储有用的东西,例如重要的 object 的地址
  • The python api is very powerful python api非常强大

One idea is that you can save the address of the important global variables (if they are not always accessible) using convenience variables.一种想法是,您可以使用便利变量保存重要的全局变量的地址(如果它们不总是可访问的)。 For instance, add a breakpoint where this global variable is and then add to this breakpoint the command to save the address of this variable to a convenience variable followed by continue (with continue you will not see gdb stopping there).例如,在此全局变量所在的位置添加一个断点,然后在此断点中添加命令以将此变量的地址保存到一个便利变量,然后再continue (使用continue您将不会看到 gdb 停在那里)。

set $var1 = &myglobal
continue

You might want to also delete this breakpoint with delete breakpoint_number before continue to avoid stopping at this breakpoint again.您可能还想在continue避免再次在此断点处停止之前使用delete breakpoint_number删除此断点。

Then as long is the object exists you can inspect it using p $var1 or p $var1->something when the program is stopped at a different breakpoint where myglobal might not be directly accessible.然后只要 object 存在,当程序在myglobal可能无法直接访问的不同断点处停止时,您可以使用p $var1p $var1->something检查它。

In the commands that you add to be run when a breakpoint is hit you can do things such as echo message explaining where you are , p some_var to see the values of variables or even python some_complicated_python_code .在遇到断点时添加的命令中,您可以执行诸如echo message explaining where you arep some_var以查看变量值甚至python some_complicated_python_code的操作。

In the case you want to use python for more power it is worth reading the section about it in the manual.如果您想使用 python 获得更多功率,则值得阅读手册中有关它的部分 Let-me give you one example.让我举一个例子。 Suppose one of your global variables was stored in a convenience variable called "$myvar".假设您的一个全局变量存储在一个名为“$myvar”的便利变量中。 Then you can pass it to the python interpreter with然后你可以将它传递给 python 解释器

python myvar = gdb.parse_and_eval("$myvar")

You can also pass any variable in the current scope to parse_and_eval .您还可以将当前 scope 中的任何变量传递给parse_and_eval Now, suppose this global variable stores an object of a class with a "n_elem" attribute you want to check.现在,假设这个全局变量存储一个 class 的 object,您要检查一个“n_elem”属性。 You can print it with你可以打印它

python print(myvar["n_elem"])

You can also create a python file in the same folder and use您还可以在同一文件夹中创建 python 文件并使用

python from my_python_file import *

to import functions defined there.导入那里定义的函数。

With these gdb features you can pretty much automate whatever you might need.借助这些 gdb 功能,您几乎可以自动化您可能需要的任何内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM