GDB - Prepare commands for interactive mode - gdb

I want to run some commands in gdb and then be in the interactive mode. How can I do that? If I run:
gdb -ex "b main.c:390" -ex 'r' --args ./main -b1 < in.txt
gdb then exits. I don't want that.
Thanks

You must create .gdbinit file in the folder where you have executable. Contents of .gdbinit must be as folows:
file main
set args -b1 < in.txt
break main.c:390
run
Then just invoke gdb in console.
EDIT
just invoke gdb -ex "file main" -ex "break main.c:390" -ex "run" -ex "set args -b1 < test"

Related

Problems adding a breakpoint with commands from command line with ex command

I try to start a program with gdb from commands line, then immediately add a breakpoint with commands, then run:
gdb -q -ex 'set pagination off' -ex 'break XOpenDisplay' -ex 'commands' -ex 'silent' -ex 'info locals' -ex 'bt full' -ex 'cont' -ex 'end' -ex 'r' ./myprogram
The program gets stuck after the "commands" prompting me to enter commands via keyboard then enter "end".
Did I forget something?
Regards
Update:
I added a .gdbinit with the following content:
gdb -q -ex breakXOpenDisplayRun
define breakXOpenDisplayRun
set pagination off
break XOpenDisplay
commands
silent
info locals
bt full
cont
end
run
end
gdb -q -ex breakXOpenDisplayRun ./myapp
When the program encounters the breakpoint the first time it stops there prompting a user input which should not happen. After the first cont it works as expected.
The -ex expects a complete command, and in case of commands the complete command is
commands
silent
info locals
bt full
cont
end
While you can enter multi-line command at the shell prompt, doing so is exceedingly awkward, and you'll be better off putting all of the desired commands into a temporary command file. Something like this should work:
cat > /tmp/gdb.$$ <<"EOF" && gdb -x /tmp/gdb.$$ ./myprogram && rm -f /tmp/gdb.$$
set pagination off
break XOpenDisplay'
commands
silent
info locals
bt full
cont
end
run
EOF
Thanks to gdb mailing list Andrew Burgess. This is a bug that has been fixed in gdb 11. For versions before that, using a separate source worked for me:
gdb -q -ex 'source breakXOpenDisplayRun.gdb' ./myapp

gdb backtrace with no user input?

I'm wondering if it's possible to launch an application via GDB, on a SegFault write the backtrace to a file (to look at later), and then exit GDB all without any user input.
I'm running an application from a shell script in an infinite loop (so if it crashes it reloads) on OS boot from a non-interactive session. The application is crashing in a non-reproducible way so I need a backtrace from the crash to debug the issue. Ideally, I'd just modify the shell script to include the GDB debugging + backtracing functionality and preserve the automatic restarting of the application following a crash.
Is this possible to do?
Thanks to Aditya Kumar; acceptable solution:
gdb -batch -ex "run" -ex "bt" ${my_program} 2>&1 | grep -v ^"No stack."$
If the program needs arguments:
gdb -batch -ex "run" -ex "bt" --args ${my_program} param1 param2 \
param3 ... 2>&1 | grep -v ^"No stack."$
gdb --batch -q <debuged_executable> <core_file> -ex bt
This works with gdb 7.6:
My test program that causes a core dump if it is given a command line parameter:
int a(int argc)
{
if (argc > 1) {
int *p = 0;
*p = *p +1;
return *p;
}
else {
return 0;
}
}
int b(int argc)
{
return a(argc);
}
int main(int argc, char *argv[])
{
int res = b(argc);
return res;
}
My python script my_check.py:
def my_signal_handler (event):
if (isinstance(event, gdb.SignalEvent)):
log_file_name = "a.out.crash." + str(gdb.selected_inferior().pid) + ".log"
gdb.execute("set logging file " + log_file_name )
gdb.execute("set logging on")
gdb.execute("set logging redirect on")
gdb.execute("thread apply all bt")
gdb.execute("q")
gdb.events.stop.connect(my_signal_handler)
gdb.execute("set confirm off")
gdb.execute("set pagination off")
gdb.execute("r")
gdb.execute("q")
So, first I run a.out and there is no crash. No log files are created:
gdb -q -x my_check.py --args ./a.out >/dev/null
Next I run a.out and give it one parameter:
>gdb -q -x my_check.py --args ./a.out 1 >/dev/null
And this is a crash report:
>cat a.out.crash.13554.log
Thread 1 (process 13554):
#0 0x0000000000400555 in a (argc=2) at main.cpp:5
#1 0x000000000040058a in b (argc=2) at main.cpp:15
#2 0x00000000004005a3 in main (argc=2, argv=0x7fffffffe198) at main.cpp:20
Alternatively to just storing the backtrace, you could put ulimit -c unlimited in front of your infinite loop in your shell script. The result will be that every time your program segfaults, it will write a core dump into a file which on my system is just called core but on other systems might include the process id. If the program segfaults (you see this from its exit status being equal to 139) then just move the core file to a safe location using a unique name (for example using timestamps). With these core files and gdb you can then do even more than just look at the backtrace. Thus I guess using them might even be more useful to you.

Is there a way to let the gdb repeat the same instrcutions on every start again?

