Remote debugging WebKit GTK with GDB

Debugging complex applications can be a daunting task, especially when dealing with web browsers like WebKit. Armed with the right environment and tools, you can navigate through the labyrinth of code to identify and fix issues.

However, something curious happens to me. I’ve gone through these same steps many times before and I always face the same situation when I need to debug some issue: How was it? What was it that I needed to setup the debug environment? What was the order? The name of that variable? … Always the same, always the same promise when I finally find the answers (“I will write it down somewhere for the next time”) and never fulfilled … until today.

In this post, we’ll walk you through a real-world example of live debugging WebKit using GDB (GNU Debugger).

Introduction to the Setup

In this scenario, we’ll delve into a command-line snippet that initiates a debugging session for WebKit using GDB. The code snippet looks like this:

WEB_PROCESS_CMD_PREFIX='/usr/bin/gdbserver --no-startup-with-shell localhost:9090'  \
WAYLAND_DISPLAY=wayland-1 \
XDG_RUNTIME_DIR=/run/user/1000 \
WEBKIT_INJECTED_BUNDLE_PATH=/home/psaavedra/local/git/webkit-gtk/WebKit/WebKitBuild/Debug/lib  \
WEBKIT_EXEC_PATH=/home/psaavedra/local/git/webkit-gtk/WebKit/WebKitBuild/Debug/bin  \
LD_LIBRARY_PATH=/home/psaavedra/local/git/webkit-gtk/WebKit/WebKitBuild/Debug/lib  \
COG_MODULEDIR=./WebKitBuild/Debug/Tools/cog-prefix/src/cog-build/platform  \
gdb --args ./WebKitBuild/Debug/Tools/cog-prefix/src/cog-build/launcher/cog -P wl https://www.igalia.com

Launching the Debugger

  1. Setting Up GDB Environment: The first part of the snippet configures the environment for GDB. It sets several environment variables that guide GDB’s behavior during debugging. For instance, it tells GDB to start a gdbserver on localhost:9090, defines the display server (Wayland), and specifies various paths for required libraries and executable files.
  2. Starting GDB: Next, the snippet runs the GDB command itself. It launches GDB in the terminal. The -args flag indicates that the subsequent command and arguments should be executed within the GDB session.

Getting Started with GDB Commands

Once the GDB session starts, you’re presented with a GDB command prompt. Now, let’s walk through the commands used in the debugging session:

  1. Setting Up GDB Environment in GDB: While inside GDB, you can fine-tune the environment further. For example, you can set the system root directory and library search paths using the set sysroot and set solib-search-path commands.
 $ gdb
set sysroot /
set solib-search-path /lib/:/usr/lib:/usr/lib32:/usr/lib64:/home/psaavedra/local/git/webkit-gtk/WebKit/WebKitBuild/Debug/lib
  1. Specifying Source Code Directory: The directory command is used to inform GDB about the location of source code files. This helps GDB locate and display source code lines during debugging.
directory /home/psaavedra/local/git/webkit-gtk/WebKit/Source
  1. Loading Shared Libraries: .
info sharedlibrary 
add-symbol-file /home/psaavedra/local/git/webkit-gtk/WebKit/WebKitBuild/Debug/lib/libWPEWebKit-2.0.so.0
add-symbol-file /home/psaavedra/local/git/webkit-gtk/WebKit/WebKitBuild/Debug/bin/WPEWebProcess
add-symbol-file /home/psaavedra/install/lib/x86_64-linux-gnu/libWPEBackend-fdo-1.0.so

The info sharedlibrary command lists loaded shared libraries. In this case, additional libraries are loaded using the add-symbol-file command. These libraries’ paths are explicitly provided to help GDB locate symbols for debugging

  1. Connecting to GDB Server:
target remote localhost:9090

The target remote command connects GDB to the gdbserver started earlier. This establishes a remote debugging session, allowing you to debug code running on another machine.

Setting Breakpoints and Running the Debugger

  1. Setting Breakpoints: Debugging is most effective when you can pause execution at specific points. The b command is used to set breakpoints. You can specify functions or exact source code locations where you want execution to halt:
b LayerTreeHost::willRenderFrame

b /home/psaavedra/local/git/webkit-(gdb) gtk/WebKit/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp:407
b /home/psaavedra/local/git/webkit-gtk/WebKit/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp:412
b /home/psaavedra/local/git/webkit-gtk/WebKit/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp:380
b /home/psaavedra/local/git/webkit-gtk/WebKit/Source/WebKit/WebProcess/WebPage/libwpe/AcceleratedSurfaceLibWPE.cpp:105
b /home/psaavedra/local/git/webkit-gtk/WebKit/Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.cpp:89

Alternatively, you can set breakpoints based on symbol names:

b wl_buffer_send_release
b wpe_view_backend_exportable_fdo_egl_dispatch_release_exported_image

info breakpoints

The info breakpoints command provides a list of all set breakpoints. This gives you an overview of the breakpoints you’ve configured.

  1. Running the Debugger: Once breakpoints are in place, use the run command to start execution. The application will run until a breakpoint is hit, at which point it will pause, allowing you to inspect the program state and variables.
(gdb) run

Long story short

Debugging WebKit is not far away in complex than any other application but demands setting up the right environment variables, loading necessary libraries, and configuring breakpoints to halt execution at crucial points. GDB still enables you to dive deep into the application’s codebase and identify issues.

Armed with these insights, you can run your first step for fixing bugs, enhance performance, and contribute to the improvement of large-scale software project as WebKit it is. So, the next time you ( me) encounter a perplexing issue, remember this guide to effectively navigate the debugging process. Happy debugging!

Leave a comment