I am trying to step into a method within a class through gdb. So currently, my gdb works for standalone functions. I can step into them fine, however, when I try to step into a method, it doesn't step into it. Here's my script:
#include <iostream>
using namespace std;
class test{
public:
void say_hello(){
cout<< "hello";
}
};
int main(){
test t;
t.say_hello();
return 0;
}
Here's what gdb spits out right after I press run the "run" command.
warning: `/BinaryCache/coreTLS/coreTLS-35.40.1~1/Objects/coretls.build/coretls.build/Objects-normal/x86_64/system_coretls_vers.o': can't open to read symbols: No such file or directory.
warning: Could not open OSO archive file "/BinaryCache/coreTLS/coreTLS-35.40.1~1/Symbols/BuiltProducts/libcoretls_ciphersuites.a"
warning: Could not open OSO archive file "/BinaryCache/coreTLS/coreTLS-35.40.1~1/Symbols/BuiltProducts/libcoretls_handshake.a"
warning: Could not open OSO archive file "/BinaryCache/coreTLS/coreTLS-35.40.1~1/Symbols/BuiltProducts/libcoretls_record.a"
warning: Could not open OSO archive file "/BinaryCache/coreTLS/coreTLS-35.40.1~1/Symbols/BuiltProducts/libcoretls_stream_parser.a"
Here's what happens when I try stepping:
Breakpoint 1, main () at test.cpp:13
13 t.say_hello();
(gdb) s
14 return 0;
(gdb)
0x00007fff91eec5c9 in start () from /usr/lib/system/libdyld.dylib
(gdb)
Single stepping until exit from function start,
which has no line number information.
hello[Inferior 1 (process 9896) exited normally]
If it makes any difference, when I run g++ --version, I get Apple LLVM version 7.0.0.
Thanks.
By default, GDB steps over functions which contain no debug information. But it is clear that you have it, since you see "at test.cpp:13" when you break on main().
My guess is that you have an older version of GDB that does not fully understand symbols generated by your compiler, and thus fails to step into member functions.
If I were you, I would first try to debug your program with lldb (since you already have it on your system) and see if it goes well. And if it does, then the issue is indeed with an old GDB, so I would upgrade to a later version.
Related
The following workflow worked for me at one point, and then it suddenly stopped working. I'd like to figure out why and get it to work again.
on the host, build binary for target system with debug information
send the stripped version of the binary to the target system
on the target, run the binary with gdbserver :6006 mybinary args...
on the host, run gdb-multiarch mybinary. This is the unstripped version. It shows that it loaded symbols from the local binary.
At the gdb prompt, run target remote <ip_of_target>:6006
Then, if I say b main, it inserts a breakpoint at an unrelocated address like 0x621730, which is the offset of the main function in the local binary, whereas it should be added on top of the VM address the remote binary is loaded at (0x5555555000 in this case.) Obviously the unrelocated address doesn't work.
So step 6 was working at one point. I don't know what I'm doing now differently to make the relocation no longer work. Help would be appreciated.
Version of gdbserver and that of host gdb are both Ubuntu 8.1.1-0ubuntu1. The remote system is aarch64.
So step 6 was working at one point. I don't know what I'm doing now differently to make the relocation no longer work.
I suspect that you have upgraded your toolchain, and that your upgraded toolchain produces a Position-Independent Executable mybinary by default, where the old toolchain didn't.
Try adding -no-pie to the link line of mybinary.
Obviously the unrelocated address doesn't work.
Actually, this does work for local debugging -- GDB is smart enough to realize that the code got loaded at a different address:
gdb -q a.out
Reading symbols from a.out...
(gdb) b main
Breakpoint 1 at 0x112d: file t.c, line 1. <<< Note: unrelocated address
(gdb) run
Starting program: /tmp/a.out
Breakpoint 1, main () at t.c:1
1 int main() {return 0; }
(gdb) p/x $pc
$1 = 0x55555555512d <<< Note: breakpoint worked.
It's possible that remote debugging doesn't work, although this worked fine for me using GDB-10.0:
strip a.out -o b.out
gdbserver :6006 ./b.out
Process ./b.out created; pid = 239653
Listening on port 6006
... in another window:
gdb -q ./a.out
Reading symbols from ./a.out...
(gdb) target remote :6006
Remote debugging using :6006
Reading /lib64/ld-linux-x86-64.so.2 from remote target...
warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.
Reading /lib64/ld-linux-x86-64.so.2 from remote target...
Reading symbols from target:/lib64/ld-linux-x86-64.so.2...
Reading symbols from /usr/lib/debug/.build-id/a8/97a1105e21dd270bd418fe58c441700a6d8ec5.debug...
0x00007ffff7fe4940 in _start () from target:/lib64/ld-linux-x86-64.so.2
(gdb) b main
Breakpoint 1 at 0x55555555512d: file t.c, line 1.
Lets take this very simple program here for example:
// test.cpp
#include <string>
#include <iostream>
using namespace std;
int main() {
string str = "Hello";
cout << str << endl;
return 0;
}
now I compile this code with g++ compiler:
g++ -g test.cpp -o test.exe
now I am trying to debug this with gdb:
gdb test.exe
after I set breakpoint on main and then reach the line return 0, I try to see what is in the string str. But I cannot print it in the console. It says <error reading variable>. Not only in gdb console, even Visual Studio Code UI using gdb gives the same output.
Here is a screenshot of my console:
I have searched for this everywhere and the only relevant question I found was this, which did not work.
I also found this post on github VS Code repo issues. The fix suggested there might work I am not sure, I cannot find the setting that he suggested on my Windows 11 machine.
How do I read the value in the string in debug mode?
Edit
After #ssbssa suggested me to update my gcc, I used MSYS2 to get the latest gcc, g++, and gdb versions. Now I have gdb 12.1. Now it is not showing the old error anymore but now it says "Converting character sets: Invalid argument". Still struggling to get it to work.
First run your program with gdb like so:
gdb test.exe
Now inside the command line interface run the command:
set charset UTF-8
This should temporarily fix your problem. The only inconvenience might be that you need to run this line every time you debug on your command prompt with GDB.
I noticed that you are also using Visual Studio Code. You can install C++ extensions for VS Code and there you can add the command set charset UTF-8 in the launch.json setupCommands array as shown here. This way you can debug your application faster.
I'm currently running a file manager program that abruptly crashed with a segmentation fault and dumped a core file. So I used gdb to debug the core file as:
gdb /path/to/executable /path/to/core
The program which I was running is written in C++. When I ran GDB and tried to print the source lines using "list", I got the following error:
(gdb) bt
#0 0x0000000000554286 in
MyFSEventManager::AddEvent(wxFileSystemWatcherEvent&) ()
#1 0x00000000005ab2e8 in
MyGenericDirCtrl::OnFileWatcherEvent(wxFileSystemWatcherEvent&) ()
(gdb) f 0
#0 0x0000000000554286 in
MyFSEventManager::AddEvent(wxFileSystemWatcherEvent&) ()
(gdb) l
1 /build/glib2.0-prJhLS/glib2.0-2.48.2/./glib/gmain.c: No such file or directory.
Why does gdb say this "/build/glib2.0-prJhLS/glib2.0-2.48.2/./glib/gmain.c: No such file or directory." I do not hit this issue with some other programs that I've debugged using gdb.
The operating system used is Ubuntu 16.04 running on Oracle virtual box. I think may be the gdb symbols were not loaded. I'm not sure why since I compiled the program using the "-g" option. I really need to know the source lines where the code crashes via gdb.
Any suggestions?
EDIT: changes after suggestions from Employed Russian
I was compiling my main using "-g" option and linking it to "existing" object files which were obviously not compiled using "-g" so when the core dumped, I could not see the source for these files. So I went ahead and recompiled those files with "-g" option and reproduced the core dump. It's able to show me the source lines now.
Why does gdb say this "/build/glib2.0-prJhLS/glib2.0-2.48.2/./glib/gmain.c: No such file or directory."
Because you really don't have that file on your system.
I think may be the gdb symbols were not loaded
GDB did load debug symbols for glib, but not for your main executable.
I'm not sure why since I compiled the program using the "-g" option.
Since we don't have your compile and link lines, we can't tell exactly what's wrong, but some of the common issues are:
You have a "stray" -s or -Wl,-s on your link line (this strips debug info from the resulting binary).
You have -g when compiling your main.c, but not when compiling the source in which MyFSEventManager::AddEvent() is defined
P.S.
(gdb) bt
This doesn't seem to be the complete output from bt command. Always try to paste complete outputs as it makes helping easier :)
Is there anyway to debug a link error or any kind of error that may occur before the execution of the main() function using GDB?
Is there anyway to debug a link error
Presumably you are asking about runtime link error (e.g. `error: libfoo.so: no such file or directory'), and not about (static) link step of your build process.
The trick is to set a breakpoint on exit or (exit_group on Linux) system call with e.g. catch syscall exit. You will then be stopped inside ld.so at the point where it gives up running your binary.
or any kind of error that may occur before the execution of the main() function using GDB?
Any other kind of error, e.g. SIGSEGV can be debugged "normally" -- for signal you don't need to do anything at all -- GDB will just stop. For other errors, just set a breakpoint as usual.
On way to debug initialization code (even if you don't have symbols) goes like this:
gdb somebinary
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
etc.
info file
Symbols from "somebinary".
Local exec file:
`/somebinary', file type elf64-x86-64.
Entry point: 0x4045a4, etc.
break *0x4045a4
run
...Breakpoint 1, 0x00000000004045a4 in ?? ()
From here on you can proceed as usual.
I have this C function in a huge code:
void test() {
char *arg[] = {"/bin/sh", 0};
execve("/bin/sh", arg, 0);
}
I am trying to debug this code using gdb
(gdb) call test()
process 1948 is executing new program: /bin/dash
warning: Selected architecture i386:x86-64 is not compatible with reported target architecture i386
Architecture of file not recognized.
An error occurred while in a function called from GDB.
Evaluation of the expression containing the function
(test) will be abandoned.
When the function is done executing, GDB will silently stop.
Hence the shell is not spawning. How to go about it?
gdb isn't allowing you to exec a binary with a different architecture, even though it's compatible on your platform. The same occurs if you try to exec a 32bit executable from a 64bit one. This occurs on the latest version (7.5.1) of gdb as well.
If you can compile your code as 32bit without it causing other problems, it would be a workaround.
As per Hasturkun's comment, there is a patch available here.