gdb is showing "program exited" during startup - gdb

Why is gdb showing that the program exited during its startup, so before to stop at the first breakpoint in the main function ?
Some steps:
$ gdb --cd $programhome -tui -tty $reservedtty --args myprogram
b main
r
gdb shows:
Starting program: myprogram
During startup program exited with code 1.
I already tried to break at exit() function, without success.

Why is gdb exiting before to stop at the first breakpoint in the main function
GDB is not exiting. Your program does.
It does exit before reaching main.
This can happen for a few reasons, such as:
Corrupt binary -- the kernel rejects it in execve system call for some reason and not a single instruction of the program actually runs.
The dynamic linker rejects it (e.g. because some required library or symbol is missing)
Your shell refuses to execute the program (bad ~/.bashrc, bad $PATH, etc).
You can narrow down the actual cause by running the program outside GDB (does it run?), running without ~/.bashrc, using (gdb) catch syscall exit_group (on Linux), etc.

There was a permission issue accessing the secondary terminal port.
The gdb is being started with the parameter -tty which switches the input/output to another tty port (in that case pseudo: pts).
When the two terminals are opened by different users, that problem occurs, even if after the first logon you change the user with su command, the first user logged needed to be the same among the two ttys.

Related

How do I configure GDB correctly, to stop error "You can't do that without a process to debug"

Ubuntu 16.04.4 LTS, GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
I am trying to call a function in a compiled C program and get the following:
"(gdb) call getVarName(someParam)
You can't do that without a process to debug."
There are no other codes or messages.
I can run the program from the shell prompt
jef#ubuntu$ ./program.
I can run the program within gdb after designating the file. Permissions are 777 (just to cover all bases).
Based on research, I set the SHELL with "export SHELL=/bin/bash"
and
set kernal.yama.ptrace_scope = 0 in /etc/sysctl.d/10-ptrace.conf
I still get the same behavior.
I still get the same behavior.
Naturally.
The error you are getting means: you can't do this, unless you are debugging a live process.
This will work:
(gdb) break main
(gdb) run
... GDB is now stopped, *and* you have a live process.
... you *can* call getVarName(...) now
(gdb) call getVarName(...)
(gdb) continue # causes the process to run to end and exit
[Inferior 1 (process 195969) exited normally]
(gdb) # Now you no longer have a live process, so you *again* can't
# call functions in it.

How to redirect std::cin to a Linux terminal when debugging with GDB?

