Why is my GDB batch mode exit status always 0? - gdb

The GDB docs say:
-batch
Run in batch mode. Exit with status 0 after processing all the command files specified with ‘-x’ ... Exit with nonzero status if an error occurs in executing the gdb commands in the command files.
But even when there are errors, I get an exit status of zero. For example:
$ cat gdbscript
foo
$ gdb -batch -x gdbscript
gdbscript:1: Error in sourced command file:
Undefined command: "foo". Try "help".
$ echo $?
0
The GDB program status is correct if I use quit 1, for example, in the script.
Why is this happening to me? Is there a way around it? I'm trying to flash a remote target, and I'd really like GDB to exit with error status if it fails.
My GDB version, should it happen to be important:
GNU gdb (GNU Tools for ARM Embedded Processors) 7.8.0.20150604-cvs

Why is this happening to me? Is there a way around it?
It is known gdb Bug 13000. You can apply experimental patch from Bug 13000 and rebuild gdb which may work for you.

Related

During startup program exited normally. gdb doesn't break at breakpoints

I'm receiving this gdb error on any code I try to debug any program with gdb. Here's the simplest process that reproduces the error
Create a main.cpp file with this content:
int main(){
return 0;
}
Run g++ -g main.cpp
Run gdb a.out
Inside gdb set a break point at line 2 with break 2
In gdb run the program with run
Output:
Starting program: /tmp/test/a.out
During startup program exited normally.
This is all done with gdb on the command line. I've tried using g++ and gcc with the same result. I'm not really sure where to go from here.
gdb version = 9.2
g++ version = 9.3.0
EDIT: I figured out what is causing the issue, but not how to fix it. The issue seems to be something related to my SHELL variable. I'm currently using xonsh as my shell but when I set my SHELL environment variable back to /bin/bash everything works as expected. Is there anything I can do to fix this while using xonsh? Should I report this to xonsh, gdb, both or neither?
I'm currently using xonsh as my shell but when I set my SHELL environment variable back to /bin/bash everything works as expected. Is there anything I can do to fix this while using xonsh? Should I report this to xonsh, gdb, both or neither?
This might be your xonsh startup problem, or it might be xonsh problem, or it could be that xonsh doesn't do what GDB expects it to do.
Normally, GDB forks / execs $SHELL -c "/path/to/your/exe $args" and expects the $SHELL to exec your program (this is done so shell redirection still works under GDB).
Only after that exec will GDB start setting breakpoints, etc.
If you have some xonsh init-file, which e.g. causes xonsh to exec something else, things could go bad. So I suggest trying to remove any such ~/.xonshrc or whatever it's called file, and seeing whether that fixes the problem.
If it doesn't, it could be that xonsh e.g. forks and execs your binary in a child (grandchild of GDB) instead of doing it directly, or it could be that xonsh doesn't understand the -c ... syntax.
If you don't care about redirection, you could also ask GDB to not use $SHELL at all: set startup-with-shell off. Documentation.

How to make LLDB quit on success, wait on failure?

This is the Clang version of:
Make gdb quit automatically on successful termination?
How to have gdb exit if program succeeds, break if program crashes?
Running my application many times, programmatically, over a large number of possible inputs, I've occasionally encountered a segmentation fault.
I'd like each test invocation to be run under lldb so that I can get a backtrace for further debugging. If an invocation exits without a crash, I'd like lldb to automatically quit so that the test harness progresses to the next iteration. This way I can set the whole thing off over lunchtime and only have the suite interrupted when something crashes.
Bonus points for having lldb auto-quit in all cases, but first print a backtrace if the program crashed.
I'm currently able to automate at least the initial run command:
lldb -o run -f $CMD -- $ARGS
I'm having difficulty finding an online command reference but it looks like the -batch command line option will get you the basic "exit on success/prompt on fail" behaviour.
For a backtrace and auto-quit on failure I think you need the --source-on-crash option...
-K <filename>
--source-on-crash <filename>
When in batch mode, tells the debugger to source this file of lldb
commands if the target crashes.
So, create the command file with something like...
echo -e 'bt\nquit' > lldb.batch
and then invoke as...
lldb --batch -K lldb.batch -o run -f $CMD -- $ARGS

