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

Reliably create a core dump in 3 lines of code on official node docker images & Alpine VM image #56

Open
ggryschuk opened this issue Mar 22, 2021 · 7 comments

Comments

@ggryschuk
Copy link

Hi. I wanted to first thank the team developing ref (and ffi), these packages have been very helpful to me. With that said I seem to have found a bug that can reliably create a core dump in 3 lines of code on any official node docker image back to the v12 release and on an alpine VM (Alpine v3.12, running in Oracle VirtualBox). The same problem does not exist running node v14 (14.16.0) on Windows v10 Home. I did the latter test because I wanted to check the OS dependency and had a Windows laptop available.

Long story short the 3 lines of code are:

const ref = require('ref-napi');
let ds = Buffer.alloc(4)
console.log(ds);

As noted I've been able to reliably reproduce the core dump using official node:alpine docker images node:14-alpine down to node:12-alpine). The same code replaced with 'ref' instead of 'ref-napi' on node:10-alpine does not core dump. The issue here at least for me is that this seems to be a symptom of something larger as these were just the 3 lines of code I produced to do a test after first running in to a Seg fault with trying to emit an event message where a ref'd Buffer is in the message

Just to be clear to reproduce the problem just create a Dockerfile with node:14-alpine & dropping to a command shell. Create a blank directory (test for me), run 'npm init' to create a package.json just accepting all defaults, than install ref-napi ( npm install ref-napi --save), dump the 3 lines of code above in to a 'test.js' & just run 'node test.js'. Commenting out the 'require' line produces expected results on the console (<Buffer 00 00 00 00>).

I also just ran a test replacing 'Buffer.alloc(4) with 'ref.alloc(ref.types.void)' & still got a Seg Fault (my original problem was related to the latter case where I use 'ref.alloc' to allocate a Buffer to create a pointer-to-pointer type to pass to a C function).

For my purposes I can stick with the 'back ported' ffi & ref versions if I want to run on node v12 or it seems I can use node v11 or lower so it's not an immediate issue for me but I'd eventually like to move to N-API for my code & need ref-napi to do that.

Thanks again to those producing this package.

@addaleax
Copy link
Contributor

Hi @ggryschuk! Is there any chance you could generate a stack trace for this with a debugger?

@ggryschuk
Copy link
Author

ggryschuk commented Mar 22, 2021 via email

@ggryschuk
Copy link
Author

Hi. I think I was able to generate the stack trace you are looking for, see attached 'ref-backtrace.txt'.

For reasons I won't go in to here this is from within a docker container generated from the node:14-alpine docker image. I've attached the Dockerfile used to generate the image. I just dumped the 3 lines of code in my original message in to a 'test.js' file. Also I had to run the docker image as root to generate the core file (the Dockerfile installs gdb & musl-dbg as well as ref-napi globally).

While you probably know how to do this, to be complete this is what I did to generate the core file from the Dockerfile & test.js.

  1. Create a new directory, 'test'.
  2. Dump the Dockerfile in it removing the '.txt' extension I had to use to upload it here.
  3. Create a subdirectory of that called 'bin', stick the 3 lines of code in a file named 'test.js' in this directory.
  4. run 'docker build --tag test .',
  5. From within the 'test' directory, run 'docker run -u root -it -v $(pwd)/bin:/home/appuser/bin:rw --name test test:latest
  6. From within the shell. Just do 'cd bin', 'node test.js'...you should receive a segfault with a core dump
  7. add 'sudo' appropriately to the docker commands if like me you run docker requiring root privileges.

While the Dockerfile I attached installs ref-napi in the global library I did that to simplify things here. The stack trace was generated by a project (package.json created with npm init, npm install ref-napi --save) I created within the running container.

ref_backtrace.txt

Dockerfile.txt

BTW, if uploading files like this is 'bad etiquette' just let me know & I'll paste in the stack trace in a new message if you like.

Take care.

Take care.

@ggryschuk
Copy link
Author

Hi. I just ran a few more tests. I can reproduce the problem back to ref-napi@1.5.2 (I didn't try every release but spot checked 3.0.0 & 2.1.2 as well as 1.5.2). It works as expected for v1.4.3 & below (output is <Buffer@0x55e73c00ff40 00 00 00 00>)

@addaleax
Copy link
Contributor

@ggryschuk Thanks for the reproduction info!

There’s something weird going on here on a system/shared library linker level. The call to snprintf() here is failing, because __snprintf_chk (the actual function call that the compiler emits) does not appear to be loaded as symbol from a dynamic library.

I’m not familiar enough with alpine/musl to know why this is happening, but I can tell you that one way to solve this is to not use prebuilt binaries (by using apk add g++ make and running npm install with the --build-from-source flag). That also matches the version numbers you mentioned – 1.5.2 was the first one to have prebuilt binaries available.

In theory, there should be a way for ref-napi to provide prebuilt binaries for musl out of the box as well, but that would require a CI host that provides an environment like that, so it’s not something I can see myself picking up anytime soon.

@ggryschuk
Copy link
Author

Thanks for the input. This is 1 (though very important) part of a larger whole. Since the back-ported (or is it 'forward ported'?) version of ref with node-12 is working I'm going to stick with that for now but will give your suggestion on the 'build-from-source' flag a try when I get a chance. I'm not an alpine or musl guru either I just used alpine because I wanted a small linux distribution & of course official node docker builds use it.

Since I'm building my javascript-to-C interface from source within the docker container the appropriate build tools are already available to use for ref-napi so it won't be hard for me to run a quick test. It may be a day or 3 though.

@ggryschuk
Copy link
Author

Hi. Quick update. I was able to multi-task & ran the 'build-from-source' test, it worked!

I'd have to do a larger test on my main application of course but this at least seemed to be related to the problem I was having. Then again it was hard to tell because it Seg Faulted on debug statements too (when trying to output the Buffer of course) which clearly are related to doing a 'console.log'. So can't be sure this will fix my main problem but at least now I'll be able to spit out debug statements at appropriate locations. Though I have high confidence this will actually fix my main issue.

Clearly this isn't a bug to be fixed but I might advise putting a note in the README about this.

thanks again for the quick help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants