You can use Visual Studio's built-in debugger or WinDBG to debug Chromium. You don't need to use the IDE to build in order to use the debugger: Ninja is used to build Chromium and most developers invoke it from a command prompt, and then open the IDE for debugging as necessary. To start debugging an executable from the command line:
This assumes you have Visual Studio installed and have devenv.exe on your path. Note that the path to the binary must use backslashes and must include the ".exe" suffix or Visual Studio will open and do nothing.
Goma (the internal Google distributed build) defaults to symbol_level = 1 which means source-level debugging will not work. If you want full debugging with goma then you need to explicitly set symbol_level = 2, and is_win_fastlink = true, however this does tend to expose bugs in debuggers, so caveat debugger, and be sure to use the very latest versions of the debuggers.
It's a good idea to use a different profile for your debugging. If you are debugging Google Chrome branded builds, or use a Chromium build as your primary browser, the profiles can collide so you can't run both at once, and your stable browser might see profile versions from the future (Google Chrome and Chromium use different profile directories by default so won't collide). Use the command-line option:
Using the IDE, go to?the Debugging tab of the properties of the chrome project, and set?the?Command Arguments.
Enable Chrome debug logging to a file by passing?--enable-logging --v=1?command-line flags at startup.?Debug builds place the?chrome_debug.log?file in the?out\Debug?directory. Release builds place the file in the top level of the user data Chromium app directory, which is OS-version-dependent. For more information, see?logging?and?user data directory?details.
If you are debugging official Google Chrome release builds, use the symbol server:
In Visual Studio, this goes in?Tools > Options?under?Debugging > Symbols. You should set?up a local cache in a empty directory on your computer.
In windbg you can add this to your symbol server search path with the command below, where c:\Symbols is a local cache directory:
You can also set the _NT_SYMBOL_PATH environment variable to include both the Microsoft and Google symbol servers - VS and windbg should both respect this environment variable:
Note that symbol servers will let the debuggers download both the PE files (DLLs and EXEs) and the PDB files.
Chrome often loads third party libraries and partial symbols for some of these are also public. For example:
For example, for completeness, the following symbol server environment variable will resolve all of above sources:
If you set up source indexing (.srcfix in windbg, Tools-> Options-> Debugging-> General-> Enable source server support in Visual Studio) then the correct source files will automatically be downloaded based on information in the downloaded symbols.
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.?The?ProcessExplorer?tool has a process tree view where you can see how these processes are related. You can also get the process IDs associated with each tab from the Chrome Task Manager (right-click on an empty area of the window title bar to open).
Automatically attach to child processes
There are two Visual Studio extensions that enable the debugger to automatically attach to all Chrome processes, so you can debug all of Chrome at once. Microsoft's Child Process Debugging Power Tool?is a standalone extension for this, and?VsChromium?is another option that bundles many other additional features. In addition to installing one of these extensions, you must?run Visual Studio as Administrator, or it will silently fail to attach to some of Chrome's child processes.
One 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
This approach isn't perfect because some problems won't manifest themselves in this mode and some features don't work and worker threads are still spawned into new processes.
You can now debug the two processes as if they were one.?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. Use:
You have to disable the sandbox or the dialog box will be prohibited from showing.?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 and can continue execution by pressing OK in the dialog.
Startup dialogs also exist for other child process types: --gpu-startup-dialog, --ppapi-startup-dialog, --plugin-startup-dialog (for NPAPI).
You can also?try?the vs-chromium plug-in?to attach to the right processes.
The following flags cause child 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.
--wait-for-debugger-children[=filter]The filter, if provided, will fire only if it matches the --type parameter to the process. Values include renderer, plugin (for NPAPI), ppapi, gpu-process, and?utility.
When using this option, it may be helpful to limit the number of renderer processes spawned, using:
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 also issues with the sandbox.
Chrome's custom debug visualizers should be added to the pdb files and automatically picked up by Visual Studio. The definitions are in?//tools/win/DebugVisualizers?if you need to modify them (the BUILD.gn file there has additional instructions).
The debugger can be configured to automatically not step into functions based on regular expression. Edit?default.natstepfilter?in the following directory:
? <Function><Name>operator new</Name><Action>NoStepInto</Action></Function>
? <Function><Name>operator delete</Name><Action>NoStepInto</Action></Function>
? <!-- Skip everything in std -->
? <!-- all methods on WebKit OwnPtr and variants, ... WTF::*Ptr<*>::* -->
This file is read at start of a debugging session (F5), so you don't need to restart Visual Studio after changing it.More info:?Andy Pennel's Blog,?microsoft email thread
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:
GPU Acceleration of rendering can be more easily debugged with tools. See:
Sometimes it's useful to debug installation and execution on a machine other than your primary build box. To run the installer on said other machine, first build the mini_installer target on your main build machine (e.g., ninja -C out\Debug mini_installer). Next, on the debug machine:
Consider reading the documentation at the top of copy-installer.bat to see how you can run it. It tries to be smart and copy the right things, but you may need to be explicit (e.g., "copy-installer.bat out Debug"). It is safe to re-run the script to copy only modified files (after a rebuild, for example).
The Windows heap manager has a really useful debug flag, where it can be asked to capture and store a stack trace with every allocation. The tool to scrape these stack traces out of processes is UMDH, which comes with WinDbg.
UMDH is great. It will capture a snapshot of the heap state as many times as you like, and it'll do it fairly quickly. You then run it again against either a single snapshot, or a pair of snapshots, at which time it'll symbolize the stack traces and aggregate usage up to unique stack traces.
Turning on the user stack trace database for chrome.exe with gflags.exe makes it run unbearably slowly; however, turning on the user stack trace database on for the browser alone is just fine.
While it's possible to turn on the user stack database with the "!gflag" debugging extension, it's too late to do this by the time the initial debugger breakpoint hits. The only reasonable way to do this is to?
If you then ever suffer a browser memory leak, you can snarf a dump of the process with?