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

test: add duplicate symbol test #1689

Conversation

gabrielschulhof
Copy link

On OSX symbols are exported by default, and they overlap if two
different copies of the same symbol appear in a process. This change
ensures that, on OSX, symbols are hidden by default.

Re: nodejs/node-addon-api#456

Checklist
  • npm install && npm test passes
  • tests are included
  • commit message follows commit guidelines
Description of change

Copy link
Member

@richardlau richardlau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if setting this by default could be breaking for any existing addons?

addon.gypi Outdated Show resolved Hide resolved
@gabrielschulhof
Copy link
Author

@richardlau addons are not built with -fvisibility=hidden because originally it was impossible to do so, because that would also hide the node::nm_module data symbol that early versions of Node.js were searching for when loading addons. However, it has been possible to load native modules via DSO constructors since 76b9846 (released in v0.11.11), meaning that it would have been possible to introduce -fvisibility=hidden all this time. In fact, in bd8a575 (released in v0.11.12) @bnoordhuis presciently defined NODE_MODULE_EXPORT as __attribute__((visibility("default"))) instead of the empty value it had had up to that point in anticipation of the ability to actually make use of it. Native addons explicitly wishing to expose symbols should prefix them with NODE_MODULE_EXPORT.

It seems that the involuntary exposure of all the symbols has so far caused few problems. Nevertheless, the test in this PR and the issue this PR references indicate that there are problems with unwittingly exposing symbols on OSX.

The problem in the wild can arise from having a large application that has two dependencies, each of which depends on (perhaps a different version of) a native addon. When this addon is loaded from two different places in the dependency tree into the same process, and if this addon exposes symbols using this static inline storage class, then the two different symbols will not be distinguishable on OSX. I have at least one case where that causes a segfault.

I guess the point of discussion should be whether we should takes this opportunity to start building addons with -fvisibility=hidden, at least on OSX, or whether we should take the advocacy approach and evangelize the addition of this flag to each addon's binding.gyp.

Can we test this change with CITGM?

@gabrielschulhof
Copy link
Author

@mcollina @kkoopa @addaleax do you think it would be feasible to add -fvisibility=hidden to addon build flags on OSX given the error I found because the flag is absent?

Copy link
Member

@bnoordhuis bnoordhuis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Gabriel, LGTM % nits.

test/node_modules/duplicate_symbols/common.h Outdated Show resolved Hide resolved
"target_defaults": {
"include_dirs": [
"<!(node -e \"require('nan')\")"
],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can go? The add-on doesn't use nan (doesn't even depend on it in package.json.)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it does use nan. I added the dependency to package.json.

test/test-addon.js Outdated Show resolved Hide resolved
test/test-addon.js Outdated Show resolved Hide resolved
test/test-addon.js Outdated Show resolved Hide resolved
test/node_modules/duplicate_symbols/package.json Outdated Show resolved Hide resolved
@gabrielschulhof
Copy link
Author

@bnoordhuis thanks for the review! I have addressed the nits.

@gabrielschulhof
Copy link
Author

Rebased to fix conflicts.

@refack
Copy link
Contributor

refack commented Jun 4, 2019

I'm wondering if setting this by default could be breaking for any existing addons?

Can we test this change with CITGM?

I think we'll need to tweak the CITGM CI script, but @gabrielschulhof you can run CITGM locally on mac. It's as simple as:

npm i -g citgm
citgm-all

But you'll need to transplant a fixed version of node-gyp into npm's node_modules...

@refack refack added the macOS label Jun 4, 2019
@gabrielschulhof
Copy link
Author

@refack the Mac machine I have access to is behind a proxy server, so I'm seeing some failures that might be related to that. I'll request access to a CI mac. Let's see if I can run the citgm there.

@gabrielschulhof
Copy link
Author

@refack I tried running citgm-all on the Mac to which I received access, but, unfortunately, it fails in lots of places even without replacing node-gyp. Thus, I have no firm basis against which to perform such a test.

@rvagg
Copy link
Member

rvagg commented Jun 20, 2019

Thus, I have no firm basis against which to perform such a test.
this is the citgm problem, there's no concrete baseline except in the heads of people that use it regularly.

I'm fine with getting this merged but could someone come up with a semver-* label for it? I don't really know. Seems potentially semer-major to me, but maybe not?

@gabrielschulhof
Copy link
Author

@rvagg for this to be semver-major there would have to be addons which, upon loading, assume the existence of symbols provided by other addons, symbols which are not explicitly marked NODE_MODULE_EXPORT.

rvagg pushed a commit that referenced this pull request Jun 20, 2019
On OSX symbols are exported by default, and they overlap if two
different copies of the same symbol appear in a process. This change
ensures that, on OSX, symbols are hidden by default.

Re: nodejs/node-addon-api#456
Fixes: nodejs/node#26765
PR-URL: #1689
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Refael Ackermann <refack@gmail.com>
rvagg pushed a commit that referenced this pull request Jun 20, 2019
On OSX symbols are exported by default, and they overlap if two
different copies of the same symbol appear in a process. This change
ensures that, on OSX, symbols are hidden by default.

Re: nodejs/node-addon-api#456
Fixes: nodejs/node#26765
PR-URL: #1689
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Refael Ackermann <refack@gmail.com>
@rvagg
Copy link
Member

rvagg commented Jun 20, 2019

