Can I debug a program running on a remote target to which I have ssh access, using local source files?
Say I've got a program called hello.c, in directory /home/jla/hello on my home machine.
And on the remote machine I put this same file in a directory /hello, and compile it with
$ gcc -g -o hello hello.c, and then delete the remote hello.c, but leave the executable.
Can I then run gdb locally, get it to ssh in to the remote machine to run the executable, but use the local sources as reference?
Notes:
Annoyingly, the remote machine is very stripped down and can't be altered. It has gdb, but it doesn't have gdbserver
Note that the local and the remote machine have different architectures. In this particular case 64bit and 32bit intel
What I really want to do is run it under emacs/gud. But this would be a great start.
The architectures of remote and local machines matter very little. What matters is how hello, gdb and gdbserver are built.
It sounds from your description that hello is built (on remote machine) for x86_64-linux-gnu
That means you need x86_64-linux-gnu gdbserver, and also a 32-bit GDB that is capable of debugging x86_64 binaries. You should be able to build both, copy gdbserver to the remote machine, and debug "normally".
Related
I'm porting a c++ program from Unix to Win7. The program only does some background computing tasks, it's a command line program. So I use build the program on cygwin with g++ on a 32bit win7 VM.
My target system is a 64bit win7 physical PC. After I copied my program to the target PC, it always fails at a system() call. I need to use system() to run a curl command. This works on my 32bit win7 VM, but always fails on the target 64bit win7 PC.
You may guess if curl command has problem. I would say no. Because I can manually run the curl command from a cmd window. I also tried to system("dir"), it also fails with same error.
On 64bit win7 PC, system() always return 127, error is "Permission denied". Does anybody have idea what the problem is.
Two points. 1) Use a 64-bit VM to build a program for a 64-bit physical machine. You must have a 32-bit or 64-bit cygwin installed on the physical machine to provide the cygwin1.dll with the bitness required by the exe. Use the mingw32 or mingw64 version of the g++ compiler if you don't want to install cygwin on the physical machine. Use the cygwin file command to check the bitness of the exe and to check if it is a cygwin or mingw exe.
2) The windows API provides for a 8-bit return code from a child process to its parent. Using 0 to 127 avoids specifying if the code is signed or unsigned. BTW, there is not dir.exe, it is part of command processor, e.g cmd.exe.
I am using Ubuntu 16.04 on x86_64 workstation, and I'm cross-compiling a small demo program in C++, and deploying it to an embedded linux target running ARM architecture (environment-setup-cortexa9hf-neon-poky-linux-gnueabi, arm-poky-linux-gnueabi-g++).
I am able to successfully do this which gives me a debug session on commandline:
Target:
rpm -ivh gdbserver-7.10.1-r0.cortexa9hf_neon.rpm
gdbserver :9091 ${APPNAME}
Host:
sudo apt-get install gdb-multiarch
gdb-multiarch $APPNAME
target remote 192.168.0.212:9091
...
I can now use gdb-multiarch on commandline!
However from here... I really want to be able to use one of the many gdb frontend tools to provide a GUI to set breakpoints and step through the code (akin to gdbgui, or using vscode and configuring for a debugger). Are there any gdb frontend tools that specifically support gdb-multiarch?
Any tool I try, I believe no matter what it uses base gdb executable and gives this error because of mismatched architecture:
target remote 192.168.0.212:9091
Remote debugging using 192.168.0.212:9091
warning: Architecture rejected target-supplied description
Remote 'g' packet reply is too long: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070fdff7e00000000c0fafc76100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
UPDATE 1 --
I can kinda sorta get this to work using ddd tool:
ddd --eval-command="target remote $MY_TARGET_IP:9091" --debugger gdb-multiarch
However! This is ancient and buggy, and I can't set breakpoints in loaded .so's right now with this.
I tried gdbgui with its options to specify debugger, but that's not currently working either. I filed a feature request report here:
https://github.com/cs01/gdbgui/issues/237
I found a way using gdbgui, but it required me to rebuild gdb from source code against my specific remote target architecture. Details of how I got it to work are here:
https://github.com/cs01/gdbgui/issues/237
Important bits in case the above link breaks:
TLDR Solution:
I was trying to rely on a prebuild gdb-multiarch from ubuntu apt repos, which didn't work. When I decided to download gdb and rebuild from source while configuring for arm-linux-gnuabi target arch.
Build method:
downloaded latest gdb source code
unzip it, go into folder, and build it like this:
./configure --host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --target=arm-linux-gnuabi && make -j8 && sudo make install
Important to note that for my particular remote gdb server it's running on ARM so i had to say target=arm-linux-gnuabi in configure. GDB is building for my PC x86 arch, but it knows when debugging to recognize the target as ARM!
Now, arm-linux-gnuabi-gdb is installed by default to /usr/local/bin ... but you can instead provide prefix=<path> to where you want it to install in ./configure script above.
Using this, I was able to build a secondary copy of gdb called arm-linux-gnuabi-gdb which i could feed to gdbgui like this:
gdbgui -g arm-linux-gnuabi-gdb
From there, I can give gdb commands to connect to my remote gdbserver. I'm having to set breakpoints beforehand. My gdb commands are like this to set a few breakpoints:
set breakpoint pending on
break my_object.cpp:<line number for breakpoint>
b example_function_name
target remote <remote arm machine IP>:<gdbserver port>
c
Works great! This is leaps and bounds better than running gdb on commandline on my remote target.
This is a question from an absolute beginner.
I have a Ubuntu 14.04 host, gdb 7.7.1 installed on it and a project cross-compiled for qnx. I also have a qnx target, that I want to debug my app on.
The instructions on the internet tell me to use either gdb on PC + gdbserver, but I don't have gdbserver installed and I don't think I can compile gdb for qnx. I have something called pdebug. Instructions for qnx tell me that gdb has to have the target qnx command, that it clearly does not posess.
Here's what I've done:
# Assuming that 255.255.255.255 is the target ip and 1234 is the port
# On target
pdebug 1234
On host
gdb
gdb> target remote 255.255.255.255:1234
Then I got a couple of warnings and the gdb> again, as it was normal.
I managed to install a connection between my host and target, but when I hit run in gdb, it tries to run my local copy of the app, instead of running it on target.
There is no way one can debug qnx apps with Ubuntu's gdb.
You have to use qnx's gdb built for the exact this purpose, that is able to run target qnx and many other commands you will need. You have to use qnx's gdb on your host and pdebug on your target and run the same commands you ran:
# on target
pdebug 1234
# on host
ntoarm-gdb
(gdb) file MyQnxApp
(gdb) target qnx 255.255.255.255:1234
(gdb) upload MyQnxApp /mnt/myWorkingDir/MyQnxApp
(gdb) b main
(gdb) r
Then you will see the info about your connection:
Remote debugging using 255.255.255.255:1234
Remote target is <your_endianness>
See this detailed instructions.
I'm trying to debug target with gdb, but get rejection.
(gdb) target remote 10.0.0.2:2345
Remote debugging using 10.0.0.2:2345
warning: Architecture rejected target-supplied description
Remote 'g' packet reply is too long: 00000000ba4eefbe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c04defbe0000000090770940100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
The PC is 64-bit architecture, ubuntu 64-bit
$ uname -a
Linux ubuntu-VirtualBox 3.13.0-24-generic #47-Ubuntu SMP Fri May 2 23:30:00 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
Trying to set different architecture doesn't help.
(gdb) set architecture i386:x86-64:intel
The target architecture is assumed to be i386:x86-64:intel
(gdb) target remote 10.0.0.2:2345
Remote debugging using 10.0.0.2:2345
warning: Architecture rejected target-supplied description
Reply contains invalid hex digit 59
Thanks for any idea,
Ran
I solved this problem using the gdb-multiarch instead of only gdb in my remote machine.
When I was using the gdb I got the following error:
(gdb) target remote 192.168.1.254:9092
Remote debugging using 192.168.1.254:9092
warning: Architecture rejected target-supplied description
Remote 'g' packet reply is too long: 000000002efeffbe34feffbe0000000000000000000000000000000000000000000000000000000000000000000000000000000020fdffbe000000006c1effb6100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
(gdb)
My remote machine is as 32bit Intel Ubuntu V 16.04 and the target machine is an ARM 32bit Linux.
I followed these steps:
1: Keep the same binary executable in remote and target machine (compiled to the target machine and with Debug option, which in GCC is just a "-g" option);
2: Install gdbserver on target machine:
$ sudo apt install gdbserver
3: Install gdb-multiarch in the remote machine:
$ sudo apt install gdb-multiarch
4: Start gdbserver on target Machine:
$ gdbserver localhost:9092 app
where 9092 is the port I chose and app is the name of the binary executable;
5: Start gdb-multiarch on remote machine:
$ gdb-multiarch app
6: Type gbd-multiarch command:
(gdb) target remote 192.168.1.254:9092
where that IP address is the one of my target machine;
After step 6 I got the following screen (instead of the error), and the debug worked well:
(gdb) target remote 192.168.1.254:9092
Remote debugging using 192.168.1.254:9092
Reading /lib/ld-uClibc.so.0 from remote target...
warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.
Reading /lib/ld-uClibc.so.0 from remote target...
Reading symbols from target:/lib/ld-uClibc.so.0...(no debugging symbols found)...done.
0xb6ff1e6c in _start () from target:/lib/ld-uClibc.so.0
(gdb)
i had a similar problem, debugging code on a ARM CortexA5 from openSUSE 13.1 i64. problem occured, when i called the gdbserver on the target and gdb on the laptop, but called gdb on laptop not pointing to the cross compiled binary, but to the one compiled for the laptop (hence i64).
after calling gdb on the laptop pointing to the same, cross compiled binary that is started with gdbserver on the target, all is OK and the error message dissapears.
This means that gdb you called on local machine and gdbserver you called on remote machine is of different architecture, this also means that the application you compiled would be cross-compiled with a compiler supported by your remote machine. So in the local machine you should call the gdb supported by the remote machine. Most probably it would be available in the same path where your cross compiler exists.
I just configured my windows and now I can remote debug from my windows machine to a linux binary.
Be sure your GDB compiled with correct options in your host machine(windows machine in my case). An example:
./gdb-7.4/configure --with-expat --target=x86_64-unknown-linux-gnu --host=i686-pc-mingw32
If you don't have expat download and install it.
You should download the gdb source code. And in same folder you should run configure.
--target option value should be same as the target's gdb banner. Go to target machine(linux in my case) and type gdb you will see something like x86_64-unknown-linux-gnu, you should input this value.
--host option should be i686-pc-mingw32 if you are on windows and using mingw.
I'm trying to compile gdbserver for the purpose of remote debugging on an embedded MIPs platform. I have a cross compiler GCC, binutils, and gdb compiled for the platform.
My configure command is as so
../gdb-7.6/gdb/gdbserver/configure --target=$TARGET --prefix=$PREFIX --target=$TARGET --build=x86_64-unknown-linux-gnu
However, it keeps building with my system compiler rather than the cross-compiler, so I get errors. How can I configure this to build with the cross compiler so that I can run gdbserver on the embedded platform and then debug it from my PC?
You want --host, not --target.