Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Spawning and unreferencing a child process prevents electron from exiting #34808

Open
3 tasks done
Josh-G opened this issue Jul 1, 2022 · 20 comments
Open
3 tasks done
Labels

Comments

@Josh-G
Copy link

Josh-G commented Jul 1, 2022

Preflight Checklist

Electron Version

19.0.7

What operating system are you using?

Other Linux

Operating System Version

Debian 10 (buster)

What arch are you using?

arm64 (including Apple Silicon)

Last Known Working Electron version

No response

Expected Behavior

Running the following:

spawn('sleep', ['10'], {
    detached: true,
    stdio: 'ignore',
}).unref();

should allow Electron to exit without waiting for the child process.

Actual Behavior

Electron emits the correct events, however some electron processes linger until the child process has completed.

Testcase Gist URL

https://gist.github.com/Josh-G/aadee165b50c7629d5f1c9340728a8ca

Additional Information

I've also created a repo with a workflow that demonstrates the issue; https://github.com/Josh-G/electron-spawn-detached

I believe this may be the same as, or a regression of, #2208 #13870.
I've reproduced this on Linux on arm64 + x64 with Debian and Ubuntu (thru GitHub Action).

@Josh-G Josh-G added the bug 🪲 label Jul 1, 2022
@Prinzhorn
Copy link
Contributor

I've noticed this in the past as well. Some processes don't exit:

  28712 ?        S      0:00 /Electron Fiddle/electron-bin/19.0.7/electron --type=zygote --no-zygote-sandbox --enable-crashpad --enable-crashpad
  28713 ?        S      0:00 /Electron Fiddle/electron-bin/19.0.7/electron --type=zygote --enable-crashpad --enable-crashpad
  28715 ?        S      0:00 /Electron Fiddle/electron-bin/19.0.7/electron --type=zygote --enable-crashpad --enable-crashpad

while these exit immediately (if you wrap process.exit in a setTimeout you will see them go away while the above stay until sleep is done):

  28971 ?        Sl     0:00 /Electron Fiddle/electron-bin/19.0.7/electron --type=gpu-process --enable-crashpad --enable-crash-reporter=a9f51b37-898e-4b52-a491-88193519d896,no_channel --user-data-dir=/illustrious-speaker-spend-o4irg --gpu-preferences=WAAAAAAAAAAgAAAIAAAAAAAAAAAAAAAAAABgAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAAAAAAABAAAAAAAAAAgAAAAAAAAACAAAAAAAAAAIAAAAAAAAAA== --shared-files --field-trial-handle=0,i,10080314104194432827,127912701232379743,131072 --disable-features=SpareRendererForSitePerProcess
  28986 ?        Sl     0:00 /Electron Fiddle/electron-bin/19.0.7/electron --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --enable-crashpad --enable-crash-reporter=a9f51b37-898e-4b52-a491-88193519d896,no_channel --user-data-dir=/illustrious-speaker-spend-o4irg --shared-files=v8_context_snapshot_data:100 --field-trial-handle=0,i,10080314104194432827,127912701232379743,131072 --disable-features=SpareRendererForSitePerProcess --enable-crashpad

@Prinzhorn
Copy link
Contributor

Prinzhorn commented Jul 1, 2022

Well, I just had a deja vu and I commented the exact same thing a year ago 😄 #24520 (comment)

Electron processes are kept alive

For some reason this child process (that now belongs to systemd) keeps several Electron processes alive. To me this looks broken?

 $ ps ax | grep electron
  16478 ?        S      0:00 /home/alex/.config/Electron Fiddle/electron-bin/13.1.6/electron --type=zygote --no-zygote-sandbox
  16479 ?        S      0:00 /home/alex/.config/Electron Fiddle/electron-bin/13.1.6/electron --type=zygote
  16481 ?        S      0:00 /home/alex/.config/Electron Fiddle/electron-bin/13.1.6/electron --type=zygote

Back then what I meant with "normal unix behavior" is that the sleep process will be moved to the next parent (e.g. systemd) and does not exit with Electron. But it shouldn't keep Electron waiting for it.

@Josh-G
Copy link
Author

Josh-G commented Jul 3, 2022

When using electron-updater on Linux with the AppImage target, this can cause a significant amount of lingering processes on long-running hosts that apply multiple updates

@jkleinsc jkleinsc added the has-repro-gist Issue can be reproduced with code at https://gist.github.com/ label Jul 13, 2022
@Prinzhorn
Copy link
Contributor

Just started writing e2e tests and now this becomes a real problem. The tests will time out because Electron never exits.

Even this is not enough:

app.exit(0);
process.exit(0);

As long as the child process does not exit, playwrights await app.close() will never resolve. If I kill the child process manually, the test passes, because the lingering Electron processes can finally exit.

@Kilian Kilian added 20-x-y and removed 20-x-y labels Aug 2, 2022
@Josh-G
Copy link
Author

Josh-G commented Aug 5, 2022