I changed the commit msg to have a "build,test" prefix and landed in 8b7fdd1. I'm still having trouble with the semveriness of this. semver-minor at least? I don't think I'll include this in 5.0.1 but maybe it should be in a 5.1.0?

@rvagg rvagg closed this Jun 20, 2019
@rvagg
Copy link
Member

rvagg commented Jun 20, 2019

@gabrielschulhof would you mind revisiting this please? I've just noticed the tests fail with Node 12 on macOS, the addon is using a bare GetFunction().

@rvagg rvagg reopened this Jun 20, 2019
@rvagg
Copy link
Member

rvagg commented Jun 20, 2019

This works:

diff --git a/test/node_modules/duplicate_symbols/binding.cc b/test/node_modules/duplicate_symbols/binding.cc
index bc5f6f5..a0999b7 100644
--- a/test/node_modules/duplicate_symbols/binding.cc
+++ b/test/node_modules/duplicate_symbols/binding.cc
@@ -2,9 +2,9 @@
 #include "common.h"

 void Init(v8::Local<v8::Object> exports) {
-  exports->Set(Nan::New("pointerCheck").ToLocalChecked(),
-               Nan::New<v8::FunctionTemplate>(Something::PointerCheck)
-      ->GetFunction());
+  Nan::Set(exports, Nan::New("pointerCheck").ToLocalChecked(),
+    Nan::GetFunction(
+      Nan::New<v8::FunctionTemplate>(Something::PointerCheck)).ToLocalChecked());
 }

 NODE_MODULE(NODE_GYP_MODULE_NAME, Init)

since this is already merged, maybe push a new commit here and I'll merge that on top of master.

@rvagg
Copy link
Member

rvagg commented Jun 20, 2019

oh, and update the "nan" version in package.json when you're in there too I think.

Use `Nan::Set()` and `Nan::GetFunction()` instead of their V8
equivalents to avoid OSX test failures with Node.js v12.x.

Thanks @rvagg!
@gabrielschulhof
Copy link
Author

@rvagg I made the changes you asked for. I'm not sure if the change I made to the version of nan requested in the test's package.json is the one you had in mind. After all, the existing ^2.0.0 should result in the latest version of nan getting pulled, right?

rvagg pushed a commit that referenced this pull request Jun 21, 2019
Use `Nan::Set()` and `Nan::GetFunction()` instead of their V8
equivalents to avoid OSX test failures with Node.js v12.x.

Thanks @rvagg!

Re: nodejs/node-addon-api#456
Fixes: nodejs/node#26765
PR-URL: #1689
Reviewed-By: Rod Vagg <rod@vagg.org>
@rvagg
Copy link
Member

rvagg commented Jun 21, 2019

great, thanks. and yes you're right about the ^2, my local version was old. landed in af0d7b8

@rvagg rvagg closed this Jun 21, 2019
rvagg pushed a commit that referenced this pull request Jun 21, 2019
On OSX symbols are exported by default, and they overlap if two
different copies of the same symbol appear in a process. This change
ensures that, on OSX, symbols are hidden by default.

Re: nodejs/node-addon-api#456
Fixes: nodejs/node#26765
PR-URL: #1689
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Refael Ackermann <refack@gmail.com>
rvagg pushed a commit that referenced this pull request Jun 21, 2019
Use `Nan::Set()` and `Nan::GetFunction()` instead of their V8
equivalents to avoid OSX test failures with Node.js v12.x.

Thanks @rvagg!

Re: nodejs/node-addon-api#456
Fixes: nodejs/node#26765
PR-URL: #1689
Reviewed-By: Rod Vagg <rod@vagg.org>
@gabrielschulhof gabrielschulhof deleted the visibility-hidden-on-osx branch June 21, 2019 03:05
@rvagg rvagg mentioned this pull request Jun 21, 2019
rvagg pushed a commit that referenced this pull request Sep 26, 2019
On OSX symbols are exported by default, and they overlap if two
different copies of the same symbol appear in a process. This change
ensures that, on OSX, symbols are hidden by default.

Re: nodejs/node-addon-api#456
Fixes: nodejs/node#26765
PR-URL: #1689
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Refael Ackermann <refack@gmail.com>
rvagg pushed a commit that referenced this pull request Sep 26, 2019
Use `Nan::Set()` and `Nan::GetFunction()` instead of their V8
equivalents to avoid OSX test failures with Node.js v12.x.

Thanks @rvagg!

Re: nodejs/node-addon-api#456
Fixes: nodejs/node#26765
PR-URL: #1689
Reviewed-By: Rod Vagg <rod@vagg.org>
rvagg pushed a commit that referenced this pull request Oct 3, 2019
On OSX symbols are exported by default, and they overlap if two
different copies of the same symbol appear in a process. This change
ensures that, on OSX, symbols are hidden by default.

Re: nodejs/node-addon-api#456
Fixes: nodejs/node#26765
PR-URL: #1689
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Refael Ackermann <refack@gmail.com>
rvagg pushed a commit that referenced this pull request Oct 3, 2019
Use `Nan::Set()` and `Nan::GetFunction()` instead of their V8
equivalents to avoid OSX test failures with Node.js v12.x.

Thanks @rvagg!

Re: nodejs/node-addon-api#456
Fixes: nodejs/node#26765
PR-URL: #1689
Reviewed-By: Rod Vagg <rod@vagg.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants