iohook
iohook copied to clipboard
Built electron binary crashes with segfault
Expected Behavior
Current Behavior
strace binaryName
poll([{fd=46, events=POLLIN|POLLOUT}], 1, -1) = 1 ([{fd=46, revents=POLLOUT}])
writev(46, [{iov_base="\20\1\6\0\20\0\0\0SCREEN_RESOURCES", iov_len=24}, {iov_base=NULL, iov_len=0}, {iov_base="", iov_len=0}], 3) = 24
poll([{fd=46, events=POLLIN}], 1, -1) = 1 ([{fd=46, revents=POLLIN}])
recvmsg(46, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="\1\0\t\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", iov_len=4096}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 32
uname({sysname="Linux", nodename="x-Lenovo-ideapad-530S-15IKB", ...}) = 0
openat(AT_FDCWD, "/home/x/.Xdefaults-x-Lenovo-ideapad-530S-15IKB", O_RDONLY) = -1 ENOENT (No such file or directory)
access("/home/x/en_US.UTF-8/libuiohook-color", R_OK) = -1 ENOENT (No such file or directory)
access("/home/x/en/libuiohook-color", R_OK) = -1 ENOENT (No such file or directory)
access("/home/x/libuiohook-color", R_OK) = -1 ENOENT (No such file or directory)
access("/home/x/en_US.UTF-8/libuiohook", R_OK) = -1 ENOENT (No such file or directory)
access("/home/x/en/libuiohook", R_OK) = -1 ENOENT (No such file or directory)
access("/home/x/libuiohook", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/X11/en_US.UTF-8/app-defaults/libuiohook", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/X11/en/app-defaults/libuiohook", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/X11/app-defaults/libuiohook", R_OK) = -1 ENOENT (No such file or directory)
access("/etc/X11/en_US.UTF-8/app-defaults/libuiohook-color", R_OK) = -1 ENOENT (No such file or directory)
access("/etc/X11/en/app-defaults/libuiohook-color", R_OK) = -1 ENOENT (No such file or directory)
access("/etc/X11/app-defaults/libuiohook-color", R_OK) = -1 ENOENT (No such file or directory)
access("/etc/X11/en_US.UTF-8/app-defaults/libuiohook", R_OK) = -1 ENOENT (No such file or directory)
access("/etc/X11/en/app-defaults/libuiohook", R_OK) = -1 ENOENT (No such file or directory)
access("/etc/X11/app-defaults/libuiohook", R_OK) = -1 ENOENT (No such file or directory)
poll([{fd=45, events=POLLIN|POLLOUT}], 1, -1) = 1 ([{fd=45, revents=POLLOUT}])
writev(45, [{iov_base="\207\27\5\0\0\1\377\0\377\0\0\0\0\0\0\0\0\0\0\0", iov_len=20}, {iov_base=NULL, iov_len=0}, {iov_base="", iov_len=0}], 3) = 20
poll([{fd=45, events=POLLIN}], 1, -1) = 1 ([{fd=45, revents=POLLIN}])
recvmsg(45, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="\1\3\7\0\371\f\0\0\10\377\0\0\177\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., iov_len=4096}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 4096
recvfrom(45, "k\377\10\20\0\0\0\0\1\1\1\0m\377\10\20\0\0\0\0\1\1\1\0h\377\0\0\0\0\0\0"..., 9220, 0, NULL, NULL) = 9220
poll([{fd=45, events=POLLIN|POLLOUT}], 1, -1) = 1 ([{fd=45, revents=POLLOUT}])
writev(45, [{iov_base="\21\27\2\0w\2\0\0", iov_len=8}, {iov_base=NULL, iov_len=0}, {iov_base="", iov_len=0}], 3) = 8
poll([{fd=45, events=POLLIN}], 1, -1) = 1 ([{fd=45, revents=POLLIN}])
recvmsg(45, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="\1\0\10\0\6\0\0\0\25\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., iov_len=4096}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 56
poll([{fd=45, events=POLLIN|POLLOUT}], 1, -1) = 1 ([{fd=45, revents=POLLOUT}])
writev(45, [{iov_base="\207\10\7\0\0\1\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", iov_len=28}, {iov_base=NULL, iov_len=0}, {iov_base="", iov_len=0}], 3) = 28
poll([{fd=45, events=POLLIN}], 1, -1) = 1 ([{fd=45, revents=POLLIN}])
recvmsg(45, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="\1\3\t\0E\5\0\0\0\0\10\377\7\0\0\34\34\10k\1\370\0\0\0\0\0\0\0\0\0\0\10"..., iov_len=4096}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 4096
recvfrom(45, "\0\0\0\0\1\1\1\0h\377\0\0\0\0\0\0\1\1\1\0X\377\10\20\0\0\0\0\1\1\1\0"..., 1332, 0, NULL, NULL) = 1332
munmap(0x7f823cb05000, 92573) = 0
--- SIGSEGV {si_signo=SIGSEGV, si_code=SI_KERNEL, si_addr=NULL} ---
+++ killed by SIGSEGV (core dumped) +++
Possible Solution
Steps to Reproduce (for bugs)
Sorry for report without data, just want to get some help on parsing segfault
Context
Your Environment
- Version used:
- Environment name and version (e.g. Chrome 39, node.js 5.4): electron 8,
- Operating System and version (desktop or mobile): desktop Ubuntu 20.04
- Link to your project:
The same issue in Electron 10, it works fine with electron 7.x and node 10.19.0. I encountered the issue after upgrading an electron project from v7 to v10.1.5. I use CMakeJS to build iohook from source, the compilation works and the resulting native module is built, but loading it keeps crashing electron.
Edit: I think it's related to https://github.com/wilix-team/iohook/issues/241
Closing as resolved.
@ash0x0 not sure why you closed this - it's still an issue for me. Even on latest build for mac I get SIGSEGV
@abacaj I thought it would've been fixed since then. Reopening. EDIT: Can you tell me your environment and versions?
Have tried custom build on both mac air M1:
System Version: macOS 11.3.1 (20E241)
And my older mac x64:
System Version: macOS 10.15.6 (19G73)
Also tried the release builds from version 0.9.1 of iohook and 0.9.0. Error is same on both macs: SIGSEGV.
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000020
Exception Note: EXC_CORPSE_NOTIFY
Electron 12.0.5 Node 14.9.0
I don't initialize iohook, I just require('iohook') and the error appears once you close electron window.
I can't reproduce this yet so I just need more info. You say it appears after you close the electron window, I'm assuming it's still docked at that point? Do you get the error when launched from terminal or what is it exactly? Is this production or development? If production, what are you using to build and what's the build configuration exactly (sandboxed? notarized? etc.) If this is happening in development, are you using iohook in renderer or main? If renderer, what are the window configuration options? If you can provide a repo or full example of your exact usage it would really really help. I'm working on an error reporting sandbox template but for now you can use the electron example.
Let me try and get a simple demo with electron up, will post a link.
We ended up with removing iohook at all from our desktop app, luckily we were able to measure activity level with electron built in idle API,
We ended up with removing iohook at all from our desktop app, luckily we were able to measure activity level with electron built in idle API,
For future reference, are you referring to powerMonitor or something different?
We ended up with removing iohook at all from our desktop app, luckily we were able to measure activity level with electron built in idle API,
For future reference, are you referring to powerMonitor or something different?
Exactly
powerMonitor.getSystemIdleState(idleThreshold)
Hi @ash0x0 please see: https://github.com/abacaj/iohook-sample made a short video here: https://streamable.com/pf9wat
I cloned iohook repo and used a local build (check package.json, I'm currently on my M1 mac).
- run yarn install
- run yarn start
- close window (red icon on mac)
- see SIGSEGV
- inspect start.js, it only calls
require('iohook')
The reason I couldn't replicate this is because I've been using iohook in renderer. I can replicate with your example now.
There are so many issues on all platforms in main process that it's probably worth avoiding using it in main for now.
The workaround to get you working is to use iohook in renderer and make sure to set both nodeIntegration:true and contextIsolation: false. I recommend you do this for now because this seems to be an issue in libuiohook (seems like a memory access bug when unloading) that's avoided when running in renderer.
Fix for this will come right after I fix build and install (which is up next on the agenda), that's when I'll get to all the libuiohook bugs and start working with upstream.
I get this warning when trying it in renderer:
Electron: Loading non-context-aware native module in renderer: '/Users/antonb/personal/iohook-sample/node_modules/iohook/builds/electron-v87-darwin-arm64/build/Release/iohook.node'. This is deprecated, see https://github.com/electron/electron/issues/18397.
Is this expected?
I get this warning when trying it in renderer:
Electron: Loading non-context-aware native module in renderer: '/Users/antonb/personal/iohook-sample/node_modules/iohook/builds/electron-v87-darwin-arm64/build/Release/iohook.node'. This is deprecated, see https://github.com/electron/electron/issues/18397.Is this expected?
For electron 12 and later this will be the behavior and unfortunately can't be suppressed. This use is already deprecated in electron 14 beta. I would recommend electron 11 if you don't want to see the deprecation warning or live with the deprecation warning in 12 and 13. In 14 the use of this module in renderer process will be disallowed, hopefully I'll manage to fix main process issues and make this NAPI or CA before electron 14 stable release (September).
EDIT: Electron 10 is the one that won't have the warning, 11 has it.
Allowing node integration is not a recommended security practice, neither is disabling context isolation.
https://www.electronjs.org/docs/tutorial/security#2-do-not-enable-nodejs-integration-for-remote-content https://www.electronjs.org/docs/tutorial/security#3-enable-context-isolation-for-remote-content
I understand it's the only way around this issue, but just wanted to point out that the current workaround is not feasible for our use case.
Allowing node integration is not a recommended security practice, neither is disabling context isolation.
https://www.electronjs.org/docs/tutorial/security#2-do-not-enable-nodejs-integration-for-remote-content https://www.electronjs.org/docs/tutorial/security#3-enable-context-isolation-for-remote-content
I understand it's the only way around this issue, but just wanted to point out that the current workaround is not feasible for our use case.
Yes, it's not valid in my use case either due to notarization and passing requirements. It's at the top of my list for mac fixes but it will be some time unfortunately. If you have some time on your hand and can figure it out a PR would be most welcome.
It looks like we can keep those options and run iohook in preload.js exposing it to renderer using context bridge (my app didn't crash when doing this).
The only piece required is:
app.allowRendererProcessReuse = false;
which will be deprecated as you mentioned.
I'm not as proficient in c/c++ so would take me ages to migrate to napi / troubleshoot the bad access error.
@abacaj can you provide an example of how you did it?
Yes I have a working example here: https://github.com/abacaj/iohook-sample
You can see what I changed here: https://github.com/abacaj/iohook-sample/commit/0094c4c3e733337f5733d80f1cb6360b86c2535f
If you yarn install and then yarn start, you should be able to see clicks logged in the console output.
Yes I have a working example here: https://github.com/abacaj/iohook-sample
You can see what I changed here: abacaj/iohook-sample@0094c4c
If you
yarn installand thenyarn start, you should be able to see clicks logged in the console output.
With your permission, I'll update the electron renderer example to use this.
Yes I have a working example here: https://github.com/abacaj/iohook-sample You can see what I changed here: abacaj/iohook-sample@0094c4c If you
yarn installand thenyarn start, you should be able to see clicks logged in the console output.With your permission, I'll update the electron renderer example to use this.
Yea sure sounds good, I think just need to change package.json to not use the local iohook.