I've tried electron 20-x-y and the 21 alpha, just in case there was any change, without success.

@NathanaelA
Copy link

I am seeing the exact same behavior, I have a work around I'm using right now...

Basically I created a function that calls the "app.close/process.exit" message, but ALSO kills all processes associated with the parent if a forceExit flag is set and it is on linux. Not the most graceful solution, but the only one I could find that actually worked... So forceExit gets set true in a couple instances in my app while the child is still running...

export function exitApp(value=0, forceExit=false) {
  if (forceExit) {
    if (process.platform === 'linux') {
      // TODO: Remove HACK -- This is because of Electron Bug only on Linux and spawns
      const result = execSync('ps -o pgid= -p ' + process.pid);
      const val = parseInt(result.toString().trim(), 10);
      // If we don't have a Group ID, there is nothing we can do, this means "ps" isn't installed... 
      if (val > 0) {
        spawn('kill', ['-term', '--', '-' + val], {detached: true, stdio: 'ignore'});
        app.quit();
        process.exit(0);
      } 
    }
  }
  app.quit();
  process.exit(value);
}

@p120ph37
Copy link
Contributor

The issue is that Chrome/Electron leaks open file-descriptors into the child-process. For one reason or another, these open file-descriptors being held by the child-process are keeping parts of Electron from exiting until they are closed. Try looking at the /proc/$PID/fd filesystem for the child-process, and you will see all of the inherited open descriptors. The general problem was discussed here, and is in a wont-fix status: #1447

One way around this is to loop over all the open file-descriptors that your child-process has inherited and close them all. (of course it would be better if Electron were to provide this functionality in the child_process functions directly...)

Below is a wrapper which accomplishes this with some bash magic:

const mySpawn = (command, args = [], options) => spawn(
  '/bin/bash',
  ['-c', 'for fd in $(ls /proc/$$/fd); do case "$fd" in 0|1|2|255) ;; *) eval "exec $fd<&-" ;; esac ; done; exec "$@"' , '--', command, ...args],
  options
);

// This now works...
mySpawn('sleep', ['10'], {
    detached: true,
    stdio: 'ignore',
}).unref();

@github-actions
Copy link
Contributor

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. If you have any new additional information—in particular, if this is still reproducible in the latest version of Electron or in the beta—please include it with your comment!

@github-actions github-actions bot added the stale label Jan 11, 2023
@Prinzhorn
Copy link
Contributor

Still repros with 22.0.1 and 23.0.0-beta.1. After the main process exits, these three processes will stay until the child has exited:

/node_modules/electron/dist/electron --type=zygote --no-zygote-sandbox
/node_modules/electron/dist/electron --type=zygote
/node_modules/electron/dist/electron --type=zygote

@github-actions github-actions bot removed the stale label Jan 12, 2023
@github-actions
Copy link
Contributor

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. If you have any new additional information—in particular, if this is still reproducible in the latest version of Electron or in the beta—please include it with your comment!

@github-actions github-actions bot added the stale label Apr 13, 2023
@NathanaelA
Copy link

This issue still affects the latest Electron, I'm now using the workaround here #34808 (comment) by p120ph37

@github-actions github-actions bot removed the stale label Apr 14, 2023
@github-actions
Copy link
Contributor

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. If you have any new additional information—in particular, if this is still reproducible in the latest version of Electron or in the beta—please include it with your comment!

@github-actions github-actions bot added the stale label Jul 13, 2023
@NathanaelA
Copy link

Anyway we can turn off the "Stale" bot on this issue?

This issue still affects the latest Electron, I'm still using the workaround here #34808 (comment) by p120ph37

@github-actions github-actions bot removed the stale label Jul 14, 2023
@electron-issue-triage
Copy link

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. If you have any new additional information—in particular, if this is still reproducible in the latest version of Electron or in the beta—please include it with your comment!

@NathanaelA
Copy link

Anyway we can turn off the "Stale" bot on this issue?

This issue still affects the latest Electron, I'm still using the workaround here #34808 (comment) by p120ph37

@electron-issue-triage
Copy link

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. If you have any new additional information—in particular, if this is still reproducible in the latest version of Electron or in the beta—please include it with your comment!

@NathanaelA
Copy link

Anyway we can turn off the "Stale" bot on this issue?

This issue still affects the latest Electron, I'm still using the workaround here #34808 (comment) by p120ph37

@electron-issue-triage
Copy link

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. If you have any new additional information—in particular, if this is still reproducible in the latest version of Electron or in the beta—please include it with your comment!

@NathanaelA
Copy link

Anyway we can turn off the "Stale" bot on this issue?

This issue still affects the latest Electron, I'm still using the workaround here #34808 (comment) by p120ph37

@oDinZu
Copy link

oDinZu commented Apr 21, 2024

I received the following similar error "white screen" when running element-desktop --enable-logging on a Nvidia GPU GTX 1080. All this 💩 javascript; no one seems to know how to code with C++ anymore 😢 .

