简体   繁体   中英

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. 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. 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.

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.

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.

More complicated algorithms are possible with the use of embedded Python.

In the .gdbinit file in your home folder add

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).

In this .gdbinit file, add the code below

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.

  • You can set breakpoints with b filename.ext:line_number or b function_name
  • You can use commands breakpoint_number (see here ) and then list commands that should be run after this breakpoint is hit. Use end to finish the commands
    • 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)
  • You can use convenience variables to store useful things such as the address of an important object
  • The python api is very powerful

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).

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.

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.

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 .

In the case you want to use python for more power it is worth reading the section about it in the manual. Let-me give you one example. Suppose one of your global variables was stored in a convenience variable called "$myvar". Then you can pass it to the python interpreter with

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

You can also pass any variable in the current scope to parse_and_eval . Now, suppose this global variable stores an object of a class with a "n_elem" attribute you want to check. You can print it with

python print(myvar["n_elem"])

You can also create a python file in the same folder and use

python from my_python_file import *

to import functions defined there.

With these gdb features you can pretty much automate whatever you might need.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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