For Developers‎ > ‎How-Tos‎ > ‎

Debugging Chromium on Windows

This page has detailed information to help you debug Chromium on Windows.

Note: If you've never built or debugged Chromium on Windows, first read the Windows build instructions.

Before you start

Requirements

You can use Visual Studio's built-in debugger or WinDBG to debug Chromium.

Optional

So that you can continue to run release versions of the browser — and avoid incompatible profile changes — while you debug, you should use a different profile for your debug Chromium instance from the release build that you use. You can set the profile by modifying the command line used to launch Chromium from the debugger. To do this, go to the Debugging tab of the properties of the chrome project, and set the Command Arguments field to --user-data-dir=c:\tmp\my_debug_profile. (Replace c:\tmp\my_debug_profile with a directory of your choosing.) Another possibility, if you have lots of different checkouts, is to change the path of the shortcut you use for the release build so that it sets the profile.

Tools such as ProcessExplorer, Spy++/Winspector Spy, Inspect32, and FileMon may be of use when debugging different parts of Chromium.

Multi-process issues

Chromium can be challenging to debug because of its multi-process architecture. When you select Run in the debugger, only the main Browser process will be debugged. The code that actually renders web pages (the Renderer) and the plugins will be in separate processes that's not (yet!) being debugged.

There are a number of approaches to solving this problem.

Single-process mode

The easiest way to debug issues is to run Chromium in single-process mode. This will allow you to see the entire state of the program without extra work (although it will still have many threads). To use single-process mode, add the command-line flag --single-process to the Command Arguments field in the Debugging tab of the properties of the chrome project. This approach isn't perfect because some problems won't manifest themselves in this mode. Also, even in single-process mode, worker threads are spawned into new processes.


Tip: By default, when you load the project, Visual Studio may select
Browser/browser.exe as the "startup project," and you will notice that chrome.exe is not bolded in the list of projects. If this is the case, then just clicking Debug > Start Debugging will start a different project, and ignore the command line flag you just provided. To change this, right-click the chrome.exe project and choose Set As Startup Project.

Using Image File Execution Options


Using Image File Execution Options (IFEO) will not work,  because CreateProcess() returns the handle to the debugger process instead of the intended child process. There are issues too with the sandbox.

Debugging with Visual Studio

Attaching to the renderer

You can also attach to the running child processes with the debugger. Select Tools > Attach to Process and click the chrome.exe process you want to attach to. You can now debug the two processes as if they were one. Use this macro to attach to the right processes.

When you are debugging multiple processes, open the Debug > Windows > Processes window to switch between them.

Sometimes you are debugging something that only happens on startup, and want to see the child process as soon as it starts. In this case, you can use the --renderer-startup-dialog command line flag to the browser. Important note: If you use this flag you also have to pass the --no-sandbox flag, since the sandbox will otherwise prevent the renderer from showing a startup dialog. The browser will pass this along to each renderer it starts, which will display a message box as soon as it starts. When the dialog appears, visit Tools > Attach to Process and attach to the process showing the Renderer startup dialog. Now you're debugging in the renderer.

Semi-automatically attaching the debugger to child processes

The following flags cause the processes to wait for 60 seconds in a busy loop for a debugger to attach to the process. Once either condition is true, it continues on; no exception is thrown. This is the only reliable way to debug an issue occurring on process startup with Visual Studio.

Usage

chrome.exe [--wait-for-debugger-children[=filter]] [--wait-for-debugger]
  • filter = plugin | renderer
  • --wait-for-debugger-children waits for a debugger in child processes for 60 seconds.
  • --wait-for-debugger waits for a debugger for 60 seconds.
It should be used with the .NET macro to help catch the processes. Alt-P does the job, too.

Symbol server

Save yourself some time and debug an official build! Setup your symbols:
  1. Menu Tools, Options
  2. Debugging, Symbols
  3. Add http://msdl.microsoft.com/download/symbols and http://chromium-browser-symsrv.commondatastorage.googleapis.com
  4. Setup a local cache in a empty directory on your computer, otherwise it'll be very slow.
Important note: release build debugging is much easier with WinDBG.

