Here is my program:
#include <stdio.h>
int main(void) {
printf("Hello world\n");
return 0;
}
That's how I compile it
aarch64-linux-gnu-gcc -O0 -g3 main.c
I started the a.out like this:
qemu-aarch64-static -L /usr/aarch64-linux-gnu -singlestep -g 1234 ./a.out
And then I started gdb
$ gdb-multiarch -q ./a.out
Reading symbols from ./a.out...done.
(gdb) set sysroot /usr/aarch64-linux-gnu/
(gdb) target remote :1234
Remote debugging using :1234
Reading symbols from /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1...(no debugging symbols found)...done.
0x0000004000814040 in ?? ()
from /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1
(gdb) break main
Breakpoint 1 at 0x76c: file main.c, line 4.
(gdb) c
Continuing.
[Inferior 1 (Remote target) exited normally]
My question: why gdb didn't stop on main entrance and program just finished without any break? What am I do wrong?
I've repeated these steps on Ubuntu 20.04 and everything works fine. To be fair, I use ubuntu for a long time and could just forget what I did before, but Debian is fresh.
Versions info:
OS: Debian GNU/Linux 10 (buster)
QEMU: qemu-aarch64 version 3.1.0 (Debian 1:3.1+dfsg-8+deb10u8)
GDB: GNU gdb (Debian 8.2.1-2+b3) 8.2.1
GCC: aarch64-linux-gnu-gcc (Debian 8.3.0-2) 8.3.0
Related
I installed gdb on Macos 11.2.3. I set it up following this tutorial and have currently a file .gdbinit containing set startup-with-shell off. I use the following script:
#include <stdio.h>
#include <stdlib.h>
int main (){
printf("hello world");
return 0;
}
Then I ran the command:
$ gcc -Wall hello_world.c -o hello_world.o
$ gdb hello_world.o
(gdb) run
...
Starting program: /path/to/hello_world.o
[New Thread 0x2403 of process 10983]
But don't get the printed hello world
Now if generate a.out with gcc hello_world.c and then run gdb hello_world.o (creating both hello_world.o and a.out) and (gdb) run now I get
$ gcc -Wall hello_world.c -o hello_world.o
$ gcc hello_world.c
$ gdb hello_world.o
...
(gdb) run
Starting program: /path/to/hello_world.o
[New Thread 0x2803 of process 15213]
[New Thread 0x1c03 of process 15213]
warning: unhandled dyld version (17)
hello world[Inferior 1 (process 15213) exited normally]
It seems that gdb works when there are both hello_world.o and a.out but not hello_world.o alone. Why? What am I doing wrong? How can I run gdb and getting the hello world output without having to compile the script with both $gcc -Wall hello_world.c -o hello_world.o and $ gcc hello_world.c
EDIT
There seems to be a problem with Macos according to this github link where the following is being said:
If after hitting run in `gdb`, you get "Starting program: /path/to/your/executable [args] [New Thread 0x2303 of process 795]" followed by a blank line which does not respond to anything, then you have hit GDB bug 24069. Check that you built the patched version from source.
What am I doing wrong?
You are trying to run hello.o, which is not an executable program, and can not run.
The tutorial you are following creates an executable with gcc hello_world.c -o hello_world -ggdb (note lack of the -c argument).
Ok I could solve the problem following the instruction on GDB Wiki BuildingOnDarwin
I am currently debugging an api from shared library libc6 using gdb
getaddrinfo()
which is being called from python module:
socket.getaddrinfo()
I have managed to set a breakpoint at getaddrinfo.c and I wish to navigate the execution in single steps.
Source files:
ldd --version
tells that I have glibc 2.19, and I have downloaded the source from here
http://ftp.gnu.org/gnu/libc/
But during single step debugging using gdb, it doesnt look like the line numbers are matching.
Is there a cleaner way to download the source for libc6
PS: I am new to gdb debugging, please do point out any needed info.
Ubuntu 22.04 minimal runnable example
See also: https://askubuntu.com/questions/487222/how-to-install-debug-symbols-for-installed-packages/1434174#1434174
In the case of glibc, the debug symbols already appear to come preinstalled, otherwise we would need to get them with:
printf "deb http://ddebs.ubuntu.com %s main restricted universe multiverse\n" $(lsb_release -cs){,-updates,-security,-proposed} | \
sudo tee -a /etc/apt/sources.list.d/ddebs.list
sudo apt install ubuntu-dbgsym-keyring
sudo apt update
sudo apt install coreutils-dbgsym
sudo apt install libc6-dbg
and then get source with:
sudo cp /etc/apt/sources.list /etc/apt/sources.list~
sudo sed -Ei 's/^# deb-src /deb-src /'
/etc/apt/sources.list sudo apt-get update
apt source libc6
which produces directory: glibc-2.35.
We then make a C hello world to test with:
main.c
#include <stdio.h>
int main(void) {
puts("hello");
}
and compile and GDB into it with:
gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -o main.out main.c
gdb -ex 'set substitute-path . glibc-2.35' main.out
and then test it out as:
(gdb) start
Temporary breakpoint 1 at 0x1151: file main.c, line 4.
Starting program: /home/ciro/tmp/main.out
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Temporary breakpoint 1, main () at main.c:4
4 puts("hello");
(gdb) s
__GI__IO_puts (str=0x555555556004 "hello") at ./libio/ioputs.c:33
33 {
(gdb) l
28 #include <string.h>
29 #include <limits.h>
30
31 int
32 _IO_puts (const char *str)
33 {
34 int result = EOF;
35 size_t len = strlen (str);
36 _IO_acquire_lock (stdout);
37
"We're in".
Some other versions of Ubuntu had sources at an absolute location like:
/tmp/build138741687/
in which case you would instead want:
set substitute-path /tmp/build138741687/ glibc-2.35
There are many questions related to specific errors why stepping into a shared library with gdb isn't working. None of them provide a systematic answer on how to confirm where the the cause is. This questions is about the ways to diagnose the setup.
Setup example
main.c
#include <stdio.h>
#include "myshared.h"
int main(void)
{
int a = 3;
print_from_lib();
return 0;
}
myshared.h
void print_from_lib();
myshared.c
#include <stdio.h>
void print_from_lib()
{
printf("Printed from shared library\n");
}
Place all the files in the same directory.
export LIBRARY_PATH=$PWD:$LIBRARY_PATH
export LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH
gcc -ggdb -c -Wall -Werror -fpic myshared.c -o myshared-ggdb.o
gcc -ggdb -shared -o libmyshared-ggdb.so myshared-ggdb.o
gcc -ggdb main.c -lmyshared-ggdb -o app-ggdb
Getting the error
$ gdb ./app-ggdb
GNU gdb (Ubuntu 7.12.50.20170314-0ubuntu1) 7.12.50.20170314-git
...### GDB STARTING TEXT
Reading symbols from app-ggdb...done.
(gdb) break 7
Breakpoint 1 at 0x78f: file main.c, line 7.
(gdb) run
Starting program: /home/user/share-lib-example/app-ggdb
Breakpoint 1, main () at main.c:7
7 print_from_lib();
(gdb) s
Printed from shared library
8 return 0;
gdb is not stepping inside of the function
Necessary but not sufficient checks
Debug symbols in the binaries
$ objdump --syms libmyshared-ggdb.so | grep debug
0000000000000000 l d .debug_aranges 0000000000000000 .debug_aranges
0000000000000000 l d .debug_info 0000000000000000 .debug_info
0000000000000000 l d .debug_abbrev 0000000000000000 .debug_abbrev
0000000000000000 l d .debug_line 0000000000000000 .debug_line
0000000000000000 l d .debug_str 0000000000000000 .debug_str
Symbols recognized by gdb
$ gdb ./app-ggdb
...### GDB STARTING TEXT
Reading symbols from app-ggdb...done.
(gdb) break 7
Breakpoint 1 at 0x78f: file main.c, line 7.
(gdb) run
Starting program: /home/user/share-lib-example/app-ggdb
Breakpoint 1, main () at main.c:7
7 print_from_lib();
(gdb)(gdb) info sharedlibrary
From To Syms Read Shared Object Library
0x00007ffff7dd7aa0 0x00007ffff7df55c0 Yes /lib64/ld-linux-x86-64.so.2
0x00007ffff7bd5580 0x00007ffff7bd5693 Yes /home/user/share-lib-example/libmyshared-ggdb.so
0x00007ffff782d9c0 0x00007ffff797ed43 Yes /lib/x86_64-linux-gnu/libc.so.6
Confirm .gdbinit isn't the cause
~/.gdbinit contains commands automatically executed upon starting gdb. ref.
Running gdb with the -nx flags can exclude .gdbinit as the source of the problem.
Question
Am looking for suggestions to complete the list of Necessary but not sufficient checks.
Current issue [Update from Mark Plotnick]
This step bug is reproducible on Ubuntu 17.04 amd64 with both a 64- and 32-bit executable and library.
The bug isn't reproducible on Ubuntu 17.04 i386. (gcc 6.3.0-12ubuntu2, gdb 7.12.50 and 8.0, no .gdbinit.).
Possibly relevant: gcc on 17.04 amd64 has been built (by Canonical) to generate pie executables by default.
Question
Can flags with which gcc was build with interfere with debugging? How can you identify if your gcc is the cause?
Your problem is self-imposed: don't do this: set step-mode on, and step will work as you expect.
From the GDB manual:
set step-mode
set step-mode on
The set step-mode on command causes the step command to stop at the first
instruction of a function which contains no debug line information
rather than stepping over it.
This is useful in cases where you may be interested in inspecting the machine
instructions of a function which has no symbolic info and do not want
GDB to automatically skip over this function.
You are interested in the opposite of the above -- you want to step into the print_from_lib function and avoid stopping inside the PLT jump stub and the dynamic loader's symbol resolution function.
GDB 7.11 can't reproduce this problem.
This is my steps. I hope this will help you:
1.gcc -ggdb -c -Wall -Werror -fpic myshared.c -o myshared-ggdb.o
2.gcc -ggdb -shared -o libmyshared-ggdb.so myshared-ggdb.o
3.gcc -ggdb main.c -lmyshared-ggdb -o app-ggdb -L.
4.gdb ./app-ggdb
In GDB,
(gdb) set env LD_LIBRARY_PATH=.
(gdb) b main.c:7
Breakpoint 1 at 0x4006a5: file main.c, line 7.
(gdb) r
Starting program: /home/haolee/tmp/app-ggdb
Breakpoint 1, main () at main.c:7
7 print_from_lib();
(gdb) s
print_from_lib () at myshared.c:5
5 printf("Printed from shared library\n");
(gdb)
I step into the function print_from_lib successfully.
Some more tests you can do on built shared library:
file libmyshared-ggdb.so should report that library has debug info and not stripped.
nm libmyshared-ggdb.so | grep print_from_lib should find the symbol for print_from_lib function.
If all above tests passed try to load the library directly in gdb and find the function:
gdb libmyshared-ggdb.so
(gdb) info functions print_from_lib
Function print_from_lib name should be printed. If not, something is wrong with gdb or gcc.
The system is Ubuntu 14.04 32bit, upgraded to the latest version.
test2.c:
#include <unistd.h>
void test() {
sleep(1000);
}
int main() {
test();
}
Compile it:
gcc /tmp/test2.c -o /tmp/test2 -g
Run and try to attach it with gdb:
$ sudo gdb -p 9038
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
...
Attaching to process 9038
Reading symbols from /tmp/test2...done.
Reading symbols from /lib/i386-linux-gnu/libc.so.6...Reading symbols from /usr/lib/debug//lib/i386-linux-gnu/libc-2.19.so...done.
done.
Loaded symbols for /lib/i386-linux-gnu/libc.so.6
Reading symbols from /lib/ld-linux.so.2...Reading symbols from /usr/lib/debug//lib/i386-linux-gnu/ld-2.19.so...done.
done.
Loaded symbols for /lib/ld-linux.so.2
0xb7799cb0 in ?? ()
(gdb) bt
#0 0xb7799cb0 in ?? ()
#1 0x00000000 in ?? ()
The gdb could load symbols from binary, but it just cannot parse the stack correctly. It's really weird.
Any suggestion?
I'm using GCC 4.4.1 and GDB 7.0-ubuntu on Ubuntu 9.10 (Karmic Koala). However, GCC won't generate debugger information when using any of the following switches: -g, -g3, -ggdb, or -ggdb3.
So when I run the program with GDB, it’s as if there wasn’t any debugger information generated. I have created very simple test source files in a new, empty folder.
Here is one example:
#include <stdlib.h>
#include <stdio.h>
int main (int argc, char **argv)
{
char msg[4];
// Allocate 4 bytes on the stack
strcpy (msg, "Hello, World!");
// Overflow
printf ("%s\n", msg);
return 0;
}
Here is my command line sequence:
gcc -g ./mytest.c -o mytest
gdb ./mytest
I have previously turned on MALLOC_CHECK_=1 in order to test the stack overflow problem in the code. And this works, so I get a stack trace. But the stack trace is no different whether I include the debug information or not. With the debugger information, I expected to see a line number of a file for where the problem occurred under GDB. However, this doesn't happen.
It works fine. I ran the debugger on my computer. I had to add
#include <string.h>
to compile it though. I called the file debugger.c. Here are the steps:
gcc -g debugger.c
gdb a.out
which will start the debugger
GNU gdb 6.3.50-20050815
...
...
(gdb) run
Starting program: /Developer/stackoverflow/extern/a.out
Reading symbols for shared libraries +. done
Program received signal SIGABRT, Aborted.
0x00007fff88040886 in __kill ()
(gdb) backtrace
#0 0x00007fff88040886 in __kill ()
#1 0x00007fff880e0e4f in __abort ()
#2 0x00007fff880d5693 in __chk_fail ()
#3 0x00007fff8802f851 in __strcpy_chk ()
#4 0x0000000100000f04 in main (argc=1, argv=0x7fff5fbff958) at debugger.c:9
(gdb)
But it seems like your problem isn't running the debugger, but getting the information where your code failed. You can use backtrace to achieve that.
You want:
gcc -g test.c -o mytest
gdb mytest
Never call anything "test" - it clashes with a shell built in. and "test.o" would by convention be the name of an object file, not an executable.
Your comment says you ran:
gcc -ggdb ./test.c -o test.o
That's probably not what you want.
gcc -ggdb -o mytest test.c
is likelier to be successful. If gdb ralphs on that then you have something wrong with your installation of gcc or gdb.