I go this simple code to test my GDB ( GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1), my linux runs within docker, and the code is:
// hello.cc
#include <iostream>
int main() {
std::cout << "hello world!" << std::endl;
}
I compiled it with:
$ g++ -g -o out.a hello.cc
and debug it like:
(gdb) file out.a
(gdb) b main
Note: breakpoint 1 also set at pc 0x40084a.
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x000000000040084a in main() at hello.cc:3
(gdb) r
hello world!
During startup program exited normally.
Why gdb not stopped on main?
Couple of reasons i can think of:
The gdb version i use is 7.0-0.4.16, and it worked as expected (ie., stopped at main). Probably it is related to version of gdb you have.
I am bit surprised on the info output in your gdb case. It showed the line number as '3' for breakpoint. Ideally it should be 4.
Ruling out the other two options mentioned above. Just observed that your linux is running on a docker. In this case, your test program is a process running on the docker and i assume gdb is invoked on native machine. You might need to attach the docker to gdb using lxc-attach.
Related
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.
I'm trying to get to the bottom of a bug in KDE 5.6. The locker screen breaks no matter how I lock it. Here's the relevant code: https://github.com/KDE/kscreenlocker/blob/master/abstractlocker.cpp#L51
When I run /usr/lib/kscreenlocker_greet --testing, I get an output of:
KCrash: Application 'kscreenlocker_greet' crashing...
Floating point exception (core dumped)
I'm trying to run it with gdb to try and pin the exact location of the bug, but I'm not sure where to set the breakpoints in order to isolate the bug. Should I be looking for calls to KCrash? Or perhaps a raise() call? Can I get gdb to print off the relevant line of code that causes SIGFPE?
Thanks for any advice you can offer.
but I'm not sure where to set the breakpoints in order to isolate the bug
You shouldn't need to set any breakpoints at all: when a process running under GDB encounters a fatal signal (such as SIGFPE), the OS notices that the process is being traced by the debugger, and notifies the debugger (instead of terminating the process). That in turn causes GDB to stop, and prompt you for additional commands. It is at that time that you can look around and understand what caused the crash.
Example:
cat -n t.c
1 #include <fenv.h>
2
3 int foo(double d) {
4 return 1/d;
5 }
6
7 int main()
8 {
9 feenableexcept(FE_DIVBYZERO);
10 return foo(0);
11 }
gcc -g t.c -lm
./a.out
Floating point exception
gdb -q ./a.out
(gdb) run
Starting program: /tmp/a.out
Program received signal SIGFPE, Arithmetic exception.
0x000000000040060e in foo (d=0) at t.c:4
4 return 1/d;
(gdb) bt
#0 0x000000000040060e in foo (d=0) at t.c:4
#1 0x0000000000400635 in main () at t.c:10
(gdb) q
Here, as you can see, GDB stops when SIGFPE is delivered, and allows you to look around and understand the crash.
In your case, you would want to first install debuginfo symbols for KDE, and then run
gdb --args /usr/lib/kscreenlocker_greet --testing
(gdb) run
I change post totally.
because I work in south korea army.
but south korea army internet computer is forbid upload file.
so I really upload my source code. but I can't .
so I try debug very very simple program with gdb.
but It is still not working.
my system is
Distributor ID: Ubuntu
Description: Ubuntu 14.04.3 LTS
Release: 14.04
Codename: trusty
in cloud IDE called "nitrous"
and g++ , gdb version is
g++ (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
GNU gdb (GDB) 7.8
I write very simple code : simple.cpp
#include <iostream>
int main(){
std::cout << "Hello World!" << std::endl;
return 0;
}
compile with "-g" and gdb execute
nitrous#ubuntu-108903:~/code$ g++ -g simple.cpp -o simple
nitrous#ubuntu-108903:~/code$ gdb simple
and set break main and run
Reading symbols from simple...done.
(gdb) break main
Breakpoint 1 at 0x400861: file simple.cpp, line 4.
(gdb) run
Starting program: /home/nitrous/code/simple
Hello World!
During startup program exited normally.
Even very simple helloworld program not work breakpoint.
just print out During startup program exited norally.
I set a break point, but it's not hit. What is problem?
The most likely problem is that your program terminates before reaching main. (A typical dynamically linked program will execute several hundred 1000s of instructions before reaching main.)
Run your program under GDB until GDB stops with SIGSEGV. Execute GDB where command. Observe that main is not on the stack.
Once you've confirmed that main is not on the stack, ask a different question (assuming you still don't understand the reason for crash).
I guess that gdb for some reason failed to set breakpoint. Try to run gdb with sudo.
Btw, could you run strace on generated elf and grep for ptrace? It should be something like follow strace -f -o syscall.txt gdb ./simple.out.
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 currently have 2 virtual machines running, one is a server and one is a client. They are both running Ubuntu. I created a C++ program to connect to a MYSQL server. When i open up a terminal in the server VM, the c++ program compiles and runs PERFECTLY!
BUT, when I try to run it on the client, it wont work at all. The code compiles perfectly fine but when i type "./main" to start the program, NOTHING comes up. It's just a blank screen. I totally do not get why this is happening. The code is exactly the same on both the client and the server, but for some reason, it wont display ANY of my code when I run it on the client side. Below are pictures to show what i mean
Here is a link to view a screenshot of what I am talking about (http://imgur.com/a/QqgPV). In the first picture, I compile the program, which compiles fine. I then run the program but NOTHING outputs to the screen.
The second picture shows the program being ran on the server and shows what is suppose to be output on the screen after the initial ./main command
What should I do to find out what's going wrong?
Compile with "-g -ggdb" and run it in a debugger:
$ cgdb --args ./main your_args
When it blocks pres Ctrl-C and type "bt". That will tell you where the program stopped.
There might be a gazillion things blocking your code (you use external stuff, like the db).
Give us some code to analyze. We can't help without specifics.
BTW: The fact that it compiles doesn't mean it will run flawlessly.
Either add logging to your program or run it under strace to figure out where it's getting stuck or what it's waiting for.
At the most basic level, you add logging by adding log statements. Say your code looks like this:
a();
b();
c();
output_stuff();
Temporarily change it to:
cout << "about to do a" << endl;
a();
cout << "about to do b" << endl;
b();
cout << "about to do c" << endl;
c();
cout << "done with c" << endl;
output_stuff();
Then see what messages you get. If you don't get "about to do a" then it's a constructor for a global object or process initialization that's hanging. If you get "about to do a" but not "about to do b", then it's a() that's hanging. And so on.
Build your program with debug symbols enabled (GCC -g option)
$ cat infinite.cpp
void infinite()
{
for(;;)
{
}
}
int main()
{
infinite();
}
$ g++ -g infinite.cpp
Run your program:
$ ./a.out
Open new terminal session
Find out what is PID of your program
$ ps x | grep a.out
7817 pts/3 R+ 0:08 ./a.out
Run gdb and attach it to your program (sudo if you get permission error):
$ gdb
...
(gdb) attach 7817
Attaching to process 7817
...
Loaded symbols for /lib64/ld-linux-x86-64.so.2
infinite () at infinite.cpp:3
3 for(;;)
(gdb) backtrace
#0 infinite () at infinite.cpp:3
#1 0x0000000000400513 in main () at infinite.cpp:10
Use the debugger to inspect at what point of execution is your program, set breakpoints, inspect state of your program (perhaps one of loop counters is unsigned integer and overflows, etc.)