Debugging an Application¶
Once an application has been built and installed, it may be necessary to debug
it from within the sandbox where it runs. By default, each flatpak that is
built has a corresponding .Debug
runtime extension that provides debugging
information for the application. This cannot be exported as a binary bundle in
the same way as for application flatpaks, so we first need to find another way
to install it.
Installing the Debug Package¶
In Installing from a Local Repository, we installed an application from a local repository by adding its repository to those registered with Flatpak on the system:
flatpak remote-add --no-gpg-verify my-local-repo myrepo
Once this repository has been added with the my-local-repo
remote, we can
list its contents:
flatpak remote-ls my-local-repo -a
The -a
option ensures that the debug runtime extension is also listed. For
the libhandy example we have been using, the above command produces this
output:
Ref
sm.puri.Handy.Demo
sm.puri.Handy.Demo.Debug
We install the application from the repository in the normal way:
flatpak install my-local-repo sm.puri.Handy.Demo
In addition to this, we install the debug runtime extension for the application:
flatpak install my-local-repo sm.puri.Handy.Demo.Debug
This allows us to access debugging symbols in the sandbox.
Running a Debug Shell¶
A debugging environment can be created by starting a shell inside the sandbox:
flatpak run --devel --command=bash sm.puri.Handy.Demo
The sandboxed shell will start running and will show a prompt like this:
bash-4.4$
From this point the application can be run as normal by running the example
executable, either relying on the PATH
environment variable or running it
using its full path:
bash-4.4$ /app/bin/example
For some kinds of applications, simply being able to run the code from the command line in the sandbox is useful. However, when using compiled languages, you may need to perform lower level debugging.
Using GDB in the Sandbox¶
We can also run the application using gdb
for debugging:
bash-4.4$ gdb /app/bin/example
So, for example, we could set a breakpoint on execution of the
main
function:
(gdb) b main
Breakpoint 1 at 0x3510
(gdb) r
Starting program: /app/bin/example
Although this is useful if we want to simply pause execution at a certain point, we need more information if we want to do more detailed debugging.
Running gdb
again, we load the debugging symbols from the relevant file:
(gdb) symbol-file /app/lib/debug/bin/example.debug
Reading symbols from /app/lib/debug/bin/example.debug...done.
We can now set a breakpoint at the start of the main
function and run the
application:
(gdb) b main
Breakpoint 1 at 0x3650: file ../examples/example.c, line 33.
(gdb) r
Starting program: /app/bin/example
Breakpoint 1, main (argc=1, argv=0x7fffffffde98) at ../examples/example.c:33
33 {
With the debugging symbols loaded, once the breakpoint is reached we can list the source code for the function:
(gdb) l
28 }
29
30 int
31 main (int argc,
32 char **argv)
33 {
34 GtkApplication *app;
35 int status;
36
37 hdy_init (&argc, &argv);
GDB can be used as normal to debug the application.
Further Reading¶
The Flatpak debugging documentation provides more ways to debug sandboxed applications.