Debugging Chromium on Windows

本文详细介绍如何使用Visual Studio和WinDBG调试Chromium项目,包括多进程调试、符号服务器配置、调试日志启用、V8调试、图形调试等高级技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

First see get the code for checkout and build instructions.

Getting started

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:

devenv /debugexe out\Debug\chrome.exe  <options to Chromium can go here>
 
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.
 
Profiles
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:
 
--user-data-dir=c:\tmp\my_debug_profile  (replace the path as necessary)
 
Using the IDE, go to the  Debugging tab of the properties of the chrome project, and set the  Command Arguments.
 
Chrome debug log
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.
 
Symbol server
If you are debugging official Google Chrome release builds, use the symbol server:
 
https://chromium-browser-symsrv.commondatastorage.googleapis.com
 
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:
 
.sympath+ SRV*c:\Symbols*https://chromium-browser-symsrv.commondatastorage.googleapis.com
 
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:
 
_NT_SYMBOL_PATH=SRV*C:\symbols*https://msdl.microsoft.com/download/symbols;SRV*C:\symbols*https://chromium-browser-symsrv.commondatastorage.googleapis.com
 
Note that symbol servers will let the debuggers download both the PE files (DLLs and EXEs) and the PDB files.
 
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.
 

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

Single-process mode

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

--single-process

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.

Manually attaching to a child process

You can 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. Before attaching, make sure you have selected only Native code when attaching to the process This is done by clicking Select... in the Attach to Process window and only checking Native. If you forget this, it may attempt to attach in "WebKit" mode to debug JavaScript, and you'll get an error message "An operation is not legal in the current state."
 
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:
 
--renderer-startup-dialog --no-sandbox
 
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.

Semi-automatically attaching the debugger to child 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  rendererplugin (for NPAPI),  ppapigpu-process, and  utility.
 
When using this option, it may be helpful to limit the number of renderer processes spawned, using:

--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 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.  &lt; 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 Blogmicrosoft email thread

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 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 (available as part of the Windows SDK) that can be used to flush out programming errors. Starting with M68 Application Verifier can be enabled for chrome.exe without needing to disable the sandbox. After adding chrome.exe to the list of applications to be stressed you need to expand the list of Basics checks and disable the Leak checks. You may also need to disable Handles and Locks checks depending on your graphics driver and specific Chrome version, but the eventual goal is to have Chrome run with Handles and Locks checks enabled. When bugs are found Chrome will trigger a breakpoint so running all Chrome processes under a debugger is recommended. Chrome will run much more slowly because Application Verifier puts every allocation on a separate page.
  • You can check the undocumented 'Cuzz' checkbox in Application Verifier to get the Windows thread scheduler to add some extra randomness in order to help expose race conditions in your code.
  • Putting every allocation on a separate page will dramatically affect performance so you may want to only do this for some applications. If you right-click on the Heaps checkbox and select Properties you can edit things like the size range for what allocations go into PageHeap (the page-per-allocation system) and you can set a RandRate percentage to randomly put allocations in PageHeap.
  • 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.

转载于:https://www.cnblogs.com/huangguanyuan/p/10268738.html

