Debugging From Inside a Docker Container

One of the most often asked questions we get when discussing moving the build environment for an embedded project into a docker image/container is "how do I do debugging"? This is a valid question since most engineers will be using a debug IDE on their host machine (e.g MacOs/Windows) and not inside of their Docker container that is doing the build. This creates two main problems when using an IDE on the host machine:

  1. When you build a project with the {% c-line %}-g{% c-line-end %} flag, source code info gets embedded into the resulting debug image. This is what enables the debugger to step through code and set breakpoints. However when you build the project inside of a Docker container, the info that gets embedded into the image is the container's file system, not the host's file system. When the debugger tries to parse the debug image and find the corresponding {% c-line %}.c{% c-line-end %} and {% c-line %}.h{% c-line-end %} files it can't, unless the file system in both the container and host machine is identical, which is almost never the case.
  2. Because the cross-compiler used to build the project is installed in the Docker container, any system headers(.e.g {% c-line %}stdint.h{% c-line-end %}) that are included with the cross-compiler are not available to the host IDE. This isn't as big of an issue as being able to parse the source code, but is still annoying.

If the project lives on the host machine's file systems and it is being mounted into the Docker container before being built, one easy solution to point 1. above is to include the compile flag {% c-line %}-file-prefix-map=OLD=NEW{% c-line-end %} in your build. This instructs the compiler to swap out the Docker container's file prefix ({% c-line %}OLD{% c-line-end %}) with the host machine's prefix ({% c-line %}NEW{% c-line-end %}) allowing the host IDE to parse the debug image. Unfortunately this doesn't solve the issue of system files that only live inside the Docker container.

Fortunately VSCode has a great extension that allows developers to connect VSCode running on the host machine to a running docker container. This is great because it effectively solves both issues, and makes developing inside a Docker container feel almost identical to developing directly on the host machine, while still giving you all the flexibility and advantages of having your entire build environment in a Docker container.

Here is more information on using VSCode to develop inside a container:

And here's a quick video of what that looks like in practice using the VSCode extension {% c-line %}C/C++{% c-line-end %} and the Lager debugger:

Want to stay up to date on the future of firmware? Join our mailing list.