I build my applications with GTK 4 (C/C++) in parallel with a nice UI named Cambalache.

Electron Version: electron29-29.3.1-1
Operating System: Arch Linux

So many npm/nodejs monsters nowadays.

Anyone have any recommendations for a client built with non-js 💩 ? JS is a security nightmare to begin with and am humored by all the js being used for secure messaging app..electron is a bloated piece of yuk imo and should rarely be used for a professional application.

A fresh init of element-desktop with electron-29 💩

Resetting the UI components after locale change
Resetting the UI components after locale change
[33791:0421/192133.432115:ERROR:angle_platform_impl.cc(44)] Display.cpp:1052 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
ERR: Display.cpp:1052 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
[33791:0421/192133.432323:ERROR:gl_display.cc(515)] EGL Driver message (Critical) eglInitialize: Could not create a backing OpenGL context.
[33791:0421/192133.432408:ERROR:gl_display.cc(786)] eglInitialize OpenGL failed with error EGL_NOT_INITIALIZED, trying next display type
[33791:0421/192133.515433:ERROR:angle_platform_impl.cc(44)] Display.cpp:1052 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
ERR: Display.cpp:1052 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
[33791:0421/192133.515593:ERROR:gl_display.cc(515)] EGL Driver message (Critical) eglInitialize: Could not create a backing OpenGL context.
[33791:0421/192133.515668:ERROR:gl_display.cc(786)] eglInitialize OpenGLES failed with error EGL_NOT_INITIALIZED
[33791:0421/192133.515745:ERROR:gl_display.cc(820)] Initialization of all EGL display types failed.
[33791:0421/192133.515818:ERROR:gl_ozone_egl.cc(26)] GLDisplayEGL::Initialize failed.
[33791:0421/192133.939565:ERROR:angle_platform_impl.cc(44)] Display.cpp:1052 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
ERR: Display.cpp:1052 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
[33791:0421/192133.939728:ERROR:gl_display.cc(515)] EGL Driver message (Critical) eglInitialize: Could not create a backing OpenGL context.
[33791:0421/192133.939850:ERROR:gl_display.cc(786)] eglInitialize OpenGL failed with error EGL_NOT_INITIALIZED, trying next display type
[33791:0421/192134.024441:ERROR:angle_platform_impl.cc(44)] Display.cpp:1052 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
ERR: Display.cpp:1052 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
[33791:0421/192134.024588:ERROR:gl_display.cc(515)] EGL Driver message (Critical) eglInitialize: Could not create a backing OpenGL context.
[33791:0421/192134.024665:ERROR:gl_display.cc(786)] eglInitialize OpenGLES failed with error EGL_NOT_INITIALIZED
[33791:0421/192134.024737:ERROR:gl_display.cc(820)] Initialization of all EGL display types failed.
[33791:0421/192134.024805:ERROR:gl_ozone_egl.cc(26)] GLDisplayEGL::Initialize failed.
[33791:0421/192134.027053:ERROR:viz_main_impl.cc(196)] Exiting GPU process due to errors during initialization
[33827:0421/192134.201826:WARNING:vaapi_wrapper.cc(1497)] Skipping nVidia device named: nvidia-drm
[33827:0421/192134.206091:WARNING:sandbox_linux.cc(418)] InitializeSandbox() called with multiple threads in process gpu-process.
[33811:0421/192134.214034:ERROR:command_buffer_proxy_impl.cc(131)] ContextResult::kTransientFailure: Failed to send GpuControl.CreateCommandBuffer.
<--- Last few GCs --->

[4:0x30a424a38000]      725 ms: Mark-Compact (reduce) 45.5 (63.5) -> 45.4 (48.2) MB, pooled: 0 MB, 91.32 / 0.00 ms  (average mu = 0.874, current mu = 0.874) last resort; GC in old space requested
[4:0x30a424a38000]      809 ms: Mark-Compact (reduce) 45.4 (48.2) -> 45.4 (48.2) MB, pooled: 0 MB, 83.64 / 0.00 ms  (average mu = 0.784, current mu = 0.000) last resort; GC in old space requested


<--- JS stacktrace --->

[33083:0421/191751.181926:ERROR:v8_initializer.cc(799)] V8 javascript OOM (Committing semi space failed.).
Renderer process crashed - see https://www.electronjs.org/docs/tutorial/application-debugging for potential debugging information.

^CError sending from webFrameMain:  Error: Render frame was disposed before WebFrameMain could be accessed
    at s.send (node:electron/js2c/browser_init:2:84285)
    at _.send (node:electron/js2c/browser_init:2:69269)
    at App.beforeQuit (/usr/lib/element/app.asar/lib/electron-main.js:551:82)
    at App.emit (node:events:514:28)
    at App.emit (node:domain:488:12)
Segmentation fault (core dumped)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
No open projects
Status: Does Not Block Stable
Development

No branches or pull requests

10 participants