Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / docs / linux_debugging.md
blob822c23d96373d2400cbc72d0df39127396a14f06
1 # Tips for debugging on Linux
3 This page is for Chromium-specific debugging tips; learning how to run gdb is
4 out of scope.
6 [TOC]
8 ## Symbolized stack trace
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`).
14 Generally, do not use `--no-sandbox` on waterfall bots, sandbox testing is
15 needed. Talk to security@chromium.org.
17 ## GDB
19 *** promo
20 GDB-7.7 is required in order to debug Chrome on Linux.
21 ***
23 Any prior version will fail to resolve symbols or segfault.
25 ### Basic browser process debugging
27     gdb -tui -ex=r --args out/Debug/chrome --disable-seccomp-sandbox \
28         http://google.com
30 ### Allowing attaching to foreign processes
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.
37 You will probably want to disable this feature by using
39     echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
41 If you don't you'll get an error message such as "Could not attach to process".
43 Note that you'll also probably want to use `--no-sandbox`, as explained below.
45 ### Multiprocess Tricks
47 #### Getting renderer subprocesses into gdb
49 Since Chromium itself spawns the renderers, it can be tricky to grab a
50 particular with gdb. This command does the trick:
52 ```
53 chrome --no-sandbox --renderer-cmd-prefix='xterm -title renderer -e gdb --args'
54 ```
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:
64     chrome --no-sandbox --renderer-cmd-prefix='xterm -title renderer -e gdb \
65         -ex run --args
67 If you're using Emacs and `M-x gdb`, you can do
69     chrome "--renderer-cmd-prefix=gdb --args"
71 *** note
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).
76 ***
78 You may also want to pass `--disable-hang-monitor` to suppress the hang monitor,
79 which is rather annoying.
81 You can also use `--renderer-startup-dialog` and attach to the process in order
82 to debug the renderer code. Go to
83 http://www.chromium.org/blink/getting-started-with-blink-debugging for more
84 information on how this can be done.
86 #### Choosing which renderers to debug
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:
92 ```sh
93 #!/bin/sh
95 echo "**** Child $$ starting: y to debug"
96 read input
97 if [ "$input" = "y" ] ; then
98   gdb --args $*
99 else
100   $*
104 #### Selective breakpoints
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.
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 '
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 `~/.`
121 #### Connecting to a running renderer
123 Usually `ps aux | grep chrome` will not give very helpful output. Try
124 `pstree -p | grep chrome` to get something like
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)
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.
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.
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.
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`.
161 #### Getting GPU subprocesses into gdb
163 Use `--gpu-launcher` flag instead of `--renderer-cmd-prefix` in the instructions
164 for renderer above.
166 #### Getting `browser_tests` launched browsers into gdb
168 Use environment variable `BROWSER_WRAPPER` instead of `--renderer-cmd-prefix`
169 switch in the instructions above.
171 Example:
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
178 #### Plugin Processes
180 Same strategies as renderers above, but the flag is called `--plugin-launcher`:
182     chrome --plugin-launcher='xterm -e gdb --args'
184 *** note
185 Note: For now, this does not currently apply to PPAPI plugins because they
186 currently run in the renderer process.
189 #### Single-Process mode
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.
195     gdb --args chrome --single-process
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
199 http://crbug.com/361689 can also sometimes occur, but that crash can be
200 continued from without harm.
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.
207 ### Printing Chromium types
209 gdb 7 lets us use Python to write pretty-printers for Chromium types. The
210 directory `tools/gdb/` contains a Python gdb scripts useful for Chromium code.
211 There are similar scripts [in WebKit](http://trac.webkit.org/wiki/GDB) (in fact,
212 the Chromium script relies on using it with the WebKit one).
214 To include these pretty-printers with your gdb, put the following into
215 `~/.gdbinit`:
217 ```python
218 python
219 import sys
220 sys.path.insert(0, "<path/to/chromium/src>/third_party/WebKit/Tools/gdb/")
221 import webkit
222 sys.path.insert(0, "<path/to/chromium/src>/tools/gdb/")
223 import gdb_chrome
226 Pretty printers for std types shouldn't be necessary in gdb 7, but they're
227 provided here in case you're using an older gdb. Put the following into
228 `~/.gdbinit`:
231 # Print a C++ string.
232 define ps
233   print $arg0.c_str()
236 # Print a C++ wstring or wchar_t*.
237 define pws
238   printf "\""
239   set $c = (wchar_t*)$arg0
240   while ( *$c )
241     if ( *$c > 0x7f )
242       printf "[%x]", *$c
243     else
244       printf "%c", *$c
245     end
246     set $c++
247   end
248   printf "\"\n"
252 [More STL GDB macros](http://www.yolinux.com/TUTORIALS/src/dbinit_stl_views-1.01.txt)
254 ### Graphical Debugging Aid for Chromium Views
256 The following link describes a tool that can be used on Linux, Windows and Mac under GDB.
258 [graphical_debugging_aid_chromium_views](graphical_debugging_aid_chromium_views.md)
260 ### Faster startup
262 Use the `gdb-add-index` script (e.g.
263 `build/gdb-add-index out/Debug/browser_tests`)
265 Only makes sense if you run the binary multiple times or maybe if you use the
266 component build since most `.so` files won't require reindexing on a rebuild.
269 https://groups.google.com/a/chromium.org/forum/#!searchin/chromium-dev/gdb-add-index/chromium-dev/ELRuj1BDCL4/5Ki4LGx41CcJ
270 for more info.
272 You can improve GDB load time significantly at the cost of link time by
273 plitting symbols from the object files. In GN, set `use_debug_fission=false` in
274 your "gn args". In GYP add `linux_use_debug_fission=0` to your `GYP_DEFINES`.
276 ## Core files
278 `ulimit -c unlimited` should cause all Chrome processes (run from that shell) to
279 dump cores, with the possible exception of some sandboxed processes.
281 Some sandboxed subprocesses might not dump cores unless you pass the
282 `--allow-sandbox-debugging` flag.
284 If the problem is a freeze rather than a crash, you may be able to trigger a
285 core-dump by sending SIGABRT to the relevant process:
287     kill -6 [process id]
289 ## Breakpad minidump files
291 See [linux_minidump_to_core.md](linux_minidump_to_core.md)
293 ## Running Tests
295 Many of our tests bring up windows on screen. This can be annoying (they steal
296 your focus) and hard to debug (they receive extra events as you mouse over them).
297 Instead, use `Xvfb` or `Xephyr` to run a nested X session to debug them, as
298 outlined on [layout_tests_linux.md](layout_tests_linux.md).
300 ### Browser tests
302 By default the `browser_tests` forks a new browser for each test. To debug the
303 browser side of a single test, use a command like
306 gdb --args out/Debug/browser_tests --single_process --gtest_filter=MyTestName
309 **note the underscore in `single_process`** -- this makes the test harness and
310 browser process share the outermost process.
313 To debug a renderer process in this case, use the tips above about renderers.
315 ### Layout tests
317 See [layout_tests_linux.md](layout_tests_linux.md) for some tips. In particular,
318 note that it's possible to debug a layout test via `ssh`ing to a Linux box; you
319 don't need anything on screen if you use `Xvfb`.
321 ### UI tests
323 UI tests are run in forked browsers. Unlike browser tests, you cannot do any
324 single process tricks here to debug the browser. See below about
325 `BROWSER_WRAPPER`.
327 To pass flags to the browser, use a command line like
328 `--extra-chrome-flags="--foo --bar"`.
330 ### Timeouts
332 UI tests have a confusing array of timeouts in place. (Pawel is working on
333 reducing the number of timeouts.) To disable them while you debug, set the
334 timeout flags to a large value:
336 *   `--test-timeout=100000000`
337 *   `--ui-test-action-timeout=100000000`
338 *   `--ui-test-terminate-timeout=100000000`
340 ### To replicate Window Manager setup on the bots
342 Chromium try bots and main waterfall's bots run tests under Xvfb&openbox
343 combination. Xvfb is an X11 server that redirects the graphical output to the
344 memory, and openbox is a simple window manager that is running on top of Xvfb.
345 The behavior of openbox is markedly different when it comes to focus management
346 and other window tasks, so test that runs fine locally may fail or be flaky on
347 try bots. To run the tests on a local machine as on a bot, follow these steps:
349 Make sure you have openbox:
351     apt-get install openbox
353 Start Xvfb and openbox on a particular display:
355     Xvfb :6.0 -screen 0 1280x1024x24 & DISPLAY=:6.0 openbox &
357 Run your tests with graphics output redirected to that display:
359     DISPLAY=:6.0 out/Debug/browser_tests --gtest_filter="MyBrowserTest.MyActivateWindowTest"
361 You can look at a snapshot of the output by:
363     xwd -display :6.0 -root | xwud
365 Alternatively, you can use testing/xvfb.py to set up your environment for you:
367     testing/xvfb.py out/Debug out/Debug/browser_tests \
368         --gtest_filter="MyBrowserTest.MyActivateWindowTest"
370 ### BROWSER_WRAPPER
372 You can also get the browser under a debugger by setting the `BROWSER_WRAPPER`
373 environment variable.  (You can use this for `browser_tests` too, but see above
374 for discussion of a simpler way.)
376     BROWSER_WRAPPER='xterm -e gdb --args' out/Debug/browser_tests
378 ### Replicating Trybot Slowness
380 Trybots are pretty stressed, and can sometimes expose timing issues you can't
381 normally reproduce locally.
383 You can simulate this by shutting down all but one of the CPUs
384 (http://www.cyberciti.biz/faq/debian-rhel-centos-redhat-suse-hotplug-cpu/) and
385 running a CPU loading tool (e.g., http://www.devin.com/lookbusy/). Now run your
386 test. It will run slowly, but any flakiness found by the trybot should replicate
387 locally now - and often nearly 100% of the time.
389 ## Logging
391 ### Seeing all LOG(foo) messages
393 Default log level hides `LOG(INFO)`. Run with `--log-level=0` and
394 `--enable-logging=stderr` flags.
396 Newer versions of chromium with VLOG may need --v=1 too. For more VLOG tips, see
397 [the chromium-dev thread](http://groups.google.com/a/chromium.org/group/chromium-dev/browse_thread/thread/dcd0cd7752b35de6?pli=1).
399 ### Seeing IPC debug messages
401 Run with `CHROME_IPC_LOGGING=1` eg.
403     CHROME_IPC_LOGGING=1 out/Debug/chrome
405 or within gdb:
407     set environment CHROME_IPC_LOGGING 1
409 If some messages show as unknown, check if the list of IPC message headers in
410 [chrome/common/logging_chrome.cc](/chrome/common/logging_chrome.cc) is
411 up-to-date. In case this file reference goes out of date, try looking for usage
412 of macros like `IPC_MESSAGE_LOG_ENABLED` or `IPC_MESSAGE_MACROS_LOG_ENABLED`.
414 ## Using valgrind
416 To run valgrind on the browser and renderer processes, with our suppression file
417 and flags:
419     $ cd $CHROMIUM_ROOT/src
420     $ tools/valgrind/valgrind.sh out/Debug/chrome
422 You can use valgrind on chrome and/or on the renderers e.g
423 `valgrind --smc-check=all ../sconsbuild/Debug/chrome`
424 or by passing valgrind as the argument to `--render-cmd-prefix`.
426 Beware that there are several valgrind "false positives" e.g. pickle, sqlite and
427 some instances in webkit that are ignorable. On systems with prelink and address
428 space randomization (e.g. Fedora), you may also see valgrind errors in libstdc++
429 on startup and in gnome-breakpad.
431 Valgrind doesn't seem to play nice with tcmalloc. To disable tcmalloc run GYP
433     $ cd $CHROMIUM_ROOT/src
434     $ build/gyp_chromium -Duse_allocator=none
436 and rebuild.
438 ## Profiling
441 https://sites.google.com/a/chromium.org/dev/developers/profiling-chromium-and-webkit
443 http://code.google.com/p/chromium/wiki/LinuxProfiling
445 ## i18n
447 We obey your system locale. Try something like:
449     LANG=ja_JP.UTF-8 out/Debug/chrome
451 If this doesn't work, make sure that the `LANGUAGE`, `LC_ALL` and `LC_MESSAGE`
452 environment variables aren't set -- they have higher priority than LANG in the
453 order listed. Alternatively, just do this:
455     LANGUAGE=fr out/Debug/chrome
457 Note that because we use GTK, some locale data comes from the system -- for
458 example, file save boxes and whether the current language is considered RTL.
459 Without all the language data available, Chrome will use a mixture of your
460 system language and the language you run Chrome in.
462 Here's how to install the Arabic (ar) and Hebrew (he) language packs:
464     sudo apt-get install language-pack-ar language-pack-he \
465         language-pack-gnome-ar language-pack-gnome-he
467 Note that the `--lang` flag does **not** work properly for this.
469 On non-Debian systems, you need the `gtk20.mo` files. (Please update these docs
470 with the appropriate instructions if you know what they are.)
472 ## Breakpad
474 See the last section of [Linux Crash Dumping](linux_crash_dumping.md); you
475 need to set a gyp variable and an environment variable for the crash dump tests
476 to work.
478 ## Drag and Drop
480 If you break in a debugger during a drag, Chrome will have grabbed your mouse
481 and keyboard so you won't be able to interact with the debugger!  To work around
482 this, run via `Xephyr`. Instructions for how to use `Xephyr` are on the
483 [Running layout tests on Linux](layout_tests_linux.md) page.
485 ## Tracking Down Bugs
487 ### Isolating Regressions
489 Old builds are archived here:
490 http://build.chromium.org/buildbot/snapshots/chromium-rel-linux/
491 (TODO: does not exist).
493 `tools/bisect-builds.py` in the tree automates bisecting through the archived
494 builds. Despite a computer science education, I am still amazed how quickly
495 binary search will find its target.
497 ### Screen recording for bug reports
499     sudo apt-get install gtk-recordmydesktop
501 ## Version-specific issues
503 ### Google Chrome
505 Google Chrome binaries don't include symbols. Googlers can read where to get
506 symbols from
507 [the Google-internal wiki](http://wiki/Main/ChromeOfficialBuildLinux#The_Build_Archive).
509 ### Ubuntu Chromium
511 Since we don't build the Ubuntu packages (Ubuntu does) we can't get useful
512 backtraces from them. Direct users to https://wiki.ubuntu.com/Chromium/Debugging
514 ### Fedora's Chromium
516 Like Ubuntu, but direct users to
517 https://fedoraproject.org/wiki/TomCallaway/Chromium_Debug
519 ### Xlib
521 If you're trying to track down X errors like:
524 The program 'chrome' received an X Window System error.
525 This probably reflects a bug in the program.
526 The error was 'BadDrawable (invalid Pixmap or Window parameter)'.
529 Some strategies are:
531 *   pass `--sync` on the command line to make all X calls synchronous
532 *   run chrome via [xtrace](http://xtrace.alioth.debian.org/)
533 *   turn on IPC debugging (see above section)
535 ### Window Managers
537 To test on various window managers, you can use a nested X server like `Xephyr`.
538 Instructions for how to use `Xephyr` are on the
539 [Running layout tests on Linux](layout_tests_linux.md) page.
541 If you need to test something with hardware accelerated compositing
542 (e.g., compiz), you can use `Xgl` (`sudo apt-get install xserver-xgl`). E.g.:
544     Xgl :1 -ac -accel glx:pbuffer -accel xv:pbuffer -screen 1024x768
546 ## Mozilla Tips
548 https://developer.mozilla.org/en/Debugging_Mozilla_on_Linux_FAQ