1

I'm trying to get gdb working with C++ programs on Ubuntu 20.04. What I need is to be able to set a breakpoint (for example, break main.cpp:3 gdb command) and then run until the breakpoint, but at the moment both start and run fail because they "Cannot insert breakpoint" and "Cannot access memory". For me gdb fails even with very simple examples. This is main.cpp content:

#include <iostream>
int main() {
    std::cout << "Hello World!";
    return 0;
}

I found somewhere that using -no-pie might help to get gdb working (with breakpoints), so I compile the program by running g++ -ggdb3 -no-pie -o main main.cpp (I also tried -g instead of -ggdb3, and -fno-PIE in addition to -no-pie). When I try to use gdb, it complains "Cannot insert breakpoint 1":

gdb -q main
Reading symbols from main...
(gdb) start
Temporary breakpoint 1 at 0x1189: file main.cpp, line 3.
Starting program: /tmp/main 
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x1189

Without -no-pie result is the same. Only thing that changes with or without -no-pie is the hexadecimal address, without -no-pie it is low like 0x1189 (as shown above), with -no-pie it can be 0x401176, but everything else exactly the same, I keep getting the "Cannot access memory at address" warning in both cases.

If I use starti instead of start, it works at first, but after a few nexti iterations it prints usual message "Cannot insteart breakpoint":

gdb -q main
Reading symbols from main...
(gdb) starti
Starting program: /tmp/main 

Program stopped.
0x00007ffff7fd0100 in ?? () from /lib64/ld-linux-x86-64.so.2
(gdb) nexti
0x00007ffff7fd0103 in ?? () from /lib64/ld-linux-x86-64.so.2
...
(gdb) nexti
Warning:
Cannot insert breakpoint 0.
Cannot access memory at address 0x4

0x00007ffff7fd0119 in ?? () from /lib64/ld-linux-x86-64.so.2
(gdb) nexti
0x00007ffff7fd011c in ?? () from /lib64/ld-linux-x86-64.so.2
...
(gdb) nexti
Warning:
Cannot insert breakpoint 0.
Cannot access memory at address 0x1c

0x000055555556ca22 in ?? ()
(gdb) nexti
[Detaching after fork from child process 3829827]
...
[Detaching after fork from child process 3829840]
Hello World![Inferior 1 (process 3819010) exited normally]

So I can use nexti, but cannot use next and obviously cannot insert breakpoints.

I tried -Wl,-no-pie (by running g++ -Wl,-no-pie -ggdb3 -o main main.cpp; adding -no-pie does not change anything) but this option causes a strange linker error:

/usr/bin/ld: cannot find -lgcc_s
/usr/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status

When I google the error, I only found advice to try -no-pie instead of -Wl,-no-pie, and no other solutions. Since debugging C++ programs is very common activity, I feel like I'm missing something obvious but I found no solution so far.

To make it easier to understand what exact commands I use and to make it clear I'm not mixing up directories and to show what versions of g++ and gdb I'm using, here is full terminal log:

$ ls
main.cpp
$ g++ --version | grep Ubuntu
g++ (Ubuntu 9.3.0-10ubuntu2) 9.3.0
$ g++ -ggdb3 -no-pie -o main main.cpp
$ ls
main  main.cpp
$ gdb --version | grep Ubuntu
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
$ readelf -h main | grep 'Type: .*EXEC'
  Type:                              EXEC (Executable file)
$ gdb -q main
Reading symbols from main...
(gdb) start
Temporary breakpoint 1 at 0x401176: file main.cpp, line 3.
Starting program: /tmp/main/main 
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x401176

For completeness, I tried the same without -no-pie:

$ rm main
$ g++ -ggdb3 -o main main.cpp
$ readelf -h main | grep 'Type: .*'
  Type:                              DYN (Shared object file)
$ gdb -q main
Reading symbols from main...
(gdb) start
Temporary breakpoint 1 at 0x1189: file main.cpp, line 3.
Starting program: /tmp/main/main 
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x1189

As you can see the only difference with or without -no-pie is the memory address, but the issue and warnings are the same. Without -no-pie this may be expected, but I do not understand why this is happening if I compiled with -no-pie and what else I can try to solve the issue.

Lissanro Rayen
  • 582
  • 8
  • 17
  • Have you looked at this https://stackoverflow.com/questions/30139356/gdb-cant-access-memory-address-error and this https://stackoverflow.com/a/61541147/6355229, by any chance. Have you checked if you got enough memory and swap space on your Ubuntu 20 host ? – Onkar N Mahajan Nov 13 '20 at 06:26
  • @OnkarNMahajan My RAM is mostly free (14.2G used out of 31.4G) and I have 2G of SSD swap, but as long as there enough RAM, swap space should not matter. So issue mentioned in your links seems to be unrelated to my problem. I'm using g++ 9.3.0 on my workstation. I tried the same C++ example on my old laptop with g++ 4.7.3 and I could run gdb without issues, everything works as expected. But this did not help me find a solution with modern g++. I tried to downgrade and compile with g++ 8.4.0, but the issue is still the same: `-no-pie` has no effect and `-Wl,-no-pie` causes the same `ld` error. – Lissanro Rayen Nov 13 '20 at 08:41
  • Can you check that both g++ and gdb refer to the Ubuntu packages (as opposed to an installation in /usr/local/bin for example) and that they are the latest versions? – Botje Nov 13 '20 at 08:54
  • @Botje Yes they are from Ubuntu packages (in /usr/bin/) since I never compiled g++/gdb myself. I could reproduce the issue on another computer which also has Ubuntu 20.04, so it is not just my workstation. I tried to downgrade gdb to 9.1, but the issue still remained, so I reinstalled gdb 9.2. Currently I'm using gdb 9.2-0ubuntu1~20.04 which is the latest version in Ubuntu LTS. I already tried g++-8 and g++-9, so I decided to try g++-10 as well (by running `g++-10 -ggdb3 -no-pie -o main main.cpp`) but this did not help unfortunately. – Lissanro Rayen Nov 14 '20 at 01:32

1 Answers1

0

This:

g++ -ggdb3 -no-pie -o main main.cpp

should produce a non-PIE executable. You should be able to verify that it non-PIE by looking at readelf -h main | grep 'Type: .*EXEC' (PIE binaries have ET_DYN type).

This:

Temporary breakpoint 1 at 0x1189: file main.cpp, line 3.

is unambiguously a PIE binary (a non-PIE binary will not have any code below 0x40000 on x86_64 Linux).

Conclusion: you are either debugging the wrong binary (e.g. you are compiling main in a different directory from the one in which you are debugging), or you are not telling is the whole story.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • Right below that terminal output I wrote "Without -no-pie result is the same". But now that you mention it, and I tried again, there is a subtle difference: with `-no-pie` the hexadecimal address is different, but all warnings and messages are exactly the same. So I assume I pasted terminal output from an attempt without `-no-pie`. I have updated my question (new text marked by *italic font*), added more information and exact commands I'm using. I'm sure I'm debugging the right binary, and I reproduced the issue on another PC with Ubuntu 20.04. Please let me know if I need to add more info. – Lissanro Rayen Nov 14 '20 at 05:01
  • @LissanroRayen What is the output from `cat /proc/sys/kernel/yama/ptrace_scope`? – Employed Russian Nov 14 '20 at 16:46
  • I got `1` as the output. – Lissanro Rayen Nov 15 '20 at 03:25