I am currently debugging a program with gdb.
I have to start gdb over and over again and do the same steps:
set a breakpoint,
run,
print a variable,
quit
Is there a way to let gdb do that automatically for me? Probably a script that could be attached as a parameter?
Thanks in advance!
You can do it either by -x file option or by -ex command option. From Gdb manual:
-command file
-x file
Execute commands from file file. The contents of this file is evaluated exactly as the source command would. See Command files.
-eval-command command
-ex command
Execute a single gdb command.
This option may be used multiple times to call multiple commands. It may also be interleaved with `-command' as required.
gdb -ex 'target sim' -ex 'load' \
-x setbreakpoints -ex 'run' a.out
The interwebs differ on whether the name of the file is .gdbrc or .gdbinit, but GDB will read this file from your home directory on start-up, and it can give any GDB command (including setting breakpoints).
Also check out http://www.andrews.edu/~seidel/gdb.help

Linux scope of redirection

I'm writing a script which starts gdb in xterm, and I would like to start my program with the output redirected to a file.
My command is something like this:
xterm -e gdb --args myprog --myargs > /tmp/file
How do I indicate which command the redirection applies to? It could apply to xterm, gdb, or myprog.
I tried using quotes:
xterm -e gdb --args "myprog --myargs > /tmp/file"
But then gdb tried to open a file with name "myprog --myargs > /tmp/file". Any help would be appreciated.
Thanks!
For a reasonably recent version of GDB, the following works:
gdb -q -ex 'set args foo > /tmp/foo.out' -ex run -ex quit /bin/echo

How to pass arguments and redirect stdin from a file to program run in gdb?

I usually run a program as :
./a.out arg1 arg2 <file
I would like to debug it using gdb.
I am aware of the set args functionality, but that only works from the gdb prompt.
You can do this:
gdb --args path/to/executable -every -arg you can=think < of
The magic bit being --args.
Just type run in the gdb command console to start debugging.
Pass the arguments to the run command from within gdb.
$ gdb ./a.out
(gdb) r < t
Starting program: /dir/a.out < t
If you want to have bare run command in gdb to execute your program with redirections and arguments, you can use set args:
% gdb ./a.out
(gdb) set args arg1 arg2 <file
(gdb) run
I was unable to achieve the same behaviour with --args parameter, gdb fiercely escapes the redirections, i.e.
% gdb --args echo 1 2 "<file"
(gdb) show args
Argument list to give program being debugged when it is started is "1 2 \<file".
(gdb) run
...
1 2 <file
...
This one actually redirects the input of gdb itself, not what we really want here
% gdb --args echo 1 2 <file
zsh: no such file or directory: file
Start GDB on your project.
Go to project directory, where you've already compiled the project executable. Issue the command gdb and the name of the executable as below:
gdb projectExecutablename
This starts up gdb, prints the following:
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
.................................................
Type "apropos word" to search for commands related to "word"...
Reading symbols from projectExecutablename...done.
(gdb)
Before you start your program running, you want to set up your breakpoints. The break command allows you to do so. To set a breakpoint at the beginning of the function named main:
(gdb) b main
Once you've have the (gdb) prompt, the run command starts the executable running. If the program you are debugging requires any command-line arguments, you specify them to the run command. If you wanted to run my program on the "xfiles" file (which is in a folder "mulder" in the project directory), you'd do the following:
(gdb) r mulder/xfiles
Hope this helps.
Disclaimer: This solution is not mine, it is adapted from https://web.stanford.edu/class/cs107/guide_gdb.html
This short guide to gdb was, most probably, developed at Stanford University.
Wouldn't it be nice to just type debug in front of any command to be able to debug it with gdb on shell level?
Below it this function. It even works with following:
"$program" "$#" < <(in) 1> >(out) 2> >(two) 3> >(three)
This is a call where you cannot control anything, everything is variable, can contain spaces, linefeeds and shell metacharacters. In this example, in, out, two, and three are arbitrary other commands which consume or produce data which must not be harmed.
Following bash function invokes gdb nearly cleanly in such an environment [Gist]:
debug()
{
1000<&0 1001>&1 1002>&2 \
0</dev/tty 1>/dev/tty 2>&0 \
/usr/bin/gdb -q -nx -nw \
-ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$#\"" exec' \
-ex r \
--args "$#";
}
Example on how to apply this: Just type debug in front:
Before:
p=($'\n' $'I\'am\'evil' " yay ")
"b u g" "${p[#]}" < <(in) 1> >(out) 2> >(two) 3> >(three)
After:
p=($'\n' $'I\'am\'evil' " yay ")
debug "b u g" "${p[#]}" < <(in) 1> >(out) 2> >(two) 3> >(three)
That's it. Now it's an absolute no-brainer to debug with gdb. Except for a few details or more:
gdb does not quit automatically and hence keeps the IO redirection open until you exit gdb. But I call this a feature.
You cannot easily pass argv0 to the program like with exec -a arg0 command args. Following should do this trick: After exec-wrapper change "exec to "exec -a \"\${DEBUG_ARG0:-\$1}\".
There are FDs above 1000 open, which are normally closed. If this is a problem, change 0<&1000 1>&1001 2>&1002 to read 0<&1000 1>&1001 2>&1002 1000<&- 1001>&- 1002>&-
You cannot run two debuggers in parallel. There also might be issues, if some other command consumes /dev/tty (or STDIN). To fix that, replace /dev/tty with "${DEBUGTTY:-/dev/tty}". In some other TTY type tty; sleep inf and then use the printed TTY (i. E. /dev/pts/60) for debugging, as in DEBUGTTY=/dev/pts/60 debug command arg... That's the Power of Shell, get used to it!
Function explained:
1000<&0 1001>&1 1002>&2 moves away the first 3 FDs
This assumes, that FDs 1000, 1001 and 1002 are free
0</dev/tty 1>/dev/tty 2>&0 restores the first 3 FDs to point to your current TTY. So you can control gdb.
/usr/bin/gdb -q -nx -nw runs gdb invokes gdb on shell
-ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$#\"" creates a startup wrapper, which restores the first 3 FDs which were saved to 1000 and above
-ex r starts the program using the exec-wrapper
--args "$#" passes the arguments as given
Wasn't that easy?