在Windows中调试Chromium-UF

Debugging Chromium on Windows

先参考get the code获取如果检出代码并编译。

开始(Getting started)

你可以使用Visual Studio内置的编译器或者WinDBG来调试Chromium。你不必为了使用内置的调试器而去用IDE编译。Ninja 常用来编译Chromium,大部分开发者直接在命令行中使用它来编译Chromium,然后在必要的时候打开IDE来调试自己关注的部分。在命令行中开始调试一个exe:

devenv /debugexe out\Debug\chrome.exe <options to Chromium can go here>

假设你已经安装了 Visual Studio,并且devenv.exe 路径也在你的PATH环境变量中。注意路径中必须使用反斜杠,并且必须包含最后的”.exe”后缀,否则仅仅是打开了Visual Studio,而没有启动调试。

Goma(Google内部的分布式编译器)默认使用的是 symbol_level = 1,这表示源码层的调试将不可用。如果你想要使用Goma来调试,你需要明确的设置 symbol_level = 2 & is_win_fastlink = true,但是,调试器可能会出错,所以使用时,请确保使用最新版本的调试器。

配置文件(Profiles)

在你调试的时候,使用不同的配置文件是个好主意。如果你正在调试一个Google Chrome编译版的浏览器,或者一个Chromium 编译版的,因为配置文件的冲突,你将不能同时运行这两个版本的浏览器。将来可能会解决(Google Chrome 和 Chromium 默认使用不同目录的配置文件,所以不会冲突了)。使用命令行选项:

--user-data-dir=c:\tmp\my_debug_profile (replace the path as necessary)

在IDE中,选择 调试-属性,并在chrome工程中,设置以上命令行参数。

Chrome调试日志(Chrome debug log)

在启动调试的时候,传入--enable-logging --v=1命令行参数,会启用Chrome 将调试日志写入文件。Debug版本的将chrome_debug.log日志文件放在out\Debug目录中。Release版本的放在user data顶层的目录中,具体与系统平台相关。更多信息请参考logginguser data directory

符号服务器(Symbol server)

如果你正在调试正式的Google Chrome发行版,使用这个符号服务器:

https://chromium-browser-symsrv.commondatastorage.googleapis.com.

Visual Studio的设置方法:工具-选项-调试-符号。如果你在本地设置一个缓存目录将会更快。

关于多进程(Multi-process issues)

因为Chromium的multi-process architecture,使得调试Chromium变得很有挑战。当你在调试器中选择运行的时候,只有主进程将会被调试。渲染web页面的(Renderer进程)和插件的代码将运行在另外的进程中,所以就没有被调试。ProcessExplorer工具有一个进程树视图让你可以查看这些进程之间的关系。你也可以在Chrome Task Manager中查看每个标签对应的进程id(右击浏览器窗口标题的空白部分选择打开)。

单进程模式(Single-process mode)

最简单的调试问题的方式就是使用单进程模式。这将会让你看到进程的整个状态,而没有其它额外的工作(尽管它仍然有很多线程)。添加命令行参数,来启用单进程模式:

--single-process

在这个模式下,有一些问题将不会表现出来,一些功能也不能正常运行,还有一些线程仍然会产生新的进程,所以,也不是很完美。

手动附加到子进程(Manually attaching to a child process)

你可以使用调试器来附加到正在运行的子进程中来调试。选择 工具-附加到进程 并选择 你想调试的chrome.exe。在附加之前,确认你在Attach to Process窗口中的Native cod选项中选择了Native。如果你忘记选择了,默认它会尝试用”WebKit”模式附加调试 JavaScript,并且你会得到一个”当前状态操作不合法”的错误消息。

现在你可以调试两个进程了,就好像一个一样。当你调试多个进程的时候,打开 调试-窗口-进程窗口 来切换它们。

有时候,你调试的东西可能只发生在启动的时候,想要在子进程启动的时候就看见它,使用:

--renderer-startup-dialog --no-sandbox

你必须禁用沙盒,否则弹出的对话框将被禁止显示。当对话框出现后,选择 工具-附加到进程 就附加到弹出对话框的进程了。现在,你就在调试Renderer进程了,并且可以单机对话框中OK按钮来继续执行。

