Debugging WebKit
Processes
The WebKit system framework exports two public APIs on both Mac and iOS: a modern, multi-process API (WKWebView) and a legacy single-process API (WebView on Mac and UIWebView on iOS). Unlike the legacy API that executes within a single-process the modern WebKit API functionality is segregated between the UIProcess (e.g. Safari) and the following auxiliary processes:
Colloquial name | Process name | Purpose |
---|---|---|
WebProcess | com.apple.WebKit.WebContent.Development | Core engine |
NetworkProcess | com.apple.WebKit.Networking.Development | Networking |
StorageProcess | com.apple.WebKit.Storage.Development | IndexedDB/Service Worker Storage |
The code base is organized around these process boundaries. You will need to attach to the appropriate process(es) to debug an issue.
Logging
WebKit emits a lot of logging by default. You can change the verbosity of this logging by setting the environment variable OS_ACTIVITY_MODE
to one of the following values:
Value | Description |
---|---|
disable | Disables all logging and activity tracing (cannot be overridden) |
off | Turn all logging and activity tracing on process launch (may be overridden by tools) |
info | Info level logging |
debug | Debug level logging |
iOS Simulator
In Terminal, run the following command to attach to the currently running MobileSafari:
xcrun --sdk iphonesimulator lldb --attach-name MobileSafari
Use the --wait-for
option to wait for MobileSafari to be launched and attach to it as early as possible.
xcrun --sdk iphonesimulator lldb --attach-name MobileSafari --wait-for
Substitute com.apple.WebKit.WebContent.Development
for the value of --attach-name
to debug the WebProcess.
macOS
Internal Debug Menu
There is a Debug menu that can be enabled in Safari, and it exposes many useful options to help with debugging. To enable it, run the following in Terminal:
defaults write com.apple.Safari IncludeInternalDebugMenu 1
Debugging UIProcess from Terminal
Run script debug-safari
or debug-minibrowser
. It will start the debugger with Safari or MiniBrowser as the target, respectively. At the debugger prompt, enter run to start the process.
Debugging using Xcode
To debug from within Xcode, you can use the WebKit workspace. Ensure that the Products, Intermediates, and Index Datastore locations for the workspace match those used by build-webkit by choosing File > Workspace Settings and clicking the Advanced button, selecting Custom, Relative to Workspace, and entering WebKitBuild for Products, Intermediates and Index Datastore. Note that if you have specified a custom build location in Xcode preferences, then you don’t need to do this.
Debugging UIProcess
- Open the WebKit Xcode workspace
- Set the project’s build products location
To find the WebKit you built, Xcode needs to know the build products location that
build-webkit
used. You can set the build products location in the project’s build settings editor. -
Set the project’s active scheme
Xcode also needs to know the build configuration you used. You can set the active scheme from the workspace window.
-
Add Safari to the project’s active scheme
Choose Edit Scheme from scheme pop-up menu. In the leftmost pane of the window, choose Run. In the Info pane, choose Other from the Executable pop-up menu. Then select
/Applications/Safari.app
. -
Launch the debugger
In the workspace window, click the Run button.
-
See Debugging Tools for more information on using Xcode to debug software on macOS.
Debugging WebProcess
Current versions of Safari use a process for each tab, so it is easy to end up with a new WebProcess and have to reattach. If you enable the Internal Debug Menu as outlined above, you can have Safari display the Process ID of the WebProcess for each tab. Simply go to Debug > Miscellaneous Flags and select Show Web Process IDs In Page Titles. You should now see something like [WP 60737]
in the title of every web page you navigate to, and 60737 is the Process ID of the WebProcess backing that tab.
Open the WebKit workspace and choose “All Source (target WebProcess)” from the Scheme pop-up menu in the toolbar, then choose Product > Run. If WebKit is already built, it is quicker to choose Product > Perform Action > Run Without Building