iohook icon indicating copy to clipboard operation
iohook copied to clipboard

Built electron binary crashes with segfault

Open ivictbor opened this issue 5 years ago • 21 comments

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:

ivictbor avatar Sep 15 '20 18:09 ivictbor

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

ahkohd avatar Nov 15 '20 07:11 ahkohd

Closing as resolved.

ash0x0 avatar Jun 11 '21 18:06 ash0x0

@ash0x0 not sure why you closed this - it's still an issue for me. Even on latest build for mac I get SIGSEGV

abacaj avatar Jun 12 '21 19:06 abacaj

@abacaj I thought it would've been fixed since then. Reopening. EDIT: Can you tell me your environment and versions?

ash0x0 avatar Jun 13 '21 03:06 ash0x0

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.

abacaj avatar Jun 13 '21 18:06 abacaj

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.

ash0x0 avatar Jun 13 '21 18:06 ash0x0

Let me try and get a simple demo with electron up, will post a link.

abacaj avatar Jun 13 '21 19:06 abacaj

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,

ivictbor avatar Jun 13 '21 19:06 ivictbor

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?

ash0x0 avatar Jun 13 '21 19:06 ash0x0

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)

ivictbor avatar Jun 13 '21 19:06 ivictbor

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).

  1. run yarn install
  2. run yarn start
  3. close window (red icon on mac)
  4. see SIGSEGV
  5. inspect start.js, it only calls require('iohook')

abacaj avatar Jun 13 '21 21:06 abacaj

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.

ash0x0 avatar Jun 13 '21 22:06 ash0x0

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?

abacaj avatar Jun 13 '21 23:06 abacaj

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.

ash0x0 avatar Jun 13 '21 23:06 ash0x0

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.

abacaj avatar Jun 14 '21 14:06 abacaj

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.

ash0x0 avatar Jun 14 '21 14:06 ash0x0

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 avatar Jun 14 '21 18:06 abacaj

@abacaj can you provide an example of how you did it?

ash0x0 avatar Jun 15 '21 01:06 ash0x0

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.

abacaj avatar Jun 15 '21 14:06 abacaj

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 install and then yarn 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.

ash0x0 avatar Jun 16 '21 00:06 ash0x0

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 install and then yarn 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.

abacaj avatar Jun 16 '21 02:06 abacaj