electron
electron copied to clipboard
[Bug]: Spawning and unreferencing a child process prevents electron from exiting
Preflight Checklist
- [X] I have read the Contributing Guidelines for this project.
- [X] I agree to follow the Code of Conduct that this project adheres to.
- [X] I have searched the issue tracker for a bug report that matches the one I want to file, without success.
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, https://github.com/electron/electron/issues/2208 https://github.com/electron/electron/issues/13870. I've reproduced this on Linux on arm64 + x64 with Debian and Ubuntu (thru GitHub Action).
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
Well, I just had a deja vu and I commented the exact same thing a year ago :smile: https://github.com/electron/electron/issues/24520#issuecomment-874941656
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.
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
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.
I've tried electron 20-x-y and the 21 alpha, just in case there was any change, without success.
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);
}
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: https://github.com/electron/electron/issues/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();
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!
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
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!
This issue still affects the latest Electron, I'm now using the workaround here https://github.com/electron/electron/issues/34808#issuecomment-1275530924 by p120ph37
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!
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 https://github.com/electron/electron/issues/34808#issuecomment-1275530924 by p120ph37
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!
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 https://github.com/electron/electron/issues/34808#issuecomment-1275530924 by p120ph37
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!
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 https://github.com/electron/electron/issues/34808#issuecomment-1275530924 by p120ph37
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!
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 https://github.com/electron/electron/issues/34808#issuecomment-1275530924 by p120ph37
I received the following similar error "white screen" when running element-desktop --enable-logging on a Nvidia GPU GTX 1080. All this :hankey: javascript; no one seems to know how to code with C++ anymore :cry: .
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 :hankey: ? 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 :hankey:
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)