Wednesday, 10 December 2014

Debugging with gdb in Code::Blocks

Part 2.1 Debugging the Host code

In my last post I covered setting up the GCC and Brown Deer OpenCL compilers to develop on the Parallella. In this post I'll cover debugging host code. Hopefully I'll be in a position to provide some thoughts on debugging accelerator code at some point in the future. I have to admit to having completely failed to getting the e-gdb epiphany debugger working with OpenCL. I'll discuss what happened at the end of this post.

Again I am indebted to AndyC for his assistance on this process. What I have written below is really just the same process he described ( with pictures.

Setting Up

To start, you need to set up your debugger. This is in a similar vein to setting up a new compiler but simpler. You get there via the Settings | Debugger... menu.

Initially, you get the default settings and some common entries.

To create a new debugger configuration, you press the Create Config button. You could just edit the default entry but I prefer to leave defaults where they are and work of copies. That means that it will be obvious what you have changed if you need to tweak the settings later on.

I gave my host debugger the name Debug Host to make it really obvious. I also created one for the epiphany debugger but, as I mentioned above, that did not lead to a happy outcome.

The critical string is the Executable path: which is:

sudo -E LD_LIBRARY_PATH=/opt/adapteva/esdk/tools/host/lib EPIPHANY_HDF=/opt/adapteva/esdk/bsps/current/platform.hdf /usr/bin/gdb

Similar to the Brown Deer compiler settings, we need to launch gdb as a super user and therefore we have to pass in out environment settings LD_LIBRARY_PATH and EPIPHANY_HDF.

The box is read because Code::Blocks expects a path only and a sudo command leaves it confused. Just leave it red - it will still work.

You also need to make sure that gdb executes in the same directory as the executable - therefore change to it using the Debugger initialization commands. I prefer to use the full path thereby eliminating the possibility that you are not where you think you are and bin/Debug does not exist in the directory tree below you.

Press OK.

The Compiler settings

Now you need to associate the output of the GCC compiler with this debugger configuration.

Go to the Settings | Compiler... menu and (with GNU GCC compiler selected) click the Toolchain executables tab.

Your new debugger configuration will now appear in the Debugger: selection list. Choose it and press OK.

For the debugger to be actually useful, it needs an executable with debugging symbols. To produce these the Produce debugging symbols [-g] option needs to be set when compiling. This can be done either in the Global compiler settings dialog (in the Compiler settings tab shown above) or in the Project build options dialog (via the Project | Build options... menu). If you want to deliver a "Release" version with a slightly smaller executable file, you would use the Project build options with -g set for the Debug version and without -g for the Release version.

Running, Breaking, Examining

Now you have associated your host executable with your Debug Host configuration.

To control the debugging session, there is the Debug menu and the Debug tool bar, shown below in the red box. 

The Debugging windows menu selection is used to select what you want to see during the debugging session. I find the Watches window the most useful. In your Debugger configuration you can ask it to automatically track local variables (way better than Eclipse where most of the values are "Optimized out" most of the time). The funny icon second from the right on the Debug toolbar (circled in red) is a quick way of getting to this selection.

To start a host code debugging session the host build target (in my example Debug) needs to be selected. Then give it somewhere to stop by setting a break point with F5 (in my example on line 80) and then press the red arrow.

After that, you are on your own. Use the Continue, Run to cursor, Next line and Step commands to navigate through your program and the various Debugging windows to figure out what is going on.

What about Epiphany Code?

Well, I don't know.

According to, Epiphany code uses the e-server program as a "host" on the ARM chip. The epiphany sends messages back to e-server which you connect using the remote command. You use the load command to load the code to the epiphany and then set breakpoints etc from the e-dgb command line.

For me, the load command failed every time. When I tried to do the same thing in Code::Blocks the message "(no debugging symbols found)" appeared during the initialization phase and I could not set breakpoints. I checked the compile commands that are sent to the Epiphany SDK and they all had -g set.

If you want to have a go here are my settings (that I pretty much guarantee will not work):

Then set your e-gdb config in your Brown Deer compiler settings.

In your project Build options... 

Note here that ndfork.elf is my build target for my OpenCL code.

And in your Project properties on the very last tab...

But use the IP address of the computer running e-server.

Good luck.

Final Words...

I really hope that someone can figure out how to debug OpenCL code running on the epiphany. I know that Adapteva is doing a lot of work on debugging at the moment and I'm confident that they will find a solution some time soon.