ferrum icon indicating copy to clipboard operation
ferrum copied to clipboard

Crash in chromium on Linux during Ferrum::Browser.new

Open kevgrig opened this issue 7 months ago • 2 comments

Describe the bug

chromium 140.0.7315.0 crashes when executing Ferrum::Browser.new on Linux x64 (Fedora 42) on top of Ruby on Rails on nginx 1.29.0 with passenger 6.0.27. Browser created with:

          self.info("FerrumBrowser starting")
          browser = Ferrum::Browser.new(
            browser_options: {
              # https://developer.chrome.com/blog/headless-chrome/
              'no-sandbox': nil,
            },
            logger: $stderr,
            window_size: [1366, 715],
            pending_connection_errors: false,
          )
          self.info("FerrumBrowser started")

The issue happens during Ferrum::Browser.new because I don't see the second print above before the crash:

Jul 24 01:29:01 web rails[77216]: [40bbb31d-76e7-4530-84fd-fe38b26579f5] FerrumBrowser starting
Jul 24 01:29:02 web systemd-coredump[78025]: Process 78022 (chrome) of user 65534 terminated abnormally with signal 6/ABRT, processing...
Jul 24 01:29:02 web systemd[1]: Started [email protected] - Process Core Dump (PID 78025/UID 0).
Jul 24 01:29:04 web systemd-coredump[78026]: Process 78022 (chrome) of user 65534 dumped core [...]

Same crash with "headless": "new" or flatten: false.

Native log output:

App 77216 output: chrome_crashpad_handler: --database is required
App 77216 output: Try 'chrome_crashpad_handler --help' for more information.
App 77216 output: [78022:78022:0724/012901.975079:ERROR:third_party/crashpad/crashpad/util/linux/socket.cc:120] recvmsg: Connection reset by peer (104)
App 77216 output: [78022:78022:0724/012901.975369:FATAL:components/crash/core/app/crashpad_linux.cc:243] Check failed: client.StartHandler(handler_path, *database_path, metrics_path, url, annotations, arguments, false, false). 
App 77216 output: #0 0x55de49c96082 base::debug::CollectStackTrace()
App 77216 output: #1 0x55de49c830be base::debug::StackTrace::StackTrace()
App 77216 output: #2 0x55de49bce7aa logging::LogMessage::Flush()
App 77216 output: #3 0x55de49bce67c logging::LogMessage::~LogMessage()
App 77216 output: #4 0x55de49bbc062 logging::(anonymous namespace)::CheckLogMessage::~CheckLogMessage()
App 77216 output: #5 0x55de49bbbd4b logging::CheckNoreturnError::~CheckNoreturnError()
App 77216 output: #6 0x55de4f820520 crash_reporter::internal::PlatformCrashpadInitialization()
App 77216 output: #7 0x55de4f816e08 crash_reporter::InitializeCrashpad()
App 77216 output: #8 0x55de447462a6 ChromeMainDelegate::PreSandboxStartup()
App 77216 output: #9 0x55de48df51b2 content::ContentMainRunnerImpl::Initialize()
App 77216 output: #10 0x55de48df33f5 content::RunContentProcess()
App 77216 output: #11 0x55de48df3707 content::ContentMain()
App 77216 output: #12 0x55de44744382 ChromeMain
App 77216 output: #13 0x7f112ef7e5f5 __libc_start_call_main
App 77216 output: #14 0x7f112ef7e6a8 __libc_start_main_alias_2
App 77216 output: #15 0x55de4474402a _start
App 77216 output: 
App 77216 output: Received signal 6

coredumpctl debug shows the command line was:

Core was generated by '/opt/chromium/1491171/chrome-linux/chrome --headless --hide-scrollbars --mute-audio --enable-automation --disable-web-security --disable-session-crashed-bubble --disable-breakpad --disable-sync --no-first-run --use-mock-keychain --keep-alive-for-test --disable-popup-blocking --disable-extensions --disable-component-extensions-with-background-pages --disable-hang-monitor --disable-features=site-per-process,IsolateOrigins,TranslateUI --disable-translate --disable-background-networking --enable-features=NetworkService,NetworkServiceInProcess --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-client-side-phishing-detection --disable-default-apps --disable-dev-shm-usage --disable-ipc-flooding-protection --disable-prompt-on-repost --disable-renderer-backgrounding --disable-site-isolation-trials --force-color-profile=srgb --metrics-recording-only --safebrowsing-disable-auto-update --password-store=basic --no-startup-window --remote-allow-origins=\* --disable-blink-features=AutomationControlled --remote-debugging-port=0 --remote-debugging-address=127.0.0.1 --window-size=1366,715 --user-data-dir=/tmp/ferrum_user_data_dir_20250724-77216-k6svj7 --no-sandbox --headless=new'.

To Reproduce

I run the same code on a Linux desktop (Fedora 42) without any problem, so I'm not sure what's unique about my production boxes (happens on all of them), though my local runs are just through the normal Rails Thin web server rather than nginx/passenger.

Desktop (please complete the following information):

  • OS: Linux
  • Browser: Chrome Version 140.0.7315.0 x64
  • Version: ferrum 0.17.1

Additional context

Originally, I was hitting this problem with the Fedora-packaged chromium 138.0.7204.157-1.fc42 so then I downloaded the latest chromium using https://github.com/scheib/chromium-latest-linux/blob/master/update.sh and pointed Ferrum to it with the BROWSER_PATH envar and it's the same issue.

kevgrig avatar Jul 24 '25 01:07 kevgrig

The following works around the issue based on a GitHub issue I found:

  1. Find the HOME directory of the process:
    $ cat /proc/78216/environ | tr '\0' '\n' | grep HOME
    HOME=/
    
  2. Set this to some variable in the shell:
    CHROME_CRASHPAD_HOME="/"
    
  3. Make some directories under the above directory:
    sudo mkdir -p ${CHROME_CRASHPAD_HOME}/.config/google-chrome/Crashpad
    
  4. Find the user running the process:
    $ ps -o user -p 78216
    USER
    nobody
    
  5. Give permissions to the user to that directory:
    chown -R nobody ${CHROME_CRASHPAD_HOME}/.config
    

I guess Ferrum should be setting --database somehow?

kevgrig avatar Jul 24 '25 02:07 kevgrig

It looks like the reason this failed in my production environment but not on my local Linux is that the behavior seems to be driven by the lack of XDG_CONFIG_HOME and XDG_CACHE_HOME envars.

My local Linux box (with a GUI):

$ cat /proc/self/environ | tr '\0' '\n' | grep -e XDG_CONFIG_HOME -e XDG_CACHE_HOME
XDG_CONFIG_HOME=/home/kevin/.config
XDG_CACHE_HOME=/home/kevin/.cache

My production boxes (without a GUI):

$ cat /proc/131088/environ | tr '\0' '\n' | grep -e XDG_CONFIG_HOME -e XDG_CACHE_HOME
$

kevgrig avatar Jul 24 '25 02:07 kevgrig