Don't step into trivial functions

Right click and select "Step Into Specific" when the current statement is on a line with multiple function calls.

The debugger can be configured to automatically not step into functions based on regular expression:
  • Find the registry location for your version of Visual Studio
    • Open regedit
    • Edit -> Find "StepOver"
      • (You only need to search Keys, and can match whole string only)
      • Different visual studio versions have different locations, e.g.:
        HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\9.0\NativeDE\StepOver
      • Check if you have more than one, if so, pick the right version. ;) e.g. VS2008 == VS9.0
  • Add regular expressions of functions to not step into, 
    • colons and angle brackets must be escaped with a \
    • You don't need to suffix =nostepinto, it's the default
    • Examples:
      • operator (new|delete).*   - operator new and delete
      • std\:\:.*                 - Skip everything in std.
      • WTF\:\:.*Ptr\<.*\>\:\:.*  - all methods on WebKit OwnPtr and variants, ... WTF::*Ptr<*>::*
  • Registry is read at start of a debugging session with F5.
  • More info: Andy Pennel's Blogmicrosoft email thread

Debugging with WinDBG

WinDBG is a great, free tool. It is more powerful than Visual Studio's built-in debugger, but is harder to use and doesn't have a nice GUI (kind of like gdb on Linux). You can retrieve the latest version from Microsoft's web site.

Initial setup

Once you're started, you may wish to fix a few things:
  1. In menu File, Symbol File Path, type this with c:\code\symbols with your local symbol cache:
    1. SRV*c:\code\symbols*http://msdl.microsoft.com/download/symbols;SRV*c:\code\symbols*http://chromium-browser-symsrv.commondatastorage.googleapis.com
  2. Open a few window from the View menu. 
  3. Use File, Open executable to start debugging
  4. In the command prompt, you may want to use these commands:
    1. .asm no_code_bytes
      1. disables display of opcodes
    2. .prompt_allow -sym -dis -ea -reg -src
      1. Disables display of symbol for the current instruction, disassembled instructions, effective address of current instruction, current state of registers and source line for the current instruction
  5. In menu File, Source File Path, ensure that the Source Path is set to: src*

Common commands

  • dt this->member_
    • Displays the data
  • x chrome*!*function_name
    • Find a symbol.
  • .open -a [symbol address or complete symbol name found by using x]
    • Opens the source file containing the specified symbol. Pretty neat.
  • ?? [data name]
    • Quick evaluation of a C++ symbol (local variable, etc). You don't need to specify this-> for member variables but it's slower if you don't.
One of the major benefits of WinDBG for debugging Chromium is its ability to automatically debug child processes. This allows you to skip all the complicated instructions above. The easiest way to enable this is to check "Debug child processes also" in the "Open Executable" dialog box when you start debugging or start "windbg.exe -o".  NOTE that on 64-bit Windows you need to use the 64-bit WinDbg for this to work!

V8 and Chromium

V8 supports many command-line flags that are useful for debugging. V8 command-line flags can be set via the Chromium command-line flag --js-flags; for instance:

chrome.exe --js-flags="--trace_exception --heap_stats"

Note that some V8 command-line flags exist only in the debug build of V8. For a list of all V8 flags try:

chrome.exe --js-flags="--help"

Graphical Debugging

GPU Acceleration of rendering can be more easily debugged with tools. See:

Miscellaneous

  • Application Verifier is a free tool from Microsoft. For the tool to run, you must disable the sandbox (--no-sandbox) and run all app-verified processes in a debugger. This means that you must run the renderer and plugin processes in a debugger or they will fail in mysterious ways. Use any of the methods mentioned above to attach to the renderer processes when they run.
  • To put a breakpoint on CreateFile(), add this break point:
{,,kernel32.dll}_CreateFileW@28
    • {,,kernel32.dll}specifies the DLL (context operator).
    • _ prefix means extern "C".
    • @28 postfix means _stdcall with the stack pop at the end of the function. i.e. the number of arguments in BYTES.
  • You can use DebugView from SysInternals or sawbuck to view LOG() messages that normally goes to stderr on POSIX.
Subpages (1): PIX for Windows
Comments