xterm window cannot be held on Linux, it appears and then disappears very fast

I am doing degug for MPI C++ on Linux with GDB.
I cannot use the following command:
xterm -e gdb mpirun -np 1 ./myApplication
to open a window for the executable program ./myApplication: the xterm terminal appears and then disappears immediately.
Why does this happen?
I can open an xterm with:
xterm or xterm -e gdb.
Any help is really appreciated.
#chatan almost got it right.
If you want to invoke gdb on a program while passing arguments to that program, you need to use gdb's --args option. For example (I don't have mpirun, so I'll use /bin/sleep):
$ gdb --args /bin/echo hello
[...]
Reading symbols from /bin/echo...(no debugging symbols found)...done.
(gdb) run
Starting program: /bin/echo hello
hello
Program exited normally.
gdb doesn't automatically start running the program; it waits for input.
Without the --args option, gdb takes -np as a gdb option, not as an argument to mpirun. Since gdb doesn't have a -np option, it terminates with an error message:
$ gdb mpirun -np 1 ./myApplication
gdb: unrecognized option '-np'
Use `gdb --help' for a complete list of options.
And when you run xterm -e gdb mpirun -np 1 ./myApplication, xterm runs, it invokes gdb, gdb terminates with an error message, and xterm terminates before you get a chance to see the message.
So this should do the trick:
xterm -e gdb --args mpirun -np 1 ./myApplication
Of course you'll still have to type the run command within gdb to invoke mpirun. (If you're using gdb, you probably already know that.)
For future reference, if you have problems running a program under xterm -e, try running it by itself.
Your command is not going to work the way you expect it to anyway. gdb will ignore the arguments after 'mpirun'. And a naked mpirun command, without any arguments, is going to immediately exit (just try running mpirun by hand in a terminal). Since your xterm was started to execute that one command, it disappears after that process is finished.
What you need to do is, open an xterm. Then run "gdb mpirun" command.
You should end up in gdb command prompt. At this prompt, you need to issue the following command:
(gdb) run -np 1 ./myApplication
Now your application should be running inside gdb.

How to run gdb with LD_PRELOAD?

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.

How to automatically run the executable in GDB?

I'd like to have gdb immediately run the executable, as if I'd typed "run"
(motivation: I dislike typing "run").
One way is to pipe the command to gdb like this:
$ echo run | gdb myApp
But the problem with this approach is that you lose interactivity with gdb,
eg. if a breakpoint triggers or myApp crashes, gdb quits.
This method is discussed here.
Looking at the options in --help, I don't see a way to do this, but perhaps I'm missing something.
gdb -ex run ./a.out
If you need to pass arguments to a.out:
gdb -ex run --args ./a.out arg1 arg2 ...
EDIT:
Orion says this doesn't work on Mac OSX.
The -ex flag has been available since GDB-6.4 (released in 2005), but OSX uses Apple's fork of GDB, and the latest XCode for Leopard contains GDB 6.3.50-20050815 (Apple version gdb-967), so you are out of luck.
Building current GDB-7.0.1 release is one possible solution. Just be sure to read this.
I would use a gdb-script:
gdb -x your-script
where your-script contains something like:
file a.out
b main
r
afterwards you have the normal interactive gdb prompt
EDIT:
here is an optimization for the truly lazy:
save the script as .gdbinit in the working directory.
Afterwards you simply run gdb as
gdb
... and gdb automatically loads and executes the content of .gdbinit.
(echo r ; cat) | gdb a.out
The cat allows you keep typing after gdb breaks.
start command
This command is another good option:
gdb -ex start --args ./a.out arg1 arg2
It is like run, but also sets a temporary breakpoint at main and stops there.
This temporary breakpoint is deactivated once it is hit.
starti
There is also a related starti which starts the program and stops at the very first instruction instead, see also: Stopping at the first machine code instruction in GDB
Great when you are doing some low level stuff.
gdb -x <(echo run) --args $program $args