1# Debugging Tips 2 3There are many ways to debug ANGLE using generic or platform-dependent tools. Here is a list of tips 4on how to use them. 5 6## Running ANGLE under apitrace on Linux 7 8[Apitrace](http://apitrace.github.io/) captures traces of OpenGL commands for later analysis, 9allowing us to see how ANGLE translates OpenGL ES commands. In order to capture the trace, it 10inserts a driver shim using `LD_PRELOAD` that records the command and then forwards it to the OpenGL 11driver. 12 13The problem with ANGLE is that it exposes the same symbols as the OpenGL driver so apitrace captures 14the entry point calls intended for ANGLE and reroutes them to the OpenGL driver. In order to avoid 15this problem, use the following: 16 171. Link your application against the static ANGLE libraries (libGLESv2_static and libEGL_static) so 18 they don't get shadowed by apitrace's shim. 192. Ask apitrace to explicitly load the driver instead of using a dlsym on the current module. 20 Otherwise apitrace will use ANGLE's symbols as the OpenGL driver entrypoint (causing infinite 21 recursion). To do this you must point an environment variable to your GL driver. For example: 22 `export TRACE_LIBGL=/usr/lib/libGL.so.1`. You can find your libGL with 23 `ldconfig -p | grep libGL`. 243. Link ANGLE against libGL instead of dlsyming the symbols at runtime; otherwise ANGLE won't use 25 the replaced driver entry points. This is done with the gn arg `angle_link_glx = true`. 26 27If you follow these steps, apitrace will work correctly aside from a few minor bugs like not being 28able to figure out what the default framebuffer size is if there is no glViewport command. 29 30For example, to trace a run of `hello_triangle`, assuming the apitrace executables are in `$PATH`: 31 32``` 33gn args out/Debug # add "angle_link_glx = true" 34# edit samples/BUILD.gn and append "_static" to "angle_util", "libEGL", "libGLESv2" 35ninja -C out/Debug 36export TRACE_LIBGL="/usr/lib/libGL.so.1" # may require a different path 37apitrace trace -o mytrace ./out/Debug/hello_triangle 38qapitrace mytrace 39``` 40 41## Enabling General Logging 42 43Normally, ANGLE only logs errors and warnings (e.g. to Android logcat). General logging, or 44additional levels of "trace" messages will be logged when the following GN arg is set: 45``` 46angle_enable_trace = true 47``` 48 49To log all GLES and EGL commands submitted by an application, including the following flag: 50``` 51angle_enable_trace_events = true 52``` 53 54## Debug Angle on Android 55 56Android is built as an Android APK, which makes it more difficult to debug an APK that is using ANGLE. The following information can allow you to debug ANGLE with LLDB. 57* You need to build ANGLE with debug symbols enabled. Assume your build variant is called Debug. Make sure you have these lines in out/Debug/args.gn 58``` 59is_component_build = false 60is_debug = true 61is_official_build = false 62symbol_level = 2 63strip_debug_info = false 64ignore_elf32_limitations = true 65angle_extract_native_libs = true 66``` 67The following local patch may also be necessary: 68``` 69diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni 70index 96a18d91a3f6..ca7971fdfd48 100644 71--- a/build/config/compiler/compiler.gni 72+++ b/build/config/compiler/compiler.gni 73@@ -86,7 +86,8 @@ declare_args() { 74 # Whether an error should be raised on attempts to make debug builds with 75 # is_component_build=false. Very large debug symbols can have unwanted side 76 # effects so this is enforced by default for chromium. 77- forbid_non_component_debug_builds = build_with_chromium 78+ forbid_non_component_debug_builds = false 79``` 80 81Build/install/enable ANGLE apk for your application following other instructions. 82* Modify gdbclient.py script to let it find the ANGLE symbols. 83``` 84diff --git a/scripts/gdbclient.py b/scripts/gdbclient.py 85index 61fac4000..1f43f4f64 100755 86--- a/scripts/gdbclient.py 87+++ b/scripts/gdbclient.py 88@@ -395,6 +395,8 @@ def generate_setup_script(debugger_path, sysroot, linker_search_dir, binary_file 89 vendor_paths = ["", "hw", "egl"] 90 solib_search_path += [os.path.join(symbols_dir, x) for x in symbols_paths] 91 solib_search_path += [os.path.join(vendor_dir, x) for x in vendor_paths] 92+ solib_search_path += ["/your_path_to_chromium_src/out/Debug/lib.unstripped/"] 93 if linker_search_dir is not None: 94 solib_search_path += [linker_search_dir] 95``` 96* Start your lldbclient.py from `/your_path_to_chromium_src/out/Debug` folder. This adds the ANGLE source-file paths to what is visible to LLDB, which allows LLDB to show ANGLE's source files. Refer to https://source.android.com/devices/tech/debug/gdb for how to attach the app for debugging. 97* If you are debugging angle_perftests, you can use `--shard-timeout 100000000` to disable the timeout so that the test won't get killed while you are debugging. If the test runs too fast that you don't have time to attach, use `--delay-test-start=60` to give you extra time to attach. 98 99## Enabling Debug-Utils Markers 100 101ANGLE can emit debug-utils markers for every GLES API command that are visible to both Android GPU 102Inspector (AGI) and RenderDoc. This support requires 103[enabling general logging](#enabling-general-logging) as well as setting the following additional 104GN arg: 105``` 106angle_enable_annotator_run_time_checks = true 107``` 108In addition, if the following GN arg is set, the API calls will output to Android's logcat: 109``` 110angle_enable_trace_android_logcat = true 111``` 112Once compiled, the markers need to be turned on. 113 114### Turning on Debug Markers on Android 115 116On Android, debug markers are turned on and off with an Android debug property that is 117automatically deleted at the next reboot: 118 119``` 120adb shell setprop debug.angle.markers 1 121``` 122 123* 0: Turned off/disabled (default) 124* 1: Turned on/enabled 125 126### Turning on Debug Markers on Desktop 127 128On desktop, debug markers are turned on and off with the ANGLE_ENABLE_DEBUG_MARKERS environment 129variable (set in OS-specific manner): 130 131* 0: Turned off/disabled (default) 132* 1: Turned on/enabled 133 134 135## Running ANGLE under GAPID on Linux 136 137[GAPID](https://github.com/google/gapid) can be used to capture trace of Vulkan commands on Linux. 138When capturing traces of gtest based tests built inside Chromium checkout, make sure to run the 139tests with `--single-process-tests` argument. 140 141## Running ANGLE under GAPID on Android 142 143[GAPID](https://github.com/google/gapid) can be used to capture a trace of the Vulkan or OpenGL ES 144command stream on Android. For it to work, ANGLE's libraries must have different names from the 145system OpenGL libraries. This is done with the gn arg: 146 147``` 148angle_libs_suffix = "_ANGLE_DEV" 149``` 150 151All 152[AngleNativeTest](https://chromium.googlesource.com/chromium/src/+/main/third_party/angle/src/tests/test_utils/runner/android/java/src/com/android/angle/test/AngleNativeTest.java) 153based tests share the same activity name, `com.android.angle.test.AngleUnitTestActivity`. 154Thus, prior to capturing your test trace, the specific test APK must be installed on the device. 155When you build the test, a test launcher is generated, for example, 156`./out/Release/bin/run_angle_end2end_tests`. The best way to install the APK is to run this test 157launcher once. 158 159In GAPID's "Capture Trace" dialog, "Package / Action:" should be: 160 161``` 162android.intent.action.MAIN:com.android.angle.test/com.android.angle.test.AngleUnitTestActivity 163``` 164 165The mandatory [extra intent 166argument](https://developer.android.com/studio/command-line/adb.html#IntentSpec) for starting the 167activity is `org.chromium.native_test.NativeTest.StdoutFile`. Without it the test APK crashes. Test 168filters can be specified via either the `org.chromium.native_test.NativeTest.CommandLineFlags` or 169the `org.chromium.native_test.NativeTest.GtestFilter` argument. Example "Intent Arguments:" values in 170GAPID's "Capture Trace" dialog: 171 172``` 173-e org.chromium.native_test.NativeTest.StdoutFile /sdcard/chromium_tests_root/out.txt -e org.chromium.native_test.NativeTest.CommandLineFlags "--gtest_filter=*ES2_VULKAN" 174``` 175 176or 177 178``` 179-e org.chromium.native_test.NativeTest.StdoutFile /sdcard/chromium_tests_root/out.txt --e org.chromium.native_test.NativeTest.GtestFilter RendererTest.SimpleOperation/ES2_VULKAN:SimpleOperationTest.DrawWithTexture/ES2_VULKAN 180``` 181 182## Running ANGLE under RenderDoc 183 184An application running through ANGLE can confuse [RenderDoc](https://github.com/baldurk/renderdoc), 185as RenderDoc [hooks to EGL](https://github.com/baldurk/renderdoc/issues/1045) and ends up tracing 186the calls the application makes, instead of the calls ANGLE makes to its backend. As ANGLE is a 187special case, there's little support for it by RenderDoc, though there are workarounds. 188 189### Windows 190 191On Windows, RenderDoc supports setting the environment variable `RENDERDOC_HOOK_EGL` to 0 to avoid 192this issue. 193 194### Linux 195 196On Linux, there is no supported workaround by RenderDoc. See [this 197issue](https://github.com/baldurk/renderdoc/issues/1045#issuecomment-463999869). To capture Vulkan 198traces, the workaround is to build RenderDoc without GL(ES) support. 199 200Building RenderDoc is straightforward. However, here are a few instructions to keep in mind. 201 202``` 203# Install dependencies based on RenderDoc document. Here are some packages that are unlikely to be already installed: 204$ sudo apt install libxcb-keysyms1-dev python3-dev qt5-qmake libqt5svg5-dev libqt5x11extras5-dev 205 206# Inside the RenderDoc directory: 207$ cmake -DCMAKE_BUILD_TYPE=Release -Bbuild -H. -DENABLE_GLES=OFF -DENABLE_GL=OFF 208 209# QT_SELECT=5 is necessary if your distribution doesn't default to Qt5 210$ QT_SELECT=5 make -j -C build 211 212# Run RenderDoc from the build directory: 213$ ./build/bin/qrenderdoc 214``` 215 216If your distribution does not provide a recent Vulkan SDK package, you would need to manually 217install that. This script tries to perform this installation as safely as possible. It would 218overwrite the system package's files, so follow at your own risk. Place this script just above the 219extracted SDK directory. 220 221``` 222#! /bin/bash 223 224if [ $# -lt 1 ]; then 225 echo "Usage: $0 <version>" 226 exit 1 227fi 228 229ver=$1 230 231if [ ! -d "$ver" ]; then 232 echo "$ver is not a directory" 233fi 234 235# Verify everything first 236echo "Verifying files..." 237echo "$ver"/x86_64/bin/vulkaninfo 238test -f "$ver"/x86_64/bin/vulkaninfo || exit 1 239echo "$ver"/x86_64/etc/explicit_layer.d/ 240test -d "$ver"/x86_64/etc/explicit_layer.d || exit 1 241echo "$ver"/x86_64/lib/ 242test -d "$ver"/x86_64/lib || exit 1 243 244echo "Verified. Performing copy..." 245 246echo sudo cp "$ver"/x86_64/bin/vulkaninfo /usr/bin/vulkaninfo 247sudo cp "$ver"/x86_64/bin/vulkaninfo /usr/bin/vulkaninfo 248echo sudo cp "$ver"/x86_64/etc/explicit_layer.d/* /etc/explicit_layer.d/ 249sudo cp "$ver"/x86_64/etc/explicit_layer.d/* /etc/explicit_layer.d/ 250echo sudo rm /usr/lib/x86_64-linux-gnu/libvulkan.so* 251sudo rm /usr/lib/x86_64-linux-gnu/libvulkan.so* 252echo sudo cp -P "$ver"/x86_64/lib/lib* /usr/lib/x86_64-linux-gnu/ 253sudo cp -P "$ver"/x86_64/lib/lib* /usr/lib/x86_64-linux-gnu/ 254 255echo "Done." 256``` 257 258### Android 259#### Linux 260 261If you are on Linux, make sure not to use the build done in the previous section. The GL renderer 262disabled in the previous section is actually needed in this section. 263 264Define the following environment variables, for example in `.bashrc` (values are examples): 265 266``` 267export JAVA_HOME=/usr/local/buildtools/java/jdk 268export ANDROID_SDK=$HOME/chromium/src/third_party/android_sdk/public 269export ANDROID_NDK=$HOME/chromium/src/third_party/android_ndk 270export ANDROID_NDK_HOME=$HOME/chromium/src/third_party/android_ndk 271``` 272 273In the renderdoc directory, create Android builds of RenderDoc: 274 275``` 276mkdir build-android-arm32 277cd build-android-arm32/ 278cmake -DBUILD_ANDROID=On -DANDROID_ABI=armeabi-v7a .. 279make -j 280cd ../ 281 282mkdir build-android-arm64 283cd build-android-arm64/ 284cmake -DBUILD_ANDROID=On -DANDROID_ABI=arm64-v8a .. 285make -j 286cd ../ 287``` 288 289Note that you need both arm32 and arm64 builds even if working with an arm64 device. See 290[RenderDoc's documentation](https://github.com/baldurk/renderdoc/blob/v1.x/docs/CONTRIBUTING/Compiling.md#android) 291for more information. 292 293When you run RenderDoc, choose the "Replay Context" from the bottom-left part of the UI (defaults to 294Local). When selecting the device, you should see the RenderDoc application running. 295 296In ANGLE itself, make sure you add a suffix for its names to be different from the system's. Add 297this to gn args: 298 299``` 300angle_libs_suffix = "_ANGLE_DEV" 301``` 302 303Next, you need to install an ANGLE test APK. When you build the test, a test launcher is generated, 304for example, `./out/Release/bin/run_angle_end2end_tests`. The best way to install the APK is to run 305this test launcher once. 306 307In RenderDoc, use `com.android.angle.test/com.android.angle.test.AngleUnitTestActivity` as the 308Executable Path, and provide the following arguments: 309 310``` 311-e org.chromium.native_test.NativeTest.StdoutFile /sdcard/chromium_tests_root/out.txt -e org.chromium.native_test.NativeTest.CommandLineFlags "--gtest_filter=*ES2_VULKAN" 312``` 313 314Note that in the above, only a single command line argument is supported with RenderDoc. If testing 315dEQP on a non-default platform, the easiest way would be to modify `GetDefaultAPIName()` in 316`src/tests/deqp_support/angle_deqp_gtest.cpp` (and avoid `--use-angle=X`). 317 318 319#### Windows 320You should be able to download the latest [RenderDoc on Windows](https://renderdoc.org/builds) and follow the 321[RenderDoc Official Documentation](https://renderdoc.org/docs/how/how_android_capture.html) for instructions on how to 322use RenderDoc on Android. If you would like to build RenderDoc for Android on Windows yourself, you can follow the 323[RenderDoc Officual Documentation](https://github.com/baldurk/renderdoc/blob/v1.x/docs/CONTRIBUTING/Compiling.md#android). 324We listed more detailed instructions below on how to set up the build on Windows. 325 326##### Install Android Dependencies 327 328On windows, we need to install dependencies to build android, as described in 329[RenderDoc Official Documentation](https://github.com/baldurk/renderdoc/blob/v1.x/docs/CONTRIBUTING/Dependencies.md#android) 3301. Install [Android SDK](https://developer.android.com/about/versions/12/setup-sdk#install-sdk). 331 332 Add a new system variable: 333 334 Variable: ANDROID_SDK 335 336 Value: path_to_sdk_directory (e.g. C:\Users\test\Appdata\Local\Android\Sdk) 3372. Install [Android NDK](https://developer.android.com/studio/projects/install-ndk). 338 339 Add a new system variable: 340 341 Variable: ANDROID_NDK 342 343 Value: path_to_ndk_directory (e.g. C:\Users\test\Appdata\Local\Android\Sdk\ndk\23.1.7779620) 344 3453. Install [Java 8](https://www.oracle.com/java/technologies/downloads/#java8). 346 347 Add a new system variable: 348 349 Variable: JAVA_HOME 350 351 Value: path_to_jdk1.8_directory (e.g. C:\Program Files\Java\jdk1.8.0_311) 352 3535. Install [Android Debug Bridge](https://developer.android.com/studio/releases/platform-tools). 354 355 Append android_sdk_platform-tools_directory to the Path system variable. 356 357 e.g. C:\Users\Test\AppData\Local\Android\Sdk\platform-tools 358 359 360##### Install Build Tools 361 3621. Install a bash shell. Git Bash comes with Git installation on Windows should work. 3632. Install [make](http://gnuwin32.sourceforge.net/packages/make.htm). 364 Add the path to bin folder of GnuWin32 to the Path system variable. 365 366 367##### Build RenderDoc Android APK on Windows 368 369If you are using the Git Bash that comes with MinGW generator, you can run below commands to build Android APK 370``` 371mkdir build-android-arm32 372cd build-android-arm32/ 373cmake -DBUILD_ANDROID=On -DANDROID_ABI=armeabi-v7a -G "MinGW Makefiles" .. 374make -j 375cd ../ 376 377mkdir build-android-arm64 378cd build-android-arm64/ 379cmake -DBUILD_ANDROID=On -DANDROID_ABI=arm64-v8a -G "MinGW Makefiles" .. 380make -j 381cd ../ 382``` 383If the generator type of the bash shell you are using is different from MinGW, replace the "MinGW" in the above cmake 384command with the generator 385type you are using, as described in 386[RenderDoc Official Documentation](https://github.com/baldurk/renderdoc/blob/v1.x/docs/CONTRIBUTING/Compiling.md#android). 387 388 389##### Build Errors And Resolutions 390 391* **cmake command errors** 392 393``` 394Error: Failed to run MSBuild command: 395C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/MSBuild/Current/Bin/MSBuild.exe to get the value of 396VCTargetsPath: 397error : The BaseOutputPath/OutputPath property is not set for project 'VCTargetsPath.vcxproj'. 398Please check to make sure that you have specified a valid combination of Configuration and Platform for this project. 399Configuration='Debug' Platform='x64'. 400``` 401 402This is due to the cmake command is using Visual Studio as the generator type. Run the cmake command with the 403generator type "MinGW Makefiles" or "MSYS Makefiles". 404 405```Error: Does not match the generator used previously``` 406 407 408 409Delete the CMakeCache file in build directories build-android-arm64/ or build-android-arm32/. 410 411 412* **make command errors** 413 414``` 415-Djava.ext.dirs is not supported. 416Error: Could not create the Java Virtual Machine. 417Error: A fatal exception has occurred. Program will exit. 418 419``` 420 421Downgrade Java JDK version to [Java 8](https://www.oracle.com/java/technologies/downloads/#java8). 422 423 424##### Steps to use the RenderDoc you just built 4251. Build arm32 and arm64 android packages. See [instructions](#build-renderdoc-android-apk-on-windows) in the above 426section. 427 4282. Uninstall the renderdoc package. 429 430This step is required if you have installed / used RenderDoc on the same Android device before. RenderDoc only pushes 431the renderdoccmd APK to the Android device if it finds the version of the existing APK on the device is different from 432the version of the APK we are going to install, and the version is dictated by the git hash it was built from. Therefore 433any local modifications in the RenderDoc codebase would not get picked up if we don't uninstall the old APK first. 434 435``` 436adb uninstall org.renderdoc.renderdoccmd.arm64 437adb uninstall org.renderdoc.renderdoccmd.arm32 438``` 4393. Build renderdoc on windows desktop by clicking "build solution" in visual studio. 4404. Launch renderdoc from visual studio, and push the android packages to android device by selecting the connected 441device at the bottom left corner. 442 443## Testing with Chrome Canary 444 445Many of ANGLE's OpenGL ES entry points are exposed in Chromium as WebGL 1.0 and WebGL 2.0 APIs that 446are available via JavaScript. For testing purposes, custom ANGLE builds may be injected in Chrome 447Canary. 448 449### Setup 450 451#### Windows 452 4531. Download and install [Google Chrome Canary](https://www.google.com/chrome/canary/). 4542. Build ANGLE x64, Release. 4553. Run `python scripts\update_chrome_angle.py` to replace Canary's ANGLE with your custom ANGLE 456 (note: Canary must be closed). 457 458#### Linux 459 4601. Install Google Chrome Dev (via apt, or otherwise). Expected installation directory is 461 `/opt/google/chrome-unstable`. 4622. Build ANGLE for the running platform. `is_component_build = false` is suggested in the GN args. 4633. Run `python scripts/update_chrome_angle.py` to replace Dev's ANGLE with your custom ANGLE 4644. Add ANGLE's build path to the `LD_LIBRARY_PATH` environment variable. 465 466#### macOS 467 4681. Download and install [Google Chrome Canary](https://www.google.com/chrome/canary/). 4692. Build ANGLE for the running platform; GN args should contain `is_debug = false`. 4703. Run `./scripts/update_chrome_angle.py` to replace Canary's ANGLE with your custom ANGLE. 471 472### Usage 473 474Run Chrome: 475 476- On Windows: `%LOCALAPPDATA%\Google\Chrome SxS\chrome.exe` 477- On Linux: `/opt/google/chrome-unstable/google-chrome-unstable` 478- On macOS: `./Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary` 479 480With the following command-line options: 481 482* `--use-cmd-decoder=passthrough --use-gl=angle` and one of 483 * `--use-angle=d3d9` (Direct3D 9 renderer, Windows only) 484 * `--use-angle=d3d11` (Direct3D 11 renderer, Windows only) 485 * `--use-angle=d3d11on12` (Direct3D 11on12 renderer, Windows only) 486 * `--use-angle=gl` (OpenGL renderer) 487 * `--use-angle=gles` (OpenGL ES renderer) 488 * `--use-angle=vulkan` (Vulkan renderer) 489 * `--use-angle=swiftshader` (SwiftShader renderer) 490 * `--use-angle=metal` (Metal renderer, macOS only) 491 492Additional useful options: 493 494* `--enable-logging`: To see logs 495* `--disable-gpu-watchdog`: To disable Chromium's watchdog, killing the GPU process when slow (due 496 to a debug build for example) 497* `--disable-gpu-sandbox`: To disable Chromium's sandboxing features, if it's getting in the way of 498 testing. 499* `--disable-gpu-compositing`: To make sure only the WebGL test being debugged is run through ANGLE, 500 not the entirety of Chromium. 501