WebKit is an engine that uses multiple processes and multiple threads at runtime. There are some very useful generic instructions on how to debug one of its processes on Linux (with focus on the GTK port) in this wiki page. They work pretty well when WebKit is built using the Flatpak SDK and the scripts and gdbserver is installed in the system, but I faced some problems when I wanted to built WebKit with CMake having custom build and installation directories. So in this post, I’m going to describe the easiest way I’ve found so far to debug it when SDK is not being used and a gdbserver is not present in the system. I’ve found this simple solution after having tried a combination of tricks from the WebKit wiki instructions, GDB documentation and a discussion with my colleages at Igalia.
Building WebKit with CMake
To build WebKit I follow the steps I’ve described in my previous post for WPE, and when I build the GTK port I simply set the PORT (
-DPORT CMake option) to be GTK instead of WPE.
Supposing that the WebKit MiniBrowser is used for debugging the WebGL or HTML output, there are different ways to use GDB. You can either start the program with GDB attached ( gdb --args ./build/bin/MiniBrowser bar.html) or start MiniBrowser and then attach the WebProcess to GDB. Not all the settings I’ll list below are strictly required in both cases but having them set doesn’t harm.
I opened my global
$HOME/.gdbinit and included the WebKit
.gdbinit path as a safe path:
Then, I added the following lines in the WebKit/.gdbinit:
set follow-fork-mode child
set detach-on-fork off
What they are for:
set follow-fork-mode child:
The new process is debugged after a fork. The parent process runs unimpeded.
set detach-on-fork off:
In this mode GDB will be attached to both parent and child processes after a call to fork() or vfork(). One can use the info inferiors command to show details and the inferior command to switch between them.
Running WebKit with GDB and setting a breakpoint in WebGL code.
I opened a terminal (where I’ve set all the required environment variables to build and run WebKit, see my previous post on building WebKit) and ran Minibrowser from the build directory, for me this directory is
WebKit/build/ (if you use the flatpak SDK it will be the standard build directory
WebKitBuild and you can modify the paths accordingly):
bar.html was a customized WebGL test I wanted to debug (most standard WebGL tests can be found under
I switched to a different terminal where the environment was identical to the first terminal’s environment (important!):
As I wanted to debug WebGL, I’ve first found the process that contains the WebGL calls. If you check the pstree output, you will notice that WebKit forks 2 processes: the WebKitWebProces and the WebKitNetworkPr that are the Web and the Network processes respectively.
WebGL is part of the WebProcess (you can tell that from the code). So, in order to debug graphics code I had to attach the WebProcess to GDB.
This is how to do it:
1. Enter the directory where you would run MiniBrowser! This is important otherwise some symbols might not be found!!! I run MiniBrowser from my checkout root directory, so the command was:
2. Find the pid of the WebProcess:
pgrep -i webproc
a pid will be returned for example 29086
3. Attach GDB to this process:
gdb ./build/bin/MiniBrowser 29086
Note that you must run
gdb and use the path to MiniBrowser that is running, the same way you’d set it to start MiniBrowser inside GDB and simply add the pid at the end. No other parameters should be needed as MiniBrowser is supposed to run at this moment.
4. Set a breakpoint the “usual” way, eg:
5. Press continue (
c in GDB) and reload the webpage in MiniBrowser. You will see that the program stopped when it reached the breakpoint:
Note that symbols are loaded from my custom installation directory
~/igalia/install where I install every WebKit dependency I need to debug myself as well as WebKit itself! This is why it is important to be in the correct directory when you attach the WebProcess to GDB.
You might not have to worry about this when you’ve built WebKit using the flatpak SDK and simply follow the instructions from the wiki page I’ve mentioned before, but if you do everything manually, running
gdb -p on a new terminal without the path to MiniBrowser and the same environment setup might attach the process, but GDB won’t be able to detect all the available debugging symbols.
If you build WebKit the recommended way (using the flatpak SDK) you might also want to try setting the prefix
WEB_PROCESS_CMD_PREFIX from instructions. Building WebKit inside “non-standard” build directories with CMake and the option
-DDEVELOPER_MODE=ON is tricky as some python scripts involved in the process might crash or complain. In case you build with CMake and don’t use the “standard” paths you’d rather use the steps I’ve just described.
Something else I tried and worked for me was to attach the parent process to gdb ( gdb --args ./build/bin/MiniBrowser bar.html) and switch processes using inferior <num_process>.
BUT! there were other issues when switching between processes and threads: a process or a thread could crash from a bug while I was debugging another, and then I wasn’t always able to switch to it. Also, always following the child process would by default follow the network process and I’d have to switch to the web later. So, I gave up and chose the simple method I described above.
And at least for debugging WebGL tests, attaching the WebProcess to gdb without using the gdbserver or having to set the prefix works well for me so far.
: WebKitGTK Debugging https://trac.webkit.org/wiki/WebKitGTK/Debugging
: Environment Variables that can be used for debugging: https://trac.webkit.org/wiki/EnvironmentVariables (not used in this post, but handy in general!)
: How to build WebKit with CMake (change the port to GTK instead of WPE for GTK builds): Build WebKit/WPE on Linux/X11
See you next time!