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 I’ve used C was 10 years ago. I took this assignment since I was pretty confident about myself, because I frequently refresh my knowledge of C by reading a book “Unix network programming”, for example. By the way, I strongly believe that this book is the only must-read book for any Java programmer who writes networking software regardless if he uses either IO or NIO.

My IDE of choice is Intellij IDEA, but I’ve evaluated Eclipse several times, so I know how it works. I also knew that Eclipse CDT is a one of the best free IDEs for C development available, so I chose it as my C IDE. On my desktop PC I use Windows, but software 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 some 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 just ask IDE to do a remote debug, IDE will display to you what command-line options you should add to java executable, then you just type host and port, and that’s it. 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. Using GDB I 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 code is. Also 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. Debugger should be able to access an 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 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.

Some links:

http://sourceware.org/gdb/current/onlinedocs/gdb/Remote-Protocol.html#Remote-Protocol

http://sourceware.org/gdb/current/onlinedocs/gdb/GDB_002fMI.html#GDB_002fMI

http://sourceware.org/gdb/current/onlinedocs/gdbint/Overall-Structure.html#Overall-Structure

http://dev.eclipse.org/mhonarc/lists/dsdp-tm-dev/msg01369.html

http://wiki.eclipse.org/TM_and_RSE_FAQ#How_can_I_do_Remote_Debugging_with_CDT.3F

http://www.ibm.com/developerworks/library/os-eclipse-cdt-debug2/index.html

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s


Follow

Get every new post delivered to your Inbox.