Remote debugging C programs with Eclipse and GDB
On my daily job I write in Java. My last assignment, however, was to patch existing networking program written in C. Last time when I wrote something in C it was 10 years ago.
My IDE of choice is Intellij IDEA, but I’ve tried Eclipse several times, so it’s my backup IDE. I also knew from my collegues who actually practicing C that Eclipse CDT is a one of the best free IDEs for C development available. So I chose Eclipse CDT it as my C IDE. On my desktop PC I use Windows, but the program I was modifying is Unix-only. When I’ve finished writing code I’ve uploaded it using FTP on Linux host (more on that later), and launched make. Of course I had compilation errors, but after several iterations of editing and uploading I finally got binary executable. The program is a network proxy. I’ve started it, sent some messages through it, and, as I expected, it was not working in a right way. I had to debug it to know why.
With Java it is very easy to debug programs remotelly. You ask IDE to do a remote debug, IDE will display to you which command-line options you should provide to java executable. You run your program, then you just ask IDE to attach to your program by specifying remote host and port. All debugging takes place in JVM, and your IDE is a debugging front-end. Easy and straightforward.
Not like this with Eclipse CDT. I’ve opened “Debug configurations” window, and saw “C/C++ Remote Application” option. I chose this option, but I found myself confused with fields I had to specify: location of executable and location of debugger. Even after I’ve downloaded executable from Linux to Windows, I couldn’t start remote debugging. So I decided to abandon this attempt for a while and try manual debugging with GDB.
This debugger was surprisingly easy for me to learn. It is much less cryptic than other Unix tools. Just a dozen of simple and memorable commands which you can print on one small sheet of paper for reference. GDB helped me to quickly found my errors. The only inconvenience is that you have to switch between terminal window where GDB is running and Eclipse CDT window where the code is. However, I still had an impression that remote debugging is actually possible from Eclpse CDT, so I decided to get it working, or at least to have an explanation why it is not possible.
And that’s that I’ve discovered after some long investigation. When C guys say “remote debug” they mean something very-very different from what Java guys mean. To remotelly debug C program you should link it with small chunk of code, which is able to do basic control of program execution (setting breakpoints, pausing-resuming, …) and basic program state examination (memory, stack frames, registers). This chunk of code is called “target side“. It will communicate with main part of a debugger which will be located on another machine. This main part should be able to access a binary image of a program with all it’s symbols. This symbolic info allows debugger to perform all high-level debugging job, like showing contents of local variables, execution of code in line-by-line mode, setting breakpoint on a function. This part of a debugger is called “symbol side+UI“. When you perform a local debug both sides are in a same gdb process. You can also avoid linking with target size code by launching gdbserver which will attach to any process on a host. There is no official name for a protocol between target side and symbol side, so I’ll call it Remote Serial Protocol. It can work over serial cable or over TCP/IP.
So, difference between remote debugging in Java and remote debugging in C is that in case of Java target side and symbol side work on the same machine as program being debugged, and UI is on remote machine. In case of C only target side is located with program being debugged, and symbol side together with UI is on remote machine. Such approach allows debugging programs in cases where normal gdb will not work in local mode. For example, if you have a program for embedded device, which doesn’t have enough memory for full GDB.
But I want to remotelly debug programs with GDB in Java style. C guys will call it “remote UI for GDB”. And I believe that this is possible. Then you debug a program locally with Eclipse CDT, it creates a process for gdb, and intercepts it’s input and output. Then it says to GDB that instead of human-oriented command language it will use for communication a special machine-oriented language called MI (“machine interface”), which is easier to parse. So in order to use Eclipse CDT as a remote UI for GDB I should just launch GDB remotelly and remotelly attach to it’s input and output. I’ll try to make a plugin for Eclipse using my knowledge of Java, because a bunch of questions on StackOverflow shows that such capability is demanded.