其它进程类型也有这种模式的启动对话框:--gpu-startup-dialog, --ppapi-startup-dialog, --plugin-startup-dialog (for NPAPI)

你还可以使用vs谷歌插件the vs-chromium plug-in来附加到正确进程。

半自动的附加到子进程(Semi-automatically attaching the debugger to child processes)

下面的参数,将会使子进程循环等待60秒的时间来让调试器附加。如果一旦附加上了,它将继续运行,没有异常会抛出。

--wait-for-debugger-children[=filter]

filter参数选项,可以不提供,针对所有子进程。如果提供了,就匹配子进程的--type参数。包括renderer, plugin (for NPAPI), ppapi, gpu-process, and utility

使用这个参数时,限制产生renderer进程的数量或许怼你会有帮助:

--renderer-process-limit=1

映像文件执行参数(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 also issues with the sandbox.

Visual Studio小技巧(Visual Studio hints)

可视化调试(Debug visualizers)

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).

设置不需要单步进入的函数(Don’t step into trivial functions)

The debugger can be configured to automatically not step into functions based on regular expression. Edit default.natstepfilter in the following directory:

  • For Visual Studio 2015: C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Packages\Debugger\Visualizers (for all users)
    or %USERPROFILE%\My Documents\Visual Studio 2015\Visualizers (for the current user only)

  • For Visual Studio 2017 Pro: C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\Packages\Debugger\Visualizers (for all users)
    or %USERPROFILE%\My Documents\Visual Studio 2017\Visualizers (for the current user only)

Add regular expressions of functions to not step into. Remember to regex-escape and XML-escape them, e.g. < for < and . for a literal dot. Example:

<Function><Name>operator new</Name><Action>NoStepInto</Action></Function>
<Function><Name>operator delete</Name><Action>NoStepInto</Action></Function>
<!-- Skip everything in std -->
<Function><Name>std::.*</Name><Action>NoStepInto</Action></Function>
<!-- all methods on WebKit OwnPtr and variants, ... WTF::*Ptr<*>::* -->
<Function><Name>WTF::.*Ptr&lt;.*&gt;::.*</Name><Action>NoStepInto</Action></Function>

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(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"

图形调试(Graphics debugging)

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

在另一台机器上调试(Debugging on another machine)

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:

  • Make the build machine’s build volume available on the debug machine either by mounting it locally (e.g., Z:) or by crafting a UNC path to it (e.g., \builder\src)
  • Open up a command prompt and change to a local disk
  • Run src\tools\win[copy-installer.bat](https://code.google.com/p/chromium/codesearch#chromium/src/tools/win/copy-installer.bat) in the remote checkout by way of the mount (e.g., Z:\PATHTOCHECKOUT\src…) or UNC path (e.g., \builder\src…). This will copy the installer, DLLs, and PDBs into your debug machine’s C:\out or C:\build (depending on if you’re rocking the component=shared_library build or not)
  • Run C:\out\Debug\mini_installer.exe with the flags of your choice to install Chrome. This can take some time, especially on a slow machine. Watch the Task Manager and wait until mini_installer.exe exits before trying to launch Chrome (by way of the shortcut(s) created by the installer)
  • For extra pleasure, add C:\out\Debug to your _NT_SYMBOL_PATH environment variable

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).

查找内存泄漏(Find memory leaks)

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

  1. Launch GFlags.exe,
  2. Enable the user stack trace database (per image below),
  3. Launch Chrome under the debugger.
  4. Set a breakpont when chrome.dll loads with “sxe ld chrome.dll”.
  5. Step up, to allow Chrome.dll to initialize.
  6. Disable the stack trace database in GFlags.exe.
  7. Continue chrome, optionally detaching the debugger.

GFlags.exe settings for user mode stack trace database.

If you then ever suffer a browser memory leak, you can snarf a dump of the process with

umdh -p:<my browser pid> > chrome-browser-leak-umdh-dump.txt

which can then typically be “trivially” analyzed to find the culprit.

其它(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.

猜你喜欢

转载自blog.csdn.net/Vincent95/article/details/78529954