Getting renderer subprocesses into gdb

The --no-sandbox flag is needed because otherwise the seccomp sandbox will kill the renderer process on startup, or the setuid sandbox will prevent xterm‘s execution. The “xterm” is necessary or gdb will run in the current terminal, which can get particularly confusing since it’s running in the background, and if you‘re also running the main process in gdb, won’t work at all (the two instances will fight over the terminal). To auto-start the renderers in the debugger, send the “run” command to the debugger:

Note: using the --renderer-cmd-prefix option bypasses the zygote launcher, so the renderers won‘t be sandboxed. It is generally not an issue, except when you are trying to debug interactions with the sandbox. If that’s what you are doing, you will need to attach your debugger to a running renderer process (see below).

You may also want to pass --disable-hang-monitor to suppress the hang monitor, which is rather annoying.

Selective breakpoints

When debugging both the browser and renderer process, you might want to have separate set of breakpoints to hit. You can use gdb's command files to accomplish this by putting breakpoints in separate files and instructing gdb to load them.

Most of those are threads. In this case the browser process would be 672 and the (sole) renderer process is 696. You can use gdb -p 696 to attach. Alternatively, you might find out the process ID from Chrome's built-in Task Manager (under the Tools menu). Right-click on the Task Manager, and enable “Process ID” in the list of columns.

Note: by default, sandboxed processes can't be attached by a debugger. To be able to do so, you will need to pass the --allow-sandbox-debugging option.

If the problem only occurs with the seccomp sandbox enabled (and the previous tricks don‘t help), you could try enabling core-dumps (see the Core files section). That would allow you to get a backtrace and see some local variables, though you won’t be able to step through the running program.

Note: If you‘re interested in debugging LinuxSandboxIPC process, you can attach to 694 in the above diagram. The LinuxSandboxIPC process has the same command line flag as the browser process so that it’s easy to identify it if you run pstree -pa.

Getting GPU subprocesses into gdb

Use --gpu-launcher flag instead of --renderer-cmd-prefix in the instructions for renderer above.

Getting browser_tests launched browsers into gdb

Use environment variable BROWSER_WRAPPER instead of --renderer-cmd-prefix switch in the instructions above.

Plugin Processes

Same strategies as renderers above, but the flag is called --plugin-launcher:

chrome --plugin-launcher='xterm -e gdb --args'

Note: For now, this does not currently apply to PPAPI plugins because they currently run in the renderer process.

Single-Process mode

Depending on whether it‘s relevant to the problem, it’s often easier to just run in “single process” mode where the renderer threads are in-process. Then you can just run gdb on the main process.

gdb --args chrome --single-process

Currently, the --disable-gpu flag is also required, as there are known crashes that occur under TextureImageTransportSurface without it. The crash described in https://crbug.com/361689 can also sometimes occur, but that crash can be continued from without harm.

Note that for technical reasons plugins cannot be in-process, so --single-process only puts the renderers in the browser process. The flag is still useful for debugging plugins (since it‘s only two processes instead of three) but you’ll still need to use --plugin-launcher or another approach.

Printing Chromium types

gdb 7 lets us use Python to write pretty-printers for Chromium types. The directory tools/gdb/ contains a Python gdb scripts useful for Chromium code. There is a similar script in thrid_party/blink/tools/gdb, which came from WebKit.

To include these pretty-printers with your gdb, put the following into ~/.gdbinit:

You can improve GDB load time significantly at the cost of link time by splitting symbols from the object files. In GN, set use_debug_fission=false in your “gn args”.

Source level debug with -fdebug-compilation-dir

When you enable GN config strip_absolute_paths_from_debug_symbols, this is enabled by default for goma on Linux build, you need to add following command to your ~/.gdbinit for source level debugging to load customized gdbinit or copy the content of the file to your ~/.gdbinit.

source path/to/chromium/src/tools/gdb/gdbinit

Core files

ulimit -c unlimited should cause all Chrome processes (run from that shell) to dump cores, with the possible exception of some sandboxed processes.

Some sandboxed subprocesses might not dump cores unless you pass the --allow-sandbox-debugging flag.

If the problem is a freeze rather than a crash, you may be able to trigger a core-dump by sending SIGABRT to the relevant process:

kill -6 [process id]

Breakpad minidump files

Running Tests

Many of our tests bring up windows on screen. This can be annoying (they steal your focus) and hard to debug (they receive extra events as you mouse over them). Instead, use Xvfb or Xephyr to run a nested X session to debug them, as outlined on layout_tests_linux.md.

Browser tests

By default the browser_tests forks a new browser for each test. To debug the browser side of a single test, use a command like

note the underscore in single_process -- this makes the test harness and browser process share the outermost process.

To debug a renderer process in this case, use the tips above about renderers.

Layout tests

See layout_tests_linux.md for some tips. In particular, note that it‘s possible to debug a layout test via sshing to a Linux box; you don’t need anything on screen if you use Xvfb.

UI tests

UI tests are run in forked browsers. Unlike browser tests, you cannot do any single process tricks here to debug the browser. See below about BROWSER_WRAPPER.

To pass flags to the browser, use a command line like --extra-chrome-flags="--foo --bar".

Timeouts

UI tests have a confusing array of timeouts in place. (Pawel is working on reducing the number of timeouts.) To disable them while you debug, set the timeout flags to a large value:

--test-timeout=100000000

--ui-test-action-timeout=100000000

--ui-test-terminate-timeout=100000000

To replicate Window Manager setup on the bots

Chromium try bots and main waterfall's bots run tests under Xvfb&openbox combination. Xvfb is an X11 server that redirects the graphical output to the memory, and openbox is a simple window manager that is running on top of Xvfb. The behavior of openbox is markedly different when it comes to focus management and other window tasks, so test that runs fine locally may fail or be flaky on try bots. To run the tests on a local machine as on a bot, follow these steps:

Seeing all LOG(foo) messages

Seeing IPC debug messages

Run with CHROME_IPC_LOGGING=1 eg.

CHROME_IPC_LOGGING=1 out/Debug/chrome

or within gdb:

set environment CHROME_IPC_LOGGING 1

If some messages show as unknown, check if the list of IPC message headers in chrome/common/logging_chrome.cc is up to date. In case this file reference goes out of date, try looking for usage of macros like IPC_MESSAGE_LOG_ENABLED or IPC_MESSAGE_MACROS_LOG_ENABLED.

Profiling

i18n

If this doesn‘t work, make sure that the LANGUAGE, LC_ALL and LC_MESSAGE environment variables aren’t set -- they have higher priority than LANG in the order listed. Alternatively, just do this:

LANGUAGE=fr out/Debug/chrome

Note that because we use GTK, some locale data comes from the system -- for example, file save boxes and whether the current language is considered RTL. Without all the language data available, Chrome will use a mixture of your system language and the language you run Chrome in.

On non-Debian systems, you need the gtk30.mo files. (Please update these docs with the appropriate instructions if you know what they are.)

Breakpad

See the last section of Linux Crash Dumping; you need to set a gyp variable and an environment variable for the crash dump tests to work.

Drag and Drop

If you break in a debugger during a drag, Chrome will have grabbed your mouse and keyboard so you won't be able to interact with the debugger! To work around this, run via Xephyr. Instructions for how to use Xephyr are on the Running layout tests on Linux page.