Skip to content

fix: do not crash in headless mode before the package is loaded (#8392) - #170

Closed
nigelgutzmann wants to merge 1 commit into
nwjs:mainfrom
nigelgutzmann:fix-headless-null-package
Closed

nigelgutzmann wants to merge 1 commit into
nwjs:mainfrom
nigelgutzmann:fix-headless-null-package

Conversation

@nigelgutzmann

Copy link
Copy Markdown

Fixes nwjs/nw.js#8392.

Since NW.js 0.114.0 (Chromium 151), launching any app with --headless / --headless=new segfaults on startup on Linux and macOS unless --user-data-dir is passed.

Root cause

  1. ChromeMain() calls headless::InitHeadlessMode() before content::ContentMain() (chrome/app/chrome_main.cc).
  2. Since Chromium 151, CreateUniqueUserDataDir() in chrome/browser/headless/headless_mode_init.cc calls chrome::GetDefaultUserDataDirectory() on non-Windows platforms when no --user-data-dir is given, to place the temporary profile under <default>-headless/. Chromium 150 just called CreateUniqueTempDir().
  3. The NW.js versions of GetDefaultUserDataDirectory() in chrome_paths_linux.cc and chrome_paths_mac.mm call nw::package()->GetName().
  4. nw::package() is still nullptr at that point. It's only created by nw::InitNWPackage() in ChromeMainDelegate::BasicStartupComplete(), which runs inside ContentMain(). The crash is the first read through it: SEGV_MAPERR at 0x20, i.e. &Package::root_ on a null Package.

Fix

When the package isn't loaded yet, fall back to "nwjs", the default name Package::GetName() returns when the manifest has none. The Windows version (chrome_paths_win.cc) already guards nw::package() for the same reason, from crashpad's early init. Before the package loads, only headless startup calls this function, and it only uses the result as the parent folder for a unique temporary profile, so normal apps keep their profile location.

Testing

  • Reproduced on NW.js 0.119.2 Linux x64 (native x86_64 runner) and macOS arm64: --headless=new exits with SIGSEGV (139). Adding --user-data-dir=<dir>, which skips step 2, makes both start normally. NW.js 0.113.0 and upstream Chrome for Testing 151 and 156 work on the same Linux machine.
  • I haven't built NW.js with this patch; I don't have a Chromium build environment. The change only adds a null check. nw::Package is visible through content/nw/src/nw_base.h, which both files already include.

Since Chromium 151, headless startup on Linux and macOS calls
chrome::GetDefaultUserDataDirectory() from ChromeMain(), when no
--user-data-dir is given, to place its temporary profile. That runs
before ChromeMainDelegate::BasicStartupComplete() calls
nw::InitNWPackage(), so nw::package() is still null and the patched
path functions crashed dereferencing it.

Fall back to "nwjs", the default Package::GetName() name, when the
package is not loaded yet, as the Windows version already does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Thanks for your contribution! Unfortunately, we don't use GitHub pull requests to manage code contributions to this repository. Instead, please see README.md which provides full instructions on how to get involved.

@github-actions github-actions Bot closed this Oct 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Linux: --headless segfaults on startup since v0.114.0: GetDefaultUserDataDirectory() dereferences a null nw::package()

1 participant