I am trying to automate a GDB Debugging session, I want to know whether is there any command or any other way in GDB which will help me know whether a program is running or stopped ?
Use gdb.selected_inferior().threads()[0].is_running() from the GDB Python API:
$ gdb -q /bin/true
(gdb) python from __future__ import print_function
(gdb) python print([ t.is_running() for t in gdb.selected_inferior().threads() ])
[True]
References
GDB Python API: Threads, Inferiors
I added a new command into gdb to know whether the program is running or stopped.
if(is_running (inferior_ptid))
{
fprintf_filtered (gdb_stdout, "running\n");
}
else
{
fprintf_filtered (gdb_stdout, "stopped\n");
}
Related
When running my program, I am getting Gtk-CRITICAL error on the Terminal, which I'd like to fix.
I found this link through Google, but turns out there is no such option in gdb:
igor#IgorReinCloud ~/dbhandler/Debug/dbhandler $ gdb --g-fatal-warnings dbhandler
gdb: unrecognized option '--g-fatal-warnings'
Use `gdb --help' for a complete list of options.
I also tried to set a breakpoint on the g_log() function, but the execution didn't stop there.
What am I missing?
Thank you.
you can use G_DEBUG=fatal-criticals, so that the application execution breaks at the first location where a critical is emitted.
To run inside gdb, run G_DEBUG=fatal-criticals gdb my-app, and as usual, do run inside gdb to run your application.
You may also set the G_DEBUG environment variable with export (if in bash). Thus you could do export G_DEBUG=fatal-criticals, and then run your app as gdb my-app, which will have the same effect.
See https://docs.gtk.org/glib/running.html for more details
What am I missing?
Looks like that after reading the link, you were confused that gdb should have --g-fatal-warnings option for debugging Gtk applications. This is not the case because gdb is not Gtk application, but your program is. So you should run your program with --g-fatal-warnings option inside gdb like this:
gdb --args dbhandler --g-fatal-warnings
See also related question How do I run a program with commandline args using gdb within a bash script?.
I want to write a script that will read a process memory, and display its contents with some modification/format.
It would be create if i could run a c program inside gdb and send gdb commands from this program. Do you know if it is possible ?
It would be great if i could run a c program inside gdb and send gdb commands from this program.
That's easy:
(gdb) shell /tmp/a.out > /tmp/gdb.script
(gdb) source /tmp/gdb.script
If your gdb is built with Python support, much better scripting support is available. Start here.
I seem to have some kind of multithreading bug in my code that makes it crash once every 30 runs of its test suite. The test suite is non-interactive. I want to run my test suite in gdb, and have gdb exit normally if the program exits normally, or break (and show a debugging prompt) if it crashes. This way I can let the test suite run repeatedly, go grab a cup of coffee, come back, and be presented with a nice debugging prompt. How can I do this with gdb?
This is a little hacky but you could do:
gdb -ex='set confirm on' -ex=run -ex=quit --args ./a.out
If a.out terminates normally, it will just drop you out of GDB. But if you crash, the program will still be active, so GDB will typically prompt if you really want to quit with an active inferior:
Program received signal SIGABRT, Aborted.
0x00007ffff72dad05 in raise (sig=...) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
64 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
in ../nptl/sysdeps/unix/sysv/linux/raise.c
A debugging session is active.
Inferior 1 [process 15126] will be killed.
Quit anyway? (y or n)
Like I said, not pretty, but it works, as long as you haven't toggled off the prompt to quit with an active process. There is probably a way to use gdb's quit command too: it takes a numeric argument which is the exit code for the debugging session. So maybe you can use --eval-command="quit stuff", where stuff is some GDB expression that reflects whether the inferior is running or not.
This program can be used to test it out:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
if (time(NULL) % 2) {
raise(SIGINT);
}
puts("no crash");
return EXIT_SUCCESS;
}
You can also trigger a backtrace when the program crashes and let gdb exit with the return code of the child process:
gdb -return-child-result -ex run -ex "thread apply all bt" -ex "quit" --args myProgram -myProgramArg
The easiest way is to use the Python API offered by gdb:
def exit_handler(event):
gdb.execute("quit")
gdb.events.exited.connect(exit_handler)
You can even do it with one line:
(gdb) python gdb.events.exited.connect(lambda x : gdb.execute("quit"))
You can also examine the return code to ensure it's the "normal" code you expected with event.exit_code.
You can use it in conjuction with --eval-command or --command as mentioned by #acm to register the event handler from the command line, or with a .gdbinit file.
Create a file named .gdbinit and it will be used when gdb is launched.
run
quit
Run with no options:
gdb --args prog arg1...
You are telling gdb to run and quit, but it should stop processing the file if an error occurs.
Make it dump core when it crashes. If you're on linux, read the man core man page and also the ulimit builtin if you're running bash.
This way when it crashes you'll find a nice corefile that you can feed to gdb:
$ ulimit -c unlimited
$ ... run program ..., gopher coffee (or reddit ;)
$ gdb progname corefile
If you put the following lines in your ~/.gdbinit file, gdb will exit when your program exits with a status code of 0.
python
def exit_handler ( event ):
if event .exit_code == 0:
gdb .execute ( "quit" )
gdb .events .exited .connect ( exit_handler )
end
The above is a refinement of Kevin's answer.
Are you not getting a core file when it crashes? Start gdb like this 'gdb -c core' and do a stack traceback.
More likely you will want to be using Valgrind.
I have a program using LD_PRELOAD. The program should be run like
this, "LD_PRELOAD=/path/to/libfoo.so qemu -U LD_PRELOAD a.out", if
without gdb.
Here are what I did while running gdb.
(gdb) set environment LD_PRELOAD=/nfs_home/chenwj/tools/lib/libdbo.so
(gdb) file /nfs_home/chenwj/tools/bin/qemu-i386
(gdb) r -U LD_PRELOAD bzip2_base.i386-m32-gcc44-annotated input.source 1
But gdb gave me the error below
Starting program: /nfs_home/chenwj/tools/bin/qemu-i386 -U LD_PRELOAD bzip2_base.i386-m32-gcc44-annotated input.source 1
bash: open "/bin/bash" failed: Permission denied
During startup program exited with code 66.
Any sugguestion appreciated.
Regards, chenwj
GDB does not invoke your executable directly. Instead, it does
bash -c '/nfs_home/chenwj/tools/bin/qemu-i386 -U LD_PRELOAD bzip2_base.i386-m32-gcc44-annotated input.source 1'
This is done so that bash takes care of I/O redirection (which you are not using).
My guess is that /bin/bash doesn't work when LD_PRELOAD=libdbo.so is in effect, though I don't understand the exact nature of failure.
One way to work around this problem is to create a wrapper executable, implementing C equivalent of this:
export LD_PRELOAD=/nfs_home/chenwj/tools/lib/libdbo.so
exec /nfs_home/chenwj/tools/bin/qemu-i386 "$#"
and debug that executable (without setting LD_PRELOAD). You'll see an extra SIGTRAP when the wrapper execve()s the wrapped qemu-i386, which you should ignore and continue.
I'm trying to create a little unit test with gdb,
for a embedded mcu that is controlled by OpenOCD (that gives me control over my target via a gdb server).
So I would like to automate this with some scripting of gdb.
I would like to write some kind of script for gdb that more or less does this:
Add a couple of breakpoints
Start the program
When we stop, where did it stop (get the frame info)
Quit.
Any ideas?
A example on how to do this in python gdb scripting would be nice.
Thanks
Johan
Note:
Let's say that we have this basic structure,
that more or less goes into test_failed() or test_success()
depending on what the function start_test() returns.
void test_failed() {
while(1);
}
void test_success() {
while(1);
}
int main(void) {
int status = start_test();
if( status > 0 ) {
test_failed();
}
test_success();
while(1);
}
To do this manually in gdb is very strait forward,
(gdb) break test_success
Breakpoint 1 at 0x20: file src/main.c, line 9.
(gdb) break test_failed
Breakpoint 2 at 0x18: file src/main.c, line 5.
(gdb) cont
Continuing.
Breakpoint 1, test_success () at src/main.c:9
9 while(1);
(gdb) frame
#0 test_success () at src/main.c:9
9 while(1);
(gdb)
So the next step I tried was to add those gdb commands into a gdb startup script that more or less just looked like this.
break test_success
break test_failed
target remote localhost:3333
cont
frame
and start it with
arm-none-eabi-gdb --batch --command=commands.gdb main.elf
And this kind of works, but it is not very nice.
How do I do this with the "new and cool" python scripts,
that gdb seem to support.
FYI recent gdb versions are scriptable in Python. You can call python code from the gdb command line. This opens a whole new world, check the relevant documentation. From the command line run:
dnf/yum/apt-get install gdb-doc
info gdb extending python
If you do not like the text-based info browser, here is one (among many?) alternative, graphical browser:
yelp 'info:gdb' # , go to "Extending"
Here is a sample gdb-python script. It attaches gdb to the first "your_program" found running.
#!/usr/bin/python
import subprocess
import string
def backquotes(cmdwords):
output = subprocess.Popen(cmdwords, stdout=subprocess.PIPE).communicate()[0]
return output.strip()
pid = backquotes(['pgrep', 'your_program'])
gdb.execute("attach " + str(pid))
A reduced example that I'm currently using:
class DebugPrintingBreakpoint(gdb.Breakpoint):
debugging_IDs = frozenset({37, 153, 420})
def stop(self):
top = gdb.newest_frame()
someVector = top.read_var('aVectorVar')
# Access the begin() & end() pointer of std::vector in GNU Standard C++ lib
first = someVector['_M_impl']['_M_start']
last = someVector['_M_impl']['_M_finish']
values = []
while first != last:
values.append(int(first.dereference()['intID']))
first = first + 1
if not set(values) & debugging_IDs:
return False # skip: none of the items we're looking for can be found by ID in the vector on the stack
print("Found other accompanying IDs: {}".format(values))
return True # drop to gdb's prompt
# Ensure shared libraries are loaded already
gdb.execute("start")
# Set our breakpoint, which happens to reside in some shared lib, hence the "start" previously
DebugPrintingBreakpoint("source.cpp:42")
gdb.execute("continue")
You can execute this script from gdb's prompt like this:
(gdb) source script.py
Or from the command-line:
$ gdb --command script.py ./executable.elf
See the complete GDB Python API docs for further info.
OK, I found the answer while asking the question... and it and it was a really simple thing.
You should not use both the "--command" and the "--eval" at the same time if you expect them to be executed in a specific order!
A more predicable way is to put everything in the commands.gdb file and ignore --eval.
So it becomes something like this:
arm-none-eabi-gdb --batch --command=commands.gdb main.elf
Where commands.gdb looks like this:
break test_success
break test_failed
target remote localhost:3333
cont
frame
But it would probably be so much nicer to do this with something like python instead.
Just wanted to note something that I find confusing whenever I come back to this topic (Note, I'm currently on Ubuntu 14.04, GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1):
First, there are references about it being "possible to invoke gdb as an interpreter":
9. Scripting gdb — The Cliffs of Inanity (http://tromey.com/blog/?p=548)
http://blog.scottt.tw/2012/01/exploring-gdb-python-api-with-ipython_31.html
... meaning, one would write a script text file with the shebang line #!/usr/bin/gbd -P or #!/usr/bin/gbd --python, then write Python code in it, then make it executable chmod +x pygdbscript, then run ./pygdbscript; ... but as in this post:
GDB - Missing "--python" Parameter? / Newbie Corner / Arch Linux Forums
..., I get gdb: unrecognized option '--python' if I try anything like that. Apparently this option is/was a feature in some "archer" branch of gdb?!
So, in order to run a Python script in gdb, there are actually two ways:
Name your script file with extension .py; say test.py here:
def Something():
print("hello from python")
Something()
gdb.execute("quit");
Note, in this case, you just write plain Python code; and you do not need to import gdb in order to access the gdb object. This you can run with either of:
gdb -x test.py
gdb -x=test.py
gdb --command test.py
gdb --command=test.py
gdb -command test.py
gdb -command=test.py
... which seem to be equivalent, as the result for any of these is the same printout, before gdb is instructed to exit by the script:
$ gdb -x=test.py
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1
...
For help, type "help".
Type "apropos word" to search for commands related to "word".
hello from python
NOTE that for this case, also names like test.gdb.py will be interpreted as pure Python scripts, since then end in .py.
Name your script anything else - as long as it does not end with .py extension; say test.pygdb here:
python
def Something():
print("hello from python")
Something()
gdb.execute("quit");
end
In this case, gdb interprets the script as being a gdb script, i.e. with gdb commands - and that means, that whatever Python code you may want to write in here, must be wrapped in "python" as a starting line and "end" at end of the Python code. Again, it would be called with any of these equivalent calls:
gdb -x test.pygdb
gdb -x=test.pygdb
gdb --command test.pygdb
gdb --command=test.pygdb
gdb -command test.pygdb
gdb -command=test.pygdb
... and then the output is the same as in the previous case (since it is the same Python script running):
$ gdb -x test.pygdb
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1
...
hello from python
And in response to OP: if the C code in OP is in /tmp/myprog.c - with an added int start_test() { return rand() % 50; } on top, otherwise it won't compile - , and is compiled with with gcc -g myprog.c -o myprog.exe into /tmp/myprog.exe; then you can use a myprog.gdb.py script like this:
# need to specify the executable file which we debug (in this case, not from command line)
# here `gdb` command `file` is used - it does not have a Python equivalent (https://sourceware.org/gdb/onlinedocs/gdb/Objfiles-In-Python.html#index-Objfile_002eframe_005ffilters)
# so we must use gdb.execute:
myexefile="/tmp/myprog.exe"
print("""
### myprog.gdb.py is running: """ + myexefile + """ - and adding breakpoints:
""")
gdb.execute("file " + myexefile)
gdb.execute("set pagination off")
ax = gdb.Breakpoint("test_success")
bx = gdb.Breakpoint("test_failed")
gdb.execute("run")
# here the program will break, so we can do:
print("""
### myprog.gdb.py after the break - current stack frame:
""")
current_frame_at_break = gdb.selected_frame()
print(current_frame_at_break) # instead of gdb.execute("frame")
print("""
### myprog.gdb.py - backtrace:
""")
gdb.execute("backtrace 2")
print("""
### myprog.gdb.py - go to frame that called current frame:
""")
parent_frame = current_frame_at_break.older()
print(parent_frame)
status_var = parent_frame.read_var("status")
print("status_var is: ", status_var)
... then run this script with:
$ gdb -x myprog.gdb.py
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1
....
For help, type "help".
Type "apropos word" to search for commands related to "word".
### myprog.gdb.py is running: /tmp/myprog.exe - and adding breakpoints:
Breakpoint 1 at 0x400565: file myprog.c, line 8.
Breakpoint 2 at 0x40055f: file myprog.c, line 4.
Breakpoint 2, test_failed () at myprog.c:4
4 while(1);
### myprog.gdb.py after the break - current stack frame:
{stack=0x7fffffffdc70,code=0x40055b,!special}
### myprog.gdb.py - backtrace:
#0 test_failed () at myprog.c:4
#1 0x000000000040058c in main () at myprog.c:15
### myprog.gdb.py - go to frame that called current frame:
{stack=0x7fffffffdc90,code=0x400567,!special}
status_var is: 33
(gdb)
Note that at the end of this script, the (gdb) interactive prompt remains, and you can use it normally here; if you don't need the interactive prompt, you can do gdb.execute("quit"); as in the above scripts to force gdb to exit instead at end of script execution.
Also, for an example of subclassing breakpoint class in gdb Python, see How to print the current line of source at breakpoint in GDB and nothing else?