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## Running ANGLE under GAPID on Linux 42 43[GAPID](https://github.com/google/gapid) can be used to capture trace of Vulkan commands on Linux. 44When capturing traces of gtest based tests built inside Chromium checkout, make sure to run the 45tests with `--single-process-tests` argument. 46 47## Running ANGLE under GAPID on Android 48 49[GAPID](https://github.com/google/gapid) can be used to capture a trace of the Vulkan or OpenGL ES 50command stream on Android. For it to work, ANGLE's libraries must have different names from the 51system OpenGL libraries. This is done with the gn arg: 52 53``` 54angle_libs_suffix = "_ANGLE_DEV" 55``` 56 57All 58[NativeTest](https://chromium.googlesource.com/chromium/src/+/master/testing/android/native_test/java/src/org/chromium/native_test/NativeTest.java) 59based tests share the same activity name, `org.chromium.native_test.NativeUnitTestNativeActivity`. 60Thus, prior to capturing your test trace, the specific test APK must be installed on the device. 61When you build the test, a test launcher is generated, for example, 62`./out/Release/bin/run_angle_end2end_tests`. The best way to install the APK is to run this test 63launcher once. 64 65In GAPID's "Capture Trace" dialog, "Package / Action:" should be: 66 67``` 68android.intent.action.MAIN:org.chromium.native_test/org.chromium.native_test.NativeUnitTestNativeActivity 69``` 70 71The mandatory [extra intent 72argument](https://developer.android.com/studio/command-line/adb.html#IntentSpec) for starting the 73activity is `org.chromium.native_test.NativeTest.StdoutFile`. Without it the test APK crashes. Test 74filters can be specified via either the `org.chromium.native_test.NativeTest.CommandLineFlags` or 75the `org.chromium.native_test.NativeTest.Shard` argument. Example "Intent Arguments:" values in 76GAPID's "Capture Trace" dialog: 77 78``` 79-e org.chromium.native_test.NativeTest.StdoutFile /sdcard/chromium_tests_root/out.txt -e org.chromium.native_test.NativeTest.CommandLineFlags "--gtest_filter=*ES2_VULKAN" 80``` 81 82or 83 84``` 85-e org.chromium.native_test.NativeTest.StdoutFile /sdcard/chromium_tests_root/out.txt --esal org.chromium.native_test.NativeTest.Shard RendererTest.SimpleOperation/ES2_VULKAN,SimpleOperationTest.DrawWithTexture/ES2_VULKAN 86``` 87 88## Running ANGLE under RenderDoc 89 90An application running through ANGLE can confuse [RenderDoc](https://github.com/baldurk/renderdoc), 91as RenderDoc [hooks to EGL](https://github.com/baldurk/renderdoc/issues/1045) and ends up tracing 92the calls the application makes, instead of the calls ANGLE makes to its backend. As ANGLE is a 93special case, there's little support for it by RenderDoc, though there are workarounds. 94 95### Windows 96 97On Windows, RenderDoc supports setting the environment variable `RENDERDOC_HOOK_EGL` to 0 to avoid 98this issue. 99 100### Linux 101 102On Linux, there is no supported workaround by RenderDoc. See [this 103issue](https://github.com/baldurk/renderdoc/issues/1045#issuecomment-463999869). To capture Vulkan 104traces, the workaround is to build RenderDoc without GL(ES) support. 105 106Building RenderDoc is straightforward. However, here are a few instructions to keep in mind. 107 108``` 109# Install dependencies based on RenderDoc document. Here are some packages that are unlikely to be already installed: 110$ sudo apt install libxcb-keysyms1-dev python3-dev qt5-qmake libqt5svg5-dev libqt5x11extras5-dev 111 112# Inside the RenderDoc directory: 113$ cmake -DCMAKE_BUILD_TYPE=Release -Bbuild -H. -DENABLE_GLES=OFF -DENABLE_GL=OFF 114 115# QT_SELECT=5 is necessary if your distribution doesn't default to Qt5 116$ QT_SELECT=5 make -j -C build 117 118# Run RenderDoc from the build directory: 119$ ./build/bin/qrenderdoc 120``` 121 122If your distribution does not provide a recent Vulkan SDK package, you would need to manually 123install that. This script tries to perform this installation as safely as possible. It would 124overwrite the system package's files, so follow at your own risk. Place this script just above the 125extracted SDK directory. 126 127``` 128#! /bin/bash 129 130if [ $# -lt 1 ]; then 131 echo "Usage: $0 <version>" 132 exit 1 133fi 134 135ver=$1 136 137if [ ! -d "$ver" ]; then 138 echo "$ver is not a directory" 139fi 140 141# Verify everything first 142echo "Verifying files..." 143echo "$ver"/x86_64/bin/vulkaninfo 144test -f "$ver"/x86_64/bin/vulkaninfo || exit 1 145echo "$ver"/x86_64/etc/explicit_layer.d/ 146test -d "$ver"/x86_64/etc/explicit_layer.d || exit 1 147echo "$ver"/x86_64/lib/ 148test -d "$ver"/x86_64/lib || exit 1 149 150echo "Verified. Performing copy..." 151 152echo sudo cp "$ver"/x86_64/bin/vulkaninfo /usr/bin/vulkaninfo 153sudo cp "$ver"/x86_64/bin/vulkaninfo /usr/bin/vulkaninfo 154echo sudo cp "$ver"/x86_64/etc/explicit_layer.d/* /etc/explicit_layer.d/ 155sudo cp "$ver"/x86_64/etc/explicit_layer.d/* /etc/explicit_layer.d/ 156echo sudo rm /usr/lib/x86_64-linux-gnu/libvulkan.so* 157sudo rm /usr/lib/x86_64-linux-gnu/libvulkan.so* 158echo sudo cp -P "$ver"/x86_64/lib/lib* /usr/lib/x86_64-linux-gnu/ 159sudo cp -P "$ver"/x86_64/lib/lib* /usr/lib/x86_64-linux-gnu/ 160 161echo "Done." 162``` 163 164### Android 165 166If you are on Linux, make sure not to use the build done in the previous section. The GL renderer 167disabled in the previous section is actually needed in this section. 168 169Define the following environment variables, for example in `.bashrc` (values are examples): 170 171``` 172export JAVA_HOME=/usr/local/buildtools/java/jdk 173export ANDROID_SDK=$HOME/chromium/src/third_party/android_sdk/public 174export ANDROID_NDK=$HOME/chromium/src/third_party/android_ndk 175export ANDROID_NDK_HOME=$HOME/chromium/src/third_party/android_ndk 176``` 177 178In the renderdoc directory, create Android builds of RenderDoc: 179 180``` 181mkdir build-android-arm32 182cd build-android-arm32/ 183cmake -DBUILD_ANDROID=On -DANDROID_ABI=armeabi-v7a .. 184make -j 185cd ../ 186 187mkdir build-android-arm64 188cd build-android-arm64/ 189cmake -DBUILD_ANDROID=On -DANDROID_ABI=arm64-v8a .. 190make -j 191cd ../ 192``` 193 194Note that you need both arm32 and arm64 builds even if working with an arm64 device. See 195[RenderDoc's documentation](https://github.com/baldurk/renderdoc/blob/v1.x/docs/CONTRIBUTING/Compiling.md#android) 196for more information. 197 198When you run RenderDoc, choose the "Replay Context" from the bottom-left part of the UI (defaults to 199Local). When selecting the device, you should see the RenderDoc application running. 200 201In ANGLE itself, make sure you add a suffix for its names to be different from the system's. Add 202this to gn args: 203 204``` 205angle_libs_suffix = "_ANGLE_DEV" 206``` 207 208Next, you need to install an ANGLE test apk. When you build the test, a test launcher is generated, 209for example, `./out/Release/bin/run_angle_end2end_tests`. The best way to install the APK is to run 210this test launcher once. 211 212In RenderDoc, use `org.chromium.native_test` as the Executable Path, and provide the following 213arguments: 214 215``` 216-e org.chromium.native_test.NativeTest.StdoutFile /sdcard/chromium_tests_root/out.txt -e org.chromium.native_test.NativeTest.CommandLineFlags "--gtest_filter=*ES2_VULKAN" 217``` 218 219Note that in the above, only a single command line argument is supported with RenderDoc. If testing 220dEQP on a non-default platform, the easiest way would be to modify `GetDefaultAPIName()` in 221`src/tests/deqp_support/angle_deqp_gtest.cpp` (and avoid `--use-angle=X`). 222