with sync_playwright() as p: # 启动Firefox浏览器 browser = p.chromium.launch(headless=False) 运行报错: Exception has occurred: Error BrowserType.launch: spawn EFTYPE Call log: - <launching> C:\Users\viriya\AppData\Local\ms-playwright\chromium-1181\chrome-win\chrome.exe --disable-field-trial-config --disable-background-networking --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AcceptCHFrame,AutoExpandDetailsElement,AvoidUnnecessaryBeforeUnloadCheckSync,CertificateTransparencyComponentUpdater,DestroyProfileOnBrowserClose,DialMediaRouteProvider,ExtensionManifestV2Disabled,GlobalMediaControls,HttpsUpgrades,ImprovedCookieControls,LazyFrameLoading,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Translate --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --force-color-profile=srgb --metrics-recording-only --no-first-run --password-store=basic --use-mock-keychain --no-service-autorun --export-tagged-pdf --disable-search-engine-choice-screen --unsafely-disable-devtools-self-xss-warnings --edge-skip-compat-layer-relaunch --enable-automation --no-sandbox --user-data-dir=C:\Users\viriya\AppData\Local\Temp\playwright_chromiumdev_profile-LPQu0P --remote-debugging-pipe --no-startup-window playwright._impl._errors.Error: spawn EFTYPE
最新发布
08-04
<think>我们正在解决一个Playwright启动Chromium时出现的'spawn EFTYPE'错误。根据错误信息,这个错误通常与文件系统权限或文件类型不匹配有关。结合引用内容,我们可以从以下几个方面排查: 1. **检查浏览器可执行文件是否存在**:引用[1]中提到错误信息是浏览器可执行文件不存在。虽然我们的错误是'spawn EFTYPE',但也可能是路径问题导致的。因此,首先确认`C:\Users\LC\AppData\Local\ms-playwright\chromium-1112\chrome-win\chrome.exe`是否存在。 2. **调试启动命令**:引用[2]中提到了在Playwright源码中添加调试代码来查看启动命令。我们可以尝试在本地运行一个简单的脚本,打印出启动命令,然后手动执行该命令,看是否出现同样的错误。 3. **使用Docker环境**:引用[3]提供了一个使用Docker部署Playwright的示例。如果本地环境问题难以解决,可以考虑使用Docker容器来运行,避免环境问题。 ## 解决方案步骤 ### 步骤1:验证浏览器可执行文件 首先,检查Playwright安装的浏览器可执行文件路径是否存在。如果不存在,可能是安装不完整,需要重新安装。 ```bash npx playwright install ``` ### 步骤2:检查文件权限和类型 错误'spawn EFTYPE'在Node.js中通常表示尝试执行了一个类型错误的文件(例如,不是一个可执行文件,或者文件系统不允许执行)。请检查: - 该文件是否确实是可执行文件(在Windows上是.exe文件)。 - 文件权限:确保当前用户有执行权限。 - 文件完整性:可能文件损坏,尝试重新安装浏览器。 ### 步骤3:调试启动命令 我们可以编写一个简单的Node.js脚本来启动浏览器,并捕获错误详细信息: ```javascript const { chromium } = require('playwright'); (async () => { try { const browser = await chromium.launch({ headless: false }); const context = await browser.newContext(); const page = await context.newPage(); await page.goto('https://example.com'); await browser.close(); } catch (error) { console.error('Error occurred:', error); } })(); ``` 运行这个脚本,观察详细错误信息。 ### 步骤4:手动执行浏览器 如果步骤3中打印出了启动命令(或者通过调试代码获取),尝试在命令行中手动执行该命令,看是否出现同样的错误。例如: ```bash "C:\Users\LC\AppData\Local\ms-playwright\chromium-1112\chrome-win\chrome.exe" --disable-background-networking --enable-features=NetworkService,NetworkServiceInProcess --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=TranslateUI,BlinkGenPropertyTrees,ImprovedCookieControls,SameSiteByDefaultCookies,LazyFrameLoading,GlobalMediaControls --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-sync --force-color-profile=srgb --metrics-recording-only --no-first-run --enable-automation --password-store=basic --use-mock-keychain --user-data-dir=C:\Users\LC\AppData\Local\Temp\playwright_chromiumdev_profile-8l0eY3 --remote-debugging-pipe --headless ``` 注意:上面的命令参数很长,实际中请根据打印出的命令调整。如果手动执行也出现同样的错误,则可能是文件损坏或系统限制。 ### 步骤5:使用Docker(适用于跨平台或环境问题) 如果上述步骤无法解决,可以考虑使用Docker容器运行Playwright,避免本地环境问题。按照引用[3]提供的Dockerfile示例: ```Dockerfile FROM mcr.microsoft.com/playwright/focal:latest RUN npm install -g @playwright/test WORKDIR /app # 将你的测试代码复制到容器中 COPY . . # 安装浏览器 RUN npx playwright install chromium # 运行测试 CMD ["npx", "playwright", "test"] ``` 然后构建并运行容器: ```bash docker build -t playwright-test . docker run -it playwright-test ``` ### 步骤6:检查安全软件 某些安全软件可能会阻止浏览器进程的启动,尝试暂时禁用安全软件(如杀毒软件、防火墙)后再次运行。 ## 总结 'spawn EFTYPE'错误通常与文件权限或文件类型有关。通过重新安装浏览器、检查文件权限、调试启动命令以及使用Docker容器,可以解决大多数环境问题。如果问题依旧,请提供详细的错误堆栈信息以便进一步排查。 §§相关问题§§ 1. 如何解决Playwright启动时的浏览器路径错误? 2. 如何在Docker容器中运行Playwright测试? 3. Node.js中'spawn EFTYPE'错误的常见原因有哪些?</think>针对 Playwright 启动 Chromium 时出现的 `spawn EFTYPE` 错误,这是一个与文件系统权限或文件类型相关的 Node.js 错误。以下是系统性的解决方案: ### 1. **验证浏览器可执行文件路径** 首先确认 Playwright 安装的浏览器路径是否正确: ```bash npx playwright install --dry-run ``` 检查输出中 Chromium 的安装路径是否与错误信息中的路径一致(如 `C:\Users\LC\AppData\Local\ms-playwright\chromium-1112\chrome-win\chrome.exe`)[^1]。 ### 2. **修复文件权限问题** `EFTYPE` 错误通常表示文件权限问题: ```bash # 重置文件权限 (Linux/macOS) sudo chmod -R 755 ~/.cache/ms-playwright # Windows 用户:右键点击 chrome.exe → 属性 → 安全 → 编辑权限 # 确保当前用户有"完全控制"权限 ``` ### 3. **重新安装浏览器二进制文件** 强制重新下载浏览器: ```bash npx playwright install --force chromium ``` ### 4. **检查文件系统类型(仅限 macOS/Linux)** 某些文件系统(如 NTFS-3g)可能导致此问题: ```bash df -T ~/.cache/ms-playwright ``` 如果使用不兼容的文件系统,考虑将 Playwright 安装到原生文件系统(如 APFS/ext4)。 ### 5. **调试启动命令(高级)** 参考引用[2],添加调试代码查看实际执行的命令: ```javascript // 在 node_modules/playwright-core/lib/utils/processLauncher.js 中 async function launchProcess(options) { console.log('执行命令:', options.command, options.args.join(' ')); // 添加此行 const spawnedProcess = childProcess.spawn(options.command, options.args, {...}); } ``` 运行后检查控制台输出的命令,尝试手动执行该命令验证问题[^2]。 ### 6. **使用 Docker 容器(推荐方案)** 参考引用[3],创建隔离环境: ```dockerfile # Dockerfile FROM mcr.microsoft.com/playwright/focal:latest RUN npm install -g playwright WORKDIR /app COPY . . RUN npx playwright install chromium CMD ["npx", "playwright", "test"] ``` 构建并运行: ```bash docker build -t playwright-app . docker run -it playwright-app ``` 这能彻底避免本地环境问题[^3]。 ### 7. **检查安全软件干扰** 临时禁用杀毒软件/防火墙(特别是实时扫描功能),某些安全软件会阻止浏览器进程生成。 --- **问题根源总结**: `spawn EFTYPE` 通常由以下原因引起: 1. 浏览器可执行文件损坏或权限错误 2. 文件系统不兼容(常见于跨平台开发) 3. 安全软件阻止进程生成 4. Node.js 与系统架构不匹配(如 ARM 设备运行 x86 程序) > **建议操作顺序**: > 先尝试步骤 3(重装浏览器)→ 步骤 2(修复权限)→ 步骤 6(Docker方案)→ 步骤 4(文件系统检查)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值