andybons | e6a8f2bd | 2015-08-31 22:46:01 | [diff] [blame] | 1 | # Tips for debugging on Linux |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 2 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 3 | This page is for Chromium-specific debugging tips; learning how to run gdb is |
| 4 | out of scope. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 5 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 6 | [TOC] |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 7 | |
| 8 | ## Symbolized stack trace |
| 9 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 10 | The sandbox can interfere with the internal symbolizer. Use `--no-sandbox` (but |
| 11 | keep this temporary) or an external symbolizer (see |
| 12 | `tools/valgrind/asan/asan_symbolize.py`). |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 13 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 14 | Generally, do not use `--no-sandbox` on waterfall bots, sandbox testing is |
| 15 | needed. Talk to security@chromium.org. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 16 | |
| 17 | ## GDB |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 18 | |
nodir | a6074d4c | 2015-09-01 04:26:45 | [diff] [blame] | 19 | *** promo |
| 20 | GDB-7.7 is required in order to debug Chrome on Linux. |
| 21 | *** |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 22 | |
| 23 | Any prior version will fail to resolve symbols or segfault. |
| 24 | |
| 25 | ### Basic browser process debugging |
| 26 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 27 | gdb -tui -ex=r --args out/Debug/chrome --disable-seccomp-sandbox \ |
| 28 | http://google.com |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 29 | |
| 30 | ### Allowing attaching to foreign processes |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 31 | |
| 32 | On distributions that use the |
| 33 | [Yama LSM](https://www.kernel.org/doc/Documentation/security/Yama.txt) (that |
| 34 | includes Ubuntu and Chrome OS), process A can attach to process B only if A is |
| 35 | an ancestor of B. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 36 | |
| 37 | You will probably want to disable this feature by using |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 38 | |
| 39 | echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 40 | |
| 41 | If you don't you'll get an error message such as "Could not attach to process". |
| 42 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 43 | Note that you'll also probably want to use `--no-sandbox`, as explained below. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 44 | |
| 45 | ### Multiprocess Tricks |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 46 | |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 47 | #### Getting renderer subprocesses into gdb |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 48 | |
| 49 | Since Chromium itself spawns the renderers, it can be tricky to grab a |
| 50 | particular with gdb. This command does the trick: |
| 51 | |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 52 | ``` |
| 53 | chrome --no-sandbox --renderer-cmd-prefix='xterm -title renderer -e gdb --args' |
| 54 | ``` |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 55 | |
| 56 | The `--no-sandbox` flag is needed because otherwise the seccomp sandbox will |
| 57 | kill the renderer process on startup, or the setuid sandbox will prevent xterm's |
| 58 | execution. The "xterm" is necessary or gdb will run in the current terminal, |
| 59 | which can get particularly confusing since it's running in the background, and |
| 60 | if you're also running the main process in gdb, won't work at all (the two |
| 61 | instances will fight over the terminal). To auto-start the renderers in the |
| 62 | debugger, send the "run" command to the debugger: |
| 63 | |
nodir | a6074d4c | 2015-09-01 04:26:45 | [diff] [blame] | 64 | chrome --no-sandbox --renderer-cmd-prefix='xterm -title renderer -e gdb \ |
| 65 | -ex run --args |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 66 | |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 67 | If you're using Emacs and `M-x gdb`, you can do |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 68 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 69 | chrome "--renderer-cmd-prefix=gdb --args" |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 70 | |
nodir | a6074d4c | 2015-09-01 04:26:45 | [diff] [blame] | 71 | *** note |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 72 | Note: using the `--renderer-cmd-prefix` option bypasses the zygote launcher, so |
| 73 | the renderers won't be sandboxed. It is generally not an issue, except when you |
| 74 | are trying to debug interactions with the sandbox. If that's what you are doing, |
| 75 | you will need to attach your debugger to a running renderer process (see below). |
nodir | a6074d4c | 2015-09-01 04:26:45 | [diff] [blame] | 76 | *** |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 77 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 78 | You may also want to pass `--disable-hang-monitor` to suppress the hang monitor, |
| 79 | which is rather annoying. |
| 80 | |
| 81 | You can also use `--renderer-startup-dialog` and attach to the process in order |
| 82 | to debug the renderer code. Go to |
xiaoyin.l | 1003c0b | 2016-12-06 02:51:17 | [diff] [blame] | 83 | https://www.chromium.org/blink/getting-started-with-blink-debugging for more |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 84 | information on how this can be done. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 85 | |
| 86 | #### Choosing which renderers to debug |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 87 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 88 | If you are starting multiple renderers then the above means that multiple gdb's |
| 89 | start and fight over the console. Instead, you can set the prefix to point to |
| 90 | this shell script: |
| 91 | |
| 92 | ```sh |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 93 | #!/bin/sh |
| 94 | |
| 95 | echo "**** Child $$ starting: y to debug" |
| 96 | read input |
| 97 | if [ "$input" = "y" ] ; then |
| 98 | gdb --args $* |
| 99 | else |
| 100 | $* |
| 101 | fi |
| 102 | ``` |
| 103 | |
| 104 | #### Selective breakpoints |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 105 | |
| 106 | When debugging both the browser and renderer process, you might want to have |
| 107 | separate set of breakpoints to hit. You can use gdb's command files to |
| 108 | accomplish this by putting breakpoints in separate files and instructing gdb to |
| 109 | load them. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 110 | |
| 111 | ``` |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 112 | gdb -x ~/debug/browser --args chrome --no-sandbox --disable-hang-monitor \ |
| 113 | --renderer-cmd-prefix='xterm -title renderer -e gdb -x ~/debug/renderer \ |
| 114 | --args ' |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 115 | ``` |
| 116 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 117 | Also, instead of running gdb, you can use the script above, which let's you |
| 118 | select which renderer process to debug. Note: you might need to use the full |
| 119 | path to the script and avoid `$HOME` or `~/.` |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 120 | |
| 121 | #### Connecting to a running renderer |
| 122 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 123 | Usually `ps aux | grep chrome` will not give very helpful output. Try |
| 124 | `pstree -p | grep chrome` to get something like |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 125 | |
| 126 | ``` |
| 127 | | |-bash(21969)---chrome(672)-+-chrome(694) |
| 128 | | | |-chrome(695)---chrome(696)-+-{chrome}(697) |
| 129 | | | | \-{chrome}(709) |
| 130 | | | |-{chrome}(675) |
| 131 | | | |-{chrome}(678) |
| 132 | | | |-{chrome}(679) |
| 133 | | | |-{chrome}(680) |
| 134 | | | |-{chrome}(681) |
| 135 | | | |-{chrome}(682) |
| 136 | | | |-{chrome}(684) |
| 137 | | | |-{chrome}(685) |
| 138 | | | |-{chrome}(705) |
| 139 | | | \-{chrome}(717) |
| 140 | ``` |
| 141 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 142 | Most of those are threads. In this case the browser process would be 672 and the |
| 143 | (sole) renderer process is 696. You can use `gdb -p 696` to attach. |
| 144 | Alternatively, you might find out the process ID from Chrome's built-in Task |
| 145 | Manager (under the Tools menu). Right-click on the Task Manager, and enable |
| 146 | "Process ID" in the list of columns. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 147 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 148 | Note: by default, sandboxed processes can't be attached by a debugger. To be |
| 149 | able to do so, you will need to pass the `--allow-sandbox-debugging` option. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 150 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 151 | If the problem only occurs with the seccomp sandbox enabled (and the previous |
| 152 | tricks don't help), you could try enabling core-dumps (see the **Core files** |
| 153 | section). That would allow you to get a backtrace and see some local variables, |
| 154 | though you won't be able to step through the running program. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 155 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 156 | Note: If you're interested in debugging LinuxSandboxIPC process, you can attach |
| 157 | to 694 in the above diagram. The LinuxSandboxIPC process has the same command |
| 158 | line flag as the browser process so that it's easy to identify it if you run |
| 159 | `pstree -pa`. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 160 | |
| 161 | #### Getting GPU subprocesses into gdb |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 162 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 163 | Use `--gpu-launcher` flag instead of `--renderer-cmd-prefix` in the instructions |
| 164 | for renderer above. |
| 165 | |
| 166 | #### Getting `browser_tests` launched browsers into gdb |
| 167 | |
| 168 | Use environment variable `BROWSER_WRAPPER` instead of `--renderer-cmd-prefix` |
| 169 | switch in the instructions above. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 170 | |
| 171 | Example: |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 172 | |
| 173 | ```shell |
| 174 | BROWSER_WRAPPER='xterm -title renderer -e gdb --eval-command=run \ |
| 175 | --eval-command=quit --args' out/Debug/browser_tests --gtest_filter=Print |
| 176 | ``` |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 177 | |
| 178 | #### Plugin Processes |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 179 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 180 | Same strategies as renderers above, but the flag is called `--plugin-launcher`: |
| 181 | |
| 182 | chrome --plugin-launcher='xterm -e gdb --args' |
| 183 | |
nodir | a6074d4c | 2015-09-01 04:26:45 | [diff] [blame] | 184 | *** note |
| 185 | Note: For now, this does not currently apply to PPAPI plugins because they |
| 186 | currently run in the renderer process. |
| 187 | *** |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 188 | |
| 189 | #### Single-Process mode |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 190 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 191 | Depending on whether it's relevant to the problem, it's often easier to just run |
| 192 | in "single process" mode where the renderer threads are in-process. Then you can |
| 193 | just run gdb on the main process. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 194 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 195 | gdb --args chrome --single-process |
| 196 | |
| 197 | Currently, the `--disable-gpu` flag is also required, as there are known crashes |
| 198 | that occur under TextureImageTransportSurface without it. The crash described in |
xiaoyin.l | 1003c0b | 2016-12-06 02:51:17 | [diff] [blame] | 199 | https://crbug.com/361689 can also sometimes occur, but that crash can be |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 200 | continued from without harm. |
| 201 | |
| 202 | Note that for technical reasons plugins cannot be in-process, so |
| 203 | `--single-process` only puts the renderers in the browser process. The flag is |
| 204 | still useful for debugging plugins (since it's only two processes instead of |
| 205 | three) but you'll still need to use `--plugin-launcher` or another approach. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 206 | |
| 207 | ### Printing Chromium types |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 208 | |
Tom Anderson | f06ac38 | 2019-04-10 03:49:38 | [diff] [blame] | 209 | gdb 7 lets us use Python to write pretty-printers for Chromium types. See |
| 210 | [gdbinit](https://chromium.googlesource.com/chromium/src/+/master/docs/gdbinit.md) |
| 211 | to enable pretty-printing of Chromium types. This will import Blink |
| 212 | pretty-printers as well. |
Kenichi Ishibashi | e17b8d9f | 2018-04-26 03:32:46 | [diff] [blame] | 213 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 214 | Pretty printers for std types shouldn't be necessary in gdb 7, but they're |
| 215 | provided here in case you're using an older gdb. Put the following into |
| 216 | `~/.gdbinit`: |
| 217 | |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 218 | ``` |
| 219 | # Print a C++ string. |
| 220 | define ps |
| 221 | print $arg0.c_str() |
| 222 | end |
| 223 | |
| 224 | # Print a C++ wstring or wchar_t*. |
| 225 | define pws |
| 226 | printf "\"" |
| 227 | set $c = (wchar_t*)$arg0 |
| 228 | while ( *$c ) |
| 229 | if ( *$c > 0x7f ) |
| 230 | printf "[%x]", *$c |
| 231 | else |
| 232 | printf "%c", *$c |
| 233 | end |
| 234 | set $c++ |
| 235 | end |
| 236 | printf "\"\n" |
| 237 | end |
| 238 | ``` |
| 239 | |
| 240 | [More STL GDB macros](http://www.yolinux.com/TUTORIALS/src/dbinit_stl_views-1.01.txt) |
| 241 | |
Christian Biesinger | 3332bb3a | 2019-08-13 05:45:23 | [diff] [blame] | 242 | ### JsDbg -- visualize data structures in the browser |
| 243 | |
| 244 | JsDbg is a debugger plugin to display various Chrome data structures in a |
| 245 | browser window, such as the accessibility tree, layout object tree, DOM tree, |
| 246 | and others. |
| 247 | [Installation instructions are here](https://github.com/MicrosoftEdge/JsDbg), |
| 248 | and see [here](https://github.com/MicrosoftEdge/JsDbg/blob/master/docs/FEATURES.md) |
| 249 | for screenshots and an introduction. |
| 250 | |
| 251 | For Googlers, please see [go/jsdbg](https://goto.google.com/jsdbg) for |
| 252 | installation instructions. |
| 253 | |
| 254 | ### Time travel debugging with rr |
| 255 | |
| 256 | You can use [rr](https://rr-project.org) for time travel debugging, so you |
| 257 | can also step or execute backwards. This works by first recording a trace |
| 258 | and then debugging based on that. I recommend installing it by compiling |
| 259 | [from source](https://github.com/mozilla/rr/wiki/Building-And-Installing). |
| 260 | |
David Benjamin | e7b279b | 2020-05-26 21:38:58 | [diff] [blame] | 261 | As of May 2020, you must build from source for [`MADV_WIPEONFORK` |
| 262 | support](https://bugs.chromium.org/p/chromium/issues/detail?id=1082304). If you |
| 263 | get the following error, rr is too old: |
| 264 | ``` |
| 265 | Expected EINVAL for 'madvise' but got result 0 (errno SUCCESS); unknown madvise(18) |
| 266 | ``` |
Robert Flack | c9e6995 | 2020-05-13 19:52:31 | [diff] [blame] | 267 | |
Christian Biesinger | 3332bb3a | 2019-08-13 05:45:23 | [diff] [blame] | 268 | Once installed, you can use it like this: |
| 269 | ``` |
| 270 | rr record out/Debug/content_shell --single-process --no-sandbox --disable-hang-monitor --single-process --disable-seccomp-sandbox --disable-setuid-sandbox |
| 271 | rr replay |
| 272 | (gdb) c |
| 273 | (gdb) break blink::NGBlockNode::Layout |
| 274 | (gdb) rc # reverse-continue to the last Layout call |
| 275 | (gdb) jsdbg # run JsDbg as described above to find the interesting object |
| 276 | (gdb) watch -l box_->frame_rect_.size_.width_.value_ |
| 277 | (gdb) rc # reverse-continue to the last time the width was changed |
| 278 | (gdb) rn # reverse-next to the previous line |
| 279 | (gdb) reverse-fin # run to where this function was called from |
| 280 | ``` |
| 281 | |
Robert Flack | e13e0b1 | 2020-04-16 17:03:58 | [diff] [blame] | 282 | You can debug multi-process chrome using `rr -f [PID]`. To find the process |
| 283 | id you can either run `rr ps` after recording, or a convenient way |
| 284 | to find the correct process id is to run with `--vmodule=render_frame_impl=1` |
| 285 | which will log a message on navigations. e.g. |
| 286 | |
| 287 | ``` |
| 288 | $ rr record out/Debug/content_shell --disable-hang-monitor --no-sandbox --disable-seccomp-sandbox --disable-setuid-sandbox --vmodule=render_frame_impl=1 https://google.com/ |
| 289 | rr: Saving execution to trace directory `...'. |
| 290 | ... |
| 291 | [128515:128515:0320/164124.768687:VERBOSE1:render_frame_impl.cc(4244)] Committed provisional load: https://www.google.com/ |
| 292 | ``` |
| 293 | |
| 294 | From the log message we can see that the site was loaded into process 128515 |
| 295 | and can set a breakpoint for when that process is forked. |
| 296 | |
| 297 | ``` |
| 298 | rr replay -f 128515 |
| 299 | ``` |
| 300 | |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 301 | ### Graphical Debugging Aid for Chromium Views |
| 302 | |
| 303 | The following link describes a tool that can be used on Linux, Windows and Mac under GDB. |
| 304 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 305 | [graphical_debugging_aid_chromium_views](graphical_debugging_aid_chromium_views.md) |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 306 | |
| 307 | ### Faster startup |
| 308 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 309 | Use the `gdb-add-index` script (e.g. |
| 310 | `build/gdb-add-index out/Debug/browser_tests`) |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 311 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 312 | Only makes sense if you run the binary multiple times or maybe if you use the |
nodir | a6074d4c | 2015-09-01 04:26:45 | [diff] [blame] | 313 | component build since most `.so` files won't require reindexing on a rebuild. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 314 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 315 | See |
| 316 | https://groups.google.com/a/chromium.org/forum/#!searchin/chromium-dev/gdb-add-index/chromium-dev/ELRuj1BDCL4/5Ki4LGx41CcJ |
| 317 | for more info. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 318 | |
andybons | 8c02a1f | 2015-09-04 17:02:32 | [diff] [blame] | 319 | You can improve GDB load time significantly at the cost of link time by |
brettw | 20d800c | 2016-04-12 00:10:49 | [diff] [blame] | 320 | splitting symbols from the object files. In GN, set `use_debug_fission=false` in |
| 321 | your "gn args". |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 322 | |
Tom Anderson | 71df887 | 2018-06-21 19:02:25 | [diff] [blame] | 323 | ### Source level debug with -fdebug-compilation-dir |
Takuto Ikuta | 3ae0e03b | 2018-05-18 06:10:40 | [diff] [blame] | 324 | |
Nico Weber | 8940a78 | 2018-10-22 23:28:28 | [diff] [blame] | 325 | When `strip_absolute_paths_from_debug_symbols` is enabled (which is the |
Tom Anderson | f06ac38 | 2019-04-10 03:49:38 | [diff] [blame] | 326 | default), gdb may not be able to find debug files, making source-level debugging |
| 327 | impossible. See |
| 328 | [gdbinit](https://chromium.googlesource.com/chromium/src/+/master/docs/gdbinit.md) |
| 329 | to configure gdb to be able to find debug files. |
Takuto Ikuta | 3ae0e03b | 2018-05-18 06:10:40 | [diff] [blame] | 330 | |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 331 | ## Core files |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 332 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 333 | `ulimit -c unlimited` should cause all Chrome processes (run from that shell) to |
| 334 | dump cores, with the possible exception of some sandboxed processes. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 335 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 336 | Some sandboxed subprocesses might not dump cores unless you pass the |
| 337 | `--allow-sandbox-debugging` flag. |
| 338 | |
| 339 | If the problem is a freeze rather than a crash, you may be able to trigger a |
| 340 | core-dump by sending SIGABRT to the relevant process: |
| 341 | |
| 342 | kill -6 [process id] |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 343 | |
| 344 | ## Breakpad minidump files |
| 345 | |
Tom Anderson | abdbd6a | 2020-01-09 16:59:27 | [diff] [blame] | 346 | See [minidump_to_core.md](minidump_to_core.md) |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 347 | |
| 348 | ## Running Tests |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 349 | |
| 350 | Many of our tests bring up windows on screen. This can be annoying (they steal |
| 351 | your focus) and hard to debug (they receive extra events as you mouse over them). |
| 352 | Instead, use `Xvfb` or `Xephyr` to run a nested X session to debug them, as |
Marijn Kruisselbrink | eebac46b | 2019-05-28 19:33:16 | [diff] [blame] | 353 | outlined on [testing/web_tests_linux.md](testing/web_tests_linux.md). |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 354 | |
| 355 | ### Browser tests |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 356 | |
| 357 | By default the `browser_tests` forks a new browser for each test. To debug the |
| 358 | browser side of a single test, use a command like |
| 359 | |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 360 | ``` |
Thomas Lukaszewicz | 2c5fb614 | 2019-10-14 19:20:05 | [diff] [blame] | 361 | gdb --args out/Debug/browser_tests --single-process-tests --gtest_filter=MyTestName |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 362 | ``` |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 363 | |
Thomas Lukaszewicz | 2c5fb614 | 2019-10-14 19:20:05 | [diff] [blame] | 364 | **note the use of `single-process-tests`** -- this makes the test harness and |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 365 | browser process share the outermost process. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 366 | |
| 367 | |
| 368 | To debug a renderer process in this case, use the tips above about renderers. |
| 369 | |
Kent Tamura | 59ffb02 | 2018-11-27 05:30:56 | [diff] [blame] | 370 | ### Web tests |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 371 | |
Marijn Kruisselbrink | eebac46b | 2019-05-28 19:33:16 | [diff] [blame] | 372 | See [testing/web_tests_linux.md](testing/web_tests_linux.md) for some tips. In particular, |
Kent Tamura | 59ffb02 | 2018-11-27 05:30:56 | [diff] [blame] | 373 | note that it's possible to debug a web test via `ssh`ing to a Linux box; you |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 374 | don't need anything on screen if you use `Xvfb`. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 375 | |
| 376 | ### UI tests |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 377 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 378 | UI tests are run in forked browsers. Unlike browser tests, you cannot do any |
| 379 | single process tricks here to debug the browser. See below about |
| 380 | `BROWSER_WRAPPER`. |
| 381 | |
| 382 | To pass flags to the browser, use a command line like |
| 383 | `--extra-chrome-flags="--foo --bar"`. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 384 | |
| 385 | ### Timeouts |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 386 | |
| 387 | UI tests have a confusing array of timeouts in place. (Pawel is working on |
| 388 | reducing the number of timeouts.) To disable them while you debug, set the |
| 389 | timeout flags to a large value: |
| 390 | |
| 391 | * `--test-timeout=100000000` |
| 392 | * `--ui-test-action-timeout=100000000` |
| 393 | * `--ui-test-terminate-timeout=100000000` |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 394 | |
| 395 | ### To replicate Window Manager setup on the bots |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 396 | |
| 397 | Chromium try bots and main waterfall's bots run tests under Xvfb&openbox |
| 398 | combination. Xvfb is an X11 server that redirects the graphical output to the |
| 399 | memory, and openbox is a simple window manager that is running on top of Xvfb. |
| 400 | The behavior of openbox is markedly different when it comes to focus management |
| 401 | and other window tasks, so test that runs fine locally may fail or be flaky on |
| 402 | try bots. To run the tests on a local machine as on a bot, follow these steps: |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 403 | |
| 404 | Make sure you have openbox: |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 405 | |
| 406 | apt-get install openbox |
| 407 | |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 408 | Start Xvfb and openbox on a particular display: |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 409 | |
| 410 | Xvfb :6.0 -screen 0 1280x1024x24 & DISPLAY=:6.0 openbox & |
| 411 | |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 412 | Run your tests with graphics output redirected to that display: |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 413 | |
| 414 | DISPLAY=:6.0 out/Debug/browser_tests --gtest_filter="MyBrowserTest.MyActivateWindowTest" |
| 415 | |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 416 | You can look at a snapshot of the output by: |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 417 | |
| 418 | xwd -display :6.0 -root | xwud |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 419 | |
| 420 | Alternatively, you can use testing/xvfb.py to set up your environment for you: |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 421 | |
thomasanderson | 3d07428 | 2016-12-06 18:21:12 | [diff] [blame] | 422 | testing/xvfb.py out/Debug/browser_tests \ |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 423 | --gtest_filter="MyBrowserTest.MyActivateWindowTest" |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 424 | |
nodir | a6074d4c | 2015-09-01 04:26:45 | [diff] [blame] | 425 | ### BROWSER_WRAPPER |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 426 | |
| 427 | You can also get the browser under a debugger by setting the `BROWSER_WRAPPER` |
| 428 | environment variable. (You can use this for `browser_tests` too, but see above |
| 429 | for discussion of a simpler way.) |
| 430 | |
| 431 | BROWSER_WRAPPER='xterm -e gdb --args' out/Debug/browser_tests |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 432 | |
qyearsley | c0dc6f4 | 2016-12-02 22:13:39 | [diff] [blame] | 433 | ### Replicating try bot Slowness |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 434 | |
qyearsley | c0dc6f4 | 2016-12-02 22:13:39 | [diff] [blame] | 435 | Try bots are pretty stressed, and can sometimes expose timing issues you can't |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 436 | normally reproduce locally. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 437 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 438 | You can simulate this by shutting down all but one of the CPUs |
| 439 | (http://www.cyberciti.biz/faq/debian-rhel-centos-redhat-suse-hotplug-cpu/) and |
| 440 | running a CPU loading tool (e.g., http://www.devin.com/lookbusy/). Now run your |
qyearsley | c0dc6f4 | 2016-12-02 22:13:39 | [diff] [blame] | 441 | test. It will run slowly, but any flakiness found by the try bot should replicate |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 442 | locally now - and often nearly 100% of the time. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 443 | |
| 444 | ## Logging |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 445 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 446 | ### Seeing all LOG(foo) messages |
| 447 | |
| 448 | Default log level hides `LOG(INFO)`. Run with `--log-level=0` and |
| 449 | `--enable-logging=stderr` flags. |
| 450 | |
qyearsley | c0dc6f4 | 2016-12-02 22:13:39 | [diff] [blame] | 451 | Newer versions of Chromium with VLOG may need --v=1 too. For more VLOG tips, see |
xiaoyin.l | 1003c0b | 2016-12-06 02:51:17 | [diff] [blame] | 452 | [the chromium-dev thread](https://groups.google.com/a/chromium.org/group/chromium-dev/browse_thread/thread/dcd0cd7752b35de6?pli=1). |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 453 | |
| 454 | ### Seeing IPC debug messages |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 455 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 456 | Run with `CHROME_IPC_LOGGING=1` eg. |
| 457 | |
| 458 | CHROME_IPC_LOGGING=1 out/Debug/chrome |
| 459 | |
| 460 | or within gdb: |
| 461 | |
| 462 | set environment CHROME_IPC_LOGGING 1 |
| 463 | |
| 464 | If some messages show as unknown, check if the list of IPC message headers in |
nodir | a6074d4c | 2015-09-01 04:26:45 | [diff] [blame] | 465 | [chrome/common/logging_chrome.cc](/chrome/common/logging_chrome.cc) is |
thakis | 3e861de | 2016-06-14 14:24:01 | [diff] [blame] | 466 | up to date. In case this file reference goes out of date, try looking for usage |
nodir | a6074d4c | 2015-09-01 04:26:45 | [diff] [blame] | 467 | of macros like `IPC_MESSAGE_LOG_ENABLED` or `IPC_MESSAGE_MACROS_LOG_ENABLED`. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 468 | |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 469 | ## Profiling |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 470 | |
| 471 | See |
| 472 | https://sites.google.com/a/chromium.org/dev/developers/profiling-chromium-and-webkit |
Tom Anderson | 93e49e49 | 2019-12-23 19:55:37 | [diff] [blame] | 473 | and [Linux Profiling](profiling.md). |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 474 | |
| 475 | ## i18n |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 476 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 477 | We obey your system locale. Try something like: |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 478 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 479 | LANG=ja_JP.UTF-8 out/Debug/chrome |
| 480 | |
| 481 | If this doesn't work, make sure that the `LANGUAGE`, `LC_ALL` and `LC_MESSAGE` |
| 482 | environment variables aren't set -- they have higher priority than LANG in the |
| 483 | order listed. Alternatively, just do this: |
| 484 | |
| 485 | LANGUAGE=fr out/Debug/chrome |
| 486 | |
| 487 | Note that because we use GTK, some locale data comes from the system -- for |
| 488 | example, file save boxes and whether the current language is considered RTL. |
| 489 | Without all the language data available, Chrome will use a mixture of your |
| 490 | system language and the language you run Chrome in. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 491 | |
| 492 | Here's how to install the Arabic (ar) and Hebrew (he) language packs: |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 493 | |
| 494 | sudo apt-get install language-pack-ar language-pack-he \ |
| 495 | language-pack-gnome-ar language-pack-gnome-he |
| 496 | |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 497 | Note that the `--lang` flag does **not** work properly for this. |
| 498 | |
Tom Anderson | 287339e | 2018-08-22 21:52:02 | [diff] [blame] | 499 | On non-Debian systems, you need the `gtk30.mo` files. (Please update these docs |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 500 | with the appropriate instructions if you know what they are.) |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 501 | |
| 502 | ## Breakpad |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 503 | |
Tom Anderson | 93e49e49 | 2019-12-23 19:55:37 | [diff] [blame] | 504 | See the last section of [Linux Crash Dumping](crash_dumping.md). |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 505 | |
| 506 | ## Drag and Drop |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 507 | |
| 508 | If you break in a debugger during a drag, Chrome will have grabbed your mouse |
| 509 | and keyboard so you won't be able to interact with the debugger! To work around |
| 510 | this, run via `Xephyr`. Instructions for how to use `Xephyr` are on the |
Marijn Kruisselbrink | eebac46b | 2019-05-28 19:33:16 | [diff] [blame] | 511 | [Running web tests on Linux](testing/web_tests_linux.md) page. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 512 | |
| 513 | ## Tracking Down Bugs |
| 514 | |
| 515 | ### Isolating Regressions |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 516 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 517 | Old builds are archived here: |
xiaoyin.l | 1003c0b | 2016-12-06 02:51:17 | [diff] [blame] | 518 | https://build.chromium.org/buildbot/snapshots/chromium-rel-linux/ |
nodir | a6074d4c | 2015-09-01 04:26:45 | [diff] [blame] | 519 | (TODO: does not exist). |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 520 | |
| 521 | `tools/bisect-builds.py` in the tree automates bisecting through the archived |
| 522 | builds. Despite a computer science education, I am still amazed how quickly |
| 523 | binary search will find its target. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 524 | |
| 525 | ### Screen recording for bug reports |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 526 | |
| 527 | sudo apt-get install gtk-recordmydesktop |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 528 | |
| 529 | ## Version-specific issues |
| 530 | |
| 531 | ### Google Chrome |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 532 | |
| 533 | Google Chrome binaries don't include symbols. Googlers can read where to get |
| 534 | symbols from |
| 535 | [the Google-internal wiki](http://wiki/Main/ChromeOfficialBuildLinux#The_Build_Archive). |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 536 | |
| 537 | ### Ubuntu Chromium |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 538 | |
| 539 | Since we don't build the Ubuntu packages (Ubuntu does) we can't get useful |
| 540 | backtraces from them. Direct users to https://wiki.ubuntu.com/Chromium/Debugging |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 541 | |
| 542 | ### Fedora's Chromium |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 543 | |
| 544 | Like Ubuntu, but direct users to |
| 545 | https://fedoraproject.org/wiki/TomCallaway/Chromium_Debug |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 546 | |
| 547 | ### Xlib |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 548 | |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 549 | If you're trying to track down X errors like: |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 550 | |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 551 | ``` |
| 552 | The program 'chrome' received an X Window System error. |
| 553 | This probably reflects a bug in the program. |
| 554 | The error was 'BadDrawable (invalid Pixmap or Window parameter)'. |
| 555 | ``` |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 556 | |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 557 | Some strategies are: |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 558 | |
| 559 | * pass `--sync` on the command line to make all X calls synchronous |
| 560 | * run chrome via [xtrace](http://xtrace.alioth.debian.org/) |
| 561 | * turn on IPC debugging (see above section) |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 562 | |
| 563 | ### Window Managers |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 564 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 565 | To test on various window managers, you can use a nested X server like `Xephyr`. |
| 566 | Instructions for how to use `Xephyr` are on the |
Kent Tamura | 59ffb02 | 2018-11-27 05:30:56 | [diff] [blame] | 567 | [Running web tests on Linux](web_tests_linux.md) page. |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 568 | |
| 569 | If you need to test something with hardware accelerated compositing |
| 570 | (e.g., compiz), you can use `Xgl` (`sudo apt-get install xserver-xgl`). E.g.: |
| 571 | |
| 572 | Xgl :1 -ac -accel glx:pbuffer -accel xv:pbuffer -screen 1024x768 |
| 573 | |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 574 | ## Mozilla Tips |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 575 | |
| 576 | https://developer.mozilla.org/en/Debugging_Mozilla_on_Linux_FAQ |