In Linux, GDB doesn't allow set new-console on and in stead uses something called tty. With
set inferior-tty /dev/pts/[number of an active console],
in a .gdbinit file (requires editing the number every time) it redirects std::cout, but std::cin isn't working properly. It just interprets my input as if I'm sending a bash command and reports an error, and my program continues to wait for input. I can no longer type in the console after that, so I assume std::cin is being redirected, but doesn't work properly.
I tried looking up how to launch a terminal from the application itself. I could only find this answer, which also mentions a bug that it doesn't redirect input.
Is there any way to fix this issue and redirect std::cin (and std::cout) to a Linux terminal properly when debugging?
Background info: What I'm trying to do should be simple. Print a > in front of user input before using std::cin. I have simple code in place that prints the >, flushes cout and then calls getline(). It works when just running the program normally. But sadly, GDB refuses to flush the stream when there isn't a newline, so it doesn't print the >, ignores the first character of the user input and then does prints the >, immediately followed by the error message that my program sends because of the mutilated input string.
In Windows, I've solved it by making a .gdbinit file with set new-console on. This causes GDB to use a Windows console in stead of its own and that works as intended.
If you need to start the debugging after the program has a chance to pause, just run the program in a terminal, and then gdb - your-program-pid in another terminal. Otherwise there's a sequence of steps which is faster to do than to describe.
Start two terminal windows.
In one terminal, figure out the PID of the shell. ps should tell you.
In the other terminal, use these commands
$ gdb - pid-of-the-other-shell
(gdb) br main
(gdb) c
Now you have gdb attached to your shell in another terminal. Not very useful.
In the first terminal, type at the shell prompt
$ exec your-program
Now you have one terminal running gdb and another terminal running your program under gdb, stopped at main. Bear in mind that when the program exits, its terminal window will close. If you don't want this, start a second level shell in the first terminal and attach gdb to it.
You can also use set inferior-tty command, but you must make sure the other tty exists and no other program attempts to read from it. The easiest way is to run a shell in another terminal and give it a while true; do sleep 1000; done command. Note that you may get warning: GDB: Failed to set controlling terminal: Operation not permitted messages. They are harmless.
You can use gdb's multiprocess debugging feature and a terminal emulator like xterm to do this. (gnome-terminal won't work so well as explained later)
prompt.c
#include <stdio.h>
int main()
{
enum {
N = 100,
};
char name[N];
printf("> ");
scanf("%s", name);
printf("Hi, %s\n", name);
return 0;
}
xterm.gdb
set detach-on-fork off
set target-async on
set pagination off
set non-stop on
file /usr/bin/xterm
# -ut tells xterm not to write a utmp log record
# which involves root privileges
set args -ut -e ./prompt
catch exec
run
Sample Session
$ gdb -q -x xterm.gdb
Catchpoint 1 (exec)
<...>
[New process 7073]
<...>
Thread 0x7ffff7fb2780 (LWP 7073) is executing new program: /home/scottt/Dropbox/stackoverflow/gdb-stdin-new-terminal/prompt
Reading symbols from /home/scottt/Dropbox/stackoverflow/gdb-stdin-new-terminal/prompt...done.
Catchpoint 1 (exec'd /home/scottt/Dropbox/stackoverflow/gdb-stdin-new-terminal/prompt), 0x0000003d832011f0 in _start () from /lib64/ld-linux-x86-64.so.2
(gdb) inferior 2
[Switching to inferior 2 [process 7073] (/home/scottt/Dropbox/stackoverflow/gdb-stdin-new-terminal/prompt)]
[Switching to thread 2 (Thread 0x7ffff7fb2780 (LWP 7073))]
#0 0x0000003d832011f0 in _start () from /lib64/ld-linux-x86-64.so.2
(gdb) break prompt.c:11
Breakpoint 2 at 0x4004b4: file prompt.c, line 11.
(gdb) continue &
Continuing.
(gdb)
Breakpoint 2, main () at prompt.c:11
11 printf("> ");
next
12 scanf("%s", name);
(gdb) next
13 printf("Hi, %s\n", name);
A new xterm window will appear after executing gdb -q -x xterm.gdb and you can interact with prompt inside it without interfering with GDB.
Related GDB commands:
inferior 2 switches the process GDB's debugging much like the thread command switches threads. (GDB: Debugging Multiple Inferiors and Programs)
continue & means to continue executing in the background. (GDB: Background Execution)
I used xterm because gnome-terminal uses dbus-launch to ask another process to launch the new terminal outside of the parent-child process relationship that GDB relies on.

Debugging user-code on xv6 with gdb

I'm doing an OS class that's based on xv6 and I wrote a program that needs to run on it.
I know that I can debug kernel code with make qemu-gdb but I'm not sure how to debug my own user program.
Lets say I want to debug cat, how would I go about doing that?
Thanks
P.S. isn't there an xv6 tag? should this question even go here?
From the xv6 top-level dir:
Run the emulator in debug mode (assuming no X11): make qemu-nox-gdb
In other terminal just run the debugger loading the kernel symbols with:
gdb kernel This is important, otherwise the debugger will be confused between kernel and and user program symbols, for example main()
From the gdb interface run: (gdb) target remote localhost:26000
where 26000 is the TCP port that the step #1 report at the end (this might change).
Load the user exec with (gdb)file user_program
Place a breakpoint (gdb) break main and continue with (gdb) continue
etc...
file cat, break main, continue
semi reference running and debugging xv6

GDB - how to find out from where program exited

While debugging a program in GDB, I get an unexpected "program exited normally". So I'm wondering if is there a way to find out from where (which line) the program exited.
Program is multi-threaded, if that matters.
You could try the GDB command break exit to set a breakpoint on the exit(2) library call. If that doesn't get you what you need, maybe break _exit. You might need to start your program with 'sta' before getting the latter breakpoint to take. In either case, you should then be able to use the where command to get a stack trace showing where you were when the program decided to exit.
Usually with the command below when the application has finished executing:
(gdb) thread apply all bt
Of course, if you want to know the exact line you must compile your application with debugging symbols, i.e. -g
Set a breakpoint on _exit and then examine the stack.

How to run gdb against a daemon in the background?

I'm trying to debug a server I wrote with gdb as it segfaults under very specific and rare conditions.
Is there any way I can make gdb run in the background (via quiet or batch mode?), follow children (as my server is a daemon and detaches from the main PID) and automatically dump the core and the backtrace (to a designated file) once the program crashes?
Assuming you have appropriate permissions, you can have gdb attach to any process. You can do it on the command line with:
gdb /path/to/binary _pid_
or from within gdb with the attach command:
attach _pid_
So, once your daemon has started, you can use either of these techniques to attach to the final PID your daemon is running as. Attaching gdb stops the process which you are tracing so you will need to issue a "continue" to restart it.
I don't know a direct way to get gdb to run arbitrary commands when the program crashes. Here is one workaround I can think of:
Create and register a signal handlers for SIGSEGV.
Tell gdb not to stop on that signal (handle SIGSEGV nostop)
Set a breakpoint at the first line of your signal handler.
Assign commands to the breakpoint from step 3
Why not just run the process interactively in a persistent screen session? Why must it be a daemon when debugging? Or just run gdb in the screen session and attach it to the running process (e.g. gdb /path/to/binary -p PID_of_binary) after it forks.
First, I'd setup your shell / environment to give you a core dump. In bash:
ulimit -c unlimited
Once you have the core dump, you can use gdb to examine the stack trace:
gdb /path/to/app /path/to/core/file
I'm not really a gdb expert but two things come to mind
Tracepoints which might give you the necessary information as your program runs or
Use gdb's remote debugging facility to debug your program while it's running as a daemon.
How to generate a stacktrace when my gcc C++ app crashes answer for this question should do what you want. (assuming you can make changes in your code)
You might want to take a look at how Samba facilitates debugging; it has a configurable "panic action" that can suspend the application, notify the developer, spawn gdb, etc., and is run as part of its signal handler. See lib/util/fault.c in the Samba source tree.
My practice: comment out daemon function call, rebuild binary, then use gdb to run.