Debugging and contributing on Alpine Linux

In one of my previous posts I explained my renewed router / home server. One task of the box is to serve video/audio content on DLNA. One of the easy selection in this area is minidlna to do the streaming. So I grabbed the first working minidlna docker container, which in practice Alpine Linux based and started to use that.

Our happiness was not instant using the new configuration. Minidlna was never rock-solid, but in this setup it definitely crashed from time to time. As I inspected it crashed every single time when something added to the media library, in practice when the download completed. After checking minidlna issues, I have not found anything useful, so decided to locate the exact problem.

Get our hands dirty

The investigation started with installing the gdb debugger inside the minidlna container. Since the project is written in pure C, that is the default way of doing this. Let’s create a container instance for the hacking and install minidlna + gdb.

With the new image, running minidlna with gdb I reproduced the issue. A lot of basic gdb usage and cheat sheet can be found out there, will not go into details here. As it is expected, it exactly shows nothing else than the type of the exception, which was naturally a Segmentation Fault. Something happened here what is not user error for sure :). Linux distributions are usually not shipping debugging symbols in the default production binary packages, so gdb showed only cryptic memory address in the stack trace. You can actually check this right from the binary with the file tool:

The main point is the notation that it is stripped. This means you have no symbol and source code information from compilation time.

That was the momentum when I had to get familiar with Alpine Linux build system, because the present minidlna container image used that as a base. Actually it was already familiar to me on some level. I use it @work, it is popular for it’s extreme small size, etc. BTW size is the key why it is popular to build docker images on top of it. While mainstream full-blown distributions are consuming hundred(s) of MBs because of the lot usual tools in there by default, but Alpine base image is exactly 3.96MB today :).

Recompile an Alpine package

After spinning the Google, I found some intro page like this on how to recompile things. So abuild is the thing here. The whole compiling toolchain can be installed with a single command:

Apk it the package manager for alpine. You might call also “apk update” before the very first apk . Abuild is the tool for doing everything around package maintenance except that it won’t tell you how to get the package :(. One example of my failures:

Basically that is the response for anything until you get the right APKBUILD, whatever it is. Actually it is the main descriptor of the packages, one for each. After further utilizing the most famous search engines, I found out that Alpine guys are collecting their APKBUILDs and related files in a git repository. This is the aports. The easiest way to get is to clone the whole repo with git. Let’s do it after creating a regular user (+add it to the abuild group) for building stuff:

Depending on the release of the alpine release you might change to some other branch in the repo (like 3.5). Also, add your user to the sudoers as the tools are trying to use sudo it when root privileges are needed.

Create a key to be able to generate signed packages and get into to the minidlna directory:

Now we are finally ready to build the repackage the package. Before that you need to update the checksums in the APKBUILD file:

Somewhere in the middle you can inspect that the code is actually compiled. The final package can be found in ~/packages… .

Let’s install it:

Get debugging symbols in

Now we still have stripped end-result (you can check it with the file command after installing it with “apk add file“). We can change the compilation to let the debug symbols stay in the binary. It is about to add an option to the APKBUILD file of the package:

If now you recompile and re-install the package, the file command confirms that we are getting closer:

So we have the not stripped binary. As I reproduced the problem with this, I got the correct stack trace for real debugging.


Let’s jump over the actual correction for now. The point is that the aports library actually does not contain the main source tree of the project, it only refers to the original source repo. What it really contains is:

  • The build configuration for the alpine system (the APKBUILD file).
  • Sample configuration or other files for the target system to be used after installation.
  • Installation, upgrade hooks for the package management events.
  • Finally the most important: the patches. If the project needs some source patches in order to run correctly on Alpine linux, those are added to this repo and applied during compilation.

Generally, if the problem happened to be a real bug in the software, you might end up with a patch for the software what fixes the issue. If you decide to contribute it back to the upstream, there can be two targets. If if is a generic bug in the software, you should send it to the author. In my case the correction was a special one, because the bug is alpine specific. It crashed because of the extreme small size of the child threads of a process. So my patch belongs to the aports repo. I sent the patch to their mail based patch handling system and after some mail exchange with the package maintainer it got approved. You can be much smarter by sending a patch directly to github, as I realized since than that they accept contribution there also :).

My contribution is finally in the stable 3.6 realease of the alpine distribution and I can use it without issues, hurray :).

Some further references for the alpine package build system:



Write a Comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">