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

[WIP][do not merge] Illustrate osx crash #456

Closed

Conversation

gabrielschulhof
Copy link
Contributor

This branch illustrates a crash I've seen on OSX ever since I introduced the suppressDestruct() method for AsyncWorker. To reproduce:

  1. Clone this repo into ${ADDON_API_DIR}
  2. Build Node.js with debug symbols in directory ${NODEDIR}
  3. export npm_config_nodedir=${NODEDIR}
  4. export PATH=${NODEDIR}:${PATH}
  5. alias npm=${NODEDIR}/deps/npm/bin/npm-cli.js
  6. npm run-script pretest
  7. node test/asyncworker-persistent.js

At this point it will segfault. The backtrace is as follows:

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    frame #0: 0x00000001018c7412 node_g`v8_Default_embedded_blob_ + 53010
node_g`v8_Default_embedded_blob_:
->  0x1018c7412 <+53010>: pushq  (%r10)
    0x1018c7415 <+53013>: addq   $0x1, %rcx
    0x1018c7419 <+53017>: cmpq   %rax, %rcx
    0x1018c741c <+53020>: jne    0x1018c740e               ; <+53006>
Target 0: (node_g) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x00000001018c7412 node_g`v8_Default_embedded_blob_ + 53010
    frame #1: 0x000017c475e4a151
    frame #2: 0x00003aa760305f7e
    frame #3: 0x0000000100af4fd5 node_g`v8::internal::(anonymous namespace)::Invoke(v8::internal::Isolate*, bool, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*, v8::internal::Handle<v8::internal::Object>, v8::internal::Execution::MessageHandling, v8::internal::Execution::Target) [inlined] v8::internal::GeneratedCode<v8::internal::Object*, v8::internal::Object*, v8::internal::Object*, v8::internal::Object*, int, v8::internal::Object***>::Call(args=<unavailable>, args=<unavailable>, args=<unavailable>, args=1, args=0x00007ffeefbf5a70) at simulator.h:113 [opt]
    frame #4: 0x0000000100af4fc5 node_g`v8::internal::(anonymous namespace)::Invoke(isolate=0x0000000105000000, is_construct=true, target=<unavailable>, receiver=<unavailable>, argc=1, args=0x00007ffeefbf5a70, new_target=<unavailable>, message_handling=kReport, execution_target=kCallable) at execution.cc:155 [opt]
    frame #5: 0x0000000100af4524 node_g`v8::internal::(anonymous namespace)::CallInternal(isolate=0x0000000105000000, callable=Handle<v8::internal::Object> @ r13, receiver=<unavailable>, argc=32766, argv=0x0000000105000000, message_handling=<unavailable>, target=kCallable) at execution.cc:191 [opt]
    frame #6: 0x0000000100af4327 node_g`v8::internal::Execution::Call(isolate=<unavailable>, callable=<unavailable>, receiver=<unavailable>, argc=<unavailable>, argv=<unavailable>) at execution.cc:202 [opt]
    frame #7: 0x000000010059276a node_g`v8::Function::Call(this=0x000000010586ed30, context=<unavailable>, recv=<unavailable>, argc=<unavailable>, argv=<unavailable>) at api.cc:5019 [opt]
    frame #8: 0x00000001000d2010 node_g`::napi_call_function(env=0x0000000103e1b310, recv=0x000000010586ed20, func=0x000000010586ed30, argc=1, argv=0x00007ffeefbf5a70, result=0x00007ffeefbf5878) at js_native_api_v8.cc:1746
    frame #9: 0x0000000104b055df binding.node`Napi::Function::Call(this=0x00007ffeefbf59a0, recv=0x000000010586ed20, argc=1, args=0x00007ffeefbf5a70) const at napi-inl.h:1704
    frame #10: 0x0000000104b05510 binding.node`Napi::Function::Call(this=0x00007ffeefbf59a0, recv=0x000000010586ed20, args=0x00007ffeefbf5a40) const at napi-inl.h:1695
    frame #11: 0x0000000104b05291 binding.node`Napi::FunctionReference::Call(this=0x0000000104a010e0, recv=0x000000010586ed20, args=0x00007ffeefbf5a40) const at napi-inl.h:2455
    frame #12: 0x0000000104b1fec6 binding_noexcept.node`Napi::AsyncWorker::OnError(this=0x0000000104a010b0, e=0x00007ffeefbf5ae0) at napi-inl.h:3604
    frame #13: 0x0000000104b04a53 binding.node`Napi::AsyncWorker::OnWorkComplete(this=0x00007ffeefbf5bb0)::'lambda'()::operator()() const at napi-inl.h:3634
    frame #14: 0x0000000104b04795 binding.node`napi_value__* Napi::details::WrapCallback<Napi::AsyncWorker::OnWorkComplete(napi_env__*, napi_status, void*)::'lambda'()>(callback=(anonymous class) @ 0x00007ffeefbf5bb0)::'lambda'()) at napi-inl.h:104
    frame #15: 0x0000000104b041c4 binding.node`Napi::AsyncWorker::OnWorkComplete((null)=0x0000000103e1b310, status=napi_ok, this_pointer=0x0000000104a010b0) at napi-inl.h:3629
    frame #16: 0x0000000100116e50 node_g`(anonymous namespace)::uvimpl::Work::AfterThreadPoolWork(this=0x00007ffeefbf5cd8)::'lambda'()::operator()() const at node_api.cc:880
    frame #17: 0x0000000100116c5d node_g`void NapiCallIntoModule<(anonymous namespace)::uvimpl::Work::AfterThreadPoolWork(int)::'lambda'(), (anonymous namespace)::uvimpl::Work::AfterThreadPoolWork(int)::'lambda'(v8::Local<v8::Value>)>(env=0x0000000103e1b310, call=0x00007ffeefbf5cd8, handle_exception=0x00007ffeefbf5cd0)::uvimpl::Work::AfterThreadPoolWork(int)::'lambda'()&&, (anonymous namespace)::uvimpl::Work::AfterThreadPoolWork(int)::'lambda'(v8::Local<v8::Value>)&&) at js_native_api_v8.h:121
    frame #18: 0x0000000100116955 node_g`(anonymous namespace)::uvimpl::Work::AfterThreadPoolWork(this=0x0000000104a01280, status=0) at node_api.cc:879
    frame #19: 0x00000001001170d7 node_g`node::ThreadPoolWork::ScheduleWork(this=0x0000000100117050, req=0x0000000104a012b8, status=0)::'lambda'(uv_work_s*, int)::operator()(uv_work_s*, int) const at node_internals.h:250
    frame #20: 0x000000010011706e node_g`node::ThreadPoolWork::ScheduleWork(req=0x0000000104a012b8, status=0)::'lambda'(uv_work_s*, int)::__invoke(uv_work_s*, int) at node_internals.h:247
    frame #21: 0x0000000101224ada node_g`uv__queue_done(w=0x0000000104a01310, err=0) at threadpool.c:334
    frame #22: 0x00000001012248f5 node_g`uv__work_done(handle=0x00000001028e0808) at threadpool.c:313
    frame #23: 0x000000010122c862 node_g`uv__async_io(loop=0x00000001028e0740, w=0x00000001028e09b0, events=1) at async.c:118
    frame #24: 0x000000010124a7bc node_g`uv__io_poll(loop=0x00000001028e0740, timeout=-1) at kqueue.c:343
    frame #25: 0x000000010122cf0f node_g`uv_run(loop=0x00000001028e0740, mode=UV_RUN_DEFAULT) at core.c:361
    frame #26: 0x000000010011009d node_g`node::Start(isolate=0x0000000105000000, isolate_data=0x0000000105870600, args=size=2, exec_args=size=0) at node.cc:804
    frame #27: 0x000000010010f1d1 node_g`node::Start(event_loop=0x00000001028e0740, args=size=2, exec_args=size=0) at node.cc:879
    frame #28: 0x000000010010e8f8 node_g`node::Start(argc=2, argv=0x0000000103e14b10) at node.cc:938
    frame #29: 0x000000010150215e node_g`main(argc=2, argv=0x00007ffeefbff9e8) at node_main.cc:126
    frame #30: 0x0000000100001034 node_g`start + 52

Note how frame #12 is in a different native addon than the rest of the frames. This is strange. Different instances of native addons should not be able to unintentionally reach each other's functions.

So, assuming that there's something fishy about the way OSX loads two different addons which contain identical symbols, but where one is compiled with C++ exceptions and the other is not, we can add -fvisibility=hidden to the build flags in test/binding.gyp:

diff --git a/test/binding.gyp b/test/binding.gyp
index 77c3880..0e2b7d0 100644
@@ -43,6 +44,12 @@
           'defines': ['NODE_ADDON_API_DISABLE_DEPRECATED']
         }, {
           'sources': ['object/object_deprecated.cc']
+        }],
+        ['OS=="mac"', {
+          'cflags+': ['-fvisibility=hidden'],
+          'xcode_settings': {
+            'OTHER_CFLAGS': ['-fvisibility=hidden']
+          }
         }]
       ],
       'include_dirs': ["<!@(node -p \"require('../').include\")"],

This does indeed prevent the segfault from occurring. It also prevents execution from jumping across native addon boundaries:

* thread #1, queue = 'com.apple.main-thread', stop reason = step in
  * frame #0: 0x00000001000d1dc3 node_g`::napi_call_function(env=0x00000001049005f0, recv=0x0000000104071520, func=0x0000000104071538, argc=1, argv=0x00007ffeefbf5ac0, result=0x00007ffeefbf58c8) at js_native_api_v8.cc:1733
    frame #1: 0x0000000104a057cf binding.node`Napi::Function::Call(this=0x00007ffeefbf59f0, recv=0x0000000104071520, argc=1, args=0x00007ffeefbf5ac0) const at napi-inl.h:1704
    frame #2: 0x0000000104a05700 binding.node`Napi::Function::Call(this=0x00007ffeefbf59f0, recv=0x0000000104071520, args=0x00007ffeefbf5a90) const at napi-inl.h:1695
    frame #3: 0x0000000104a05481 binding.node`Napi::FunctionReference::Call(this=0x00000001049007c0, recv=0x0000000104071520, args=0x00007ffeefbf5a90) const at napi-inl.h:2455
    frame #4: 0x0000000104a022ba binding.node`Napi::AsyncWorker::OnError(this=0x0000000104900790, e=0x00007ffeefbf5b30) at napi-inl.h:3604
    frame #5: 0x0000000104a04c43 binding.node`Napi::AsyncWorker::OnWorkComplete(this=0x00007ffeefbf5c00)::'lambda'()::operator()() const at napi-inl.h:3634
    frame #6: 0x0000000104a04985 binding.node`napi_value__* Napi::details::WrapCallback<Napi::AsyncWorker::OnWorkComplete(napi_env__*, napi_status, void*)::'lambda'()>(callback=(anonymous class) @ 0x00007ffeefbf5c00)::'lambda'()) at napi-inl.h:104
    frame #7: 0x0000000104a043b4 binding.node`Napi::AsyncWorker::OnWorkComplete((null)=0x00000001049005f0, status=napi_ok, this_pointer=0x0000000104900790) at napi-inl.h:3629
    frame #8: 0x0000000100116e50 node_g`(anonymous namespace)::uvimpl::Work::AfterThreadPoolWork(this=0x00007ffeefbf5d28)::'lambda'()::operator()() const at node_api.cc:880

Another experimental change we can make is to compile bindings.node and bindings_noexcept.node identically, without C++ exceptions. That will also result in a successful run.

Another possibility, that of adding __attribute__((visibility("hidden"))) to individual functions, especially OnWorkComplete() and OnExecute() results in a successful run on Node.js 10.15.0, but not on the latest master.

Yet another experimental change also fixes the segfault. We can disambiguate the class names at the top of napi.h:

#ifdef NAPI_CPP_EXCEPTIONS
#define AsyncWorker AsyncWorker_Except
#define FunctionReference FunctionReference_Except
#define Function Function_Except
#define Error Error_Except
#else
#define AsyncWorker AsyncWorker_No_Except
#define FunctionReference FunctionReference_No_Except
#define Function Function_No_Except
#define Error Error_No_Except
#endif

As an additional step we can identify which functions end up affected by the above preprocessor directives by running nm -Ca test/build/Debug/binding_noexcept.node | grep No_Except | grep ' T ' on the resulting native addon, and mark them as hidden using __attribute__((visibility("hidden"))). After that, we can remove the above preprocessor definitions. And, indeed, with the used symbols now hidden, there is no more segfault:

diff --git a/napi-inl.h b/napi-inl.h
index 35155bd..b4a20e4 100644
--- a/napi-inl.h
+++ b/napi-inl.h
@@ -98,6 +98,7 @@ static inline napi_status AttachData(napi_env env,
 // For use in JS to C++ callback wrappers to catch any Napi::Error exceptions
 // and rethrow them as JavaScript exceptions before returning from the callback.
 template <typename Callable>
+__attribute__((visibility("hidden")))
 inline napi_value WrapCallback(Callable callback) {
 #ifdef NAPI_CPP_EXCEPTIONS
   try {
@@ -797,6 +798,7 @@ struct vf_utf16_string {
 
 template <typename T>
 struct vf_fallback {
+  __attribute__((visibility("hidden")))
   static Value From(napi_env env, const T& value) {
     return Value(env, value);
   }
diff --git a/napi.h b/napi.h
index 2262cf7..1cc1058 100644
--- a/napi.h
+++ b/napi.h
@@ -146,6 +146,7 @@ namespace Napi {
     /// - napi::Value
     /// - napi_value
     template <typename T>
+    __attribute__((visibility("hidden")))
     static Value From(napi_env env, const T& value);
 
     /// Converts to a N-API value primitive.
@@ -203,7 +204,9 @@ namespace Napi {
     ///
     /// This conversion does NOT coerce the type. Calling any methods inappropriate for the actual
     /// value type will throw `Napi::Error`.
-    template <typename T> T As() const;
+    template <typename T>
+    __attribute__((visibility("hidden")))
+    T As() const;
 
     Boolean ToBoolean() const; ///< Coerces a value to a JavaScript boolean.
     Number ToNumber() const;   ///< Coerces a value to a JavaScript number.
@@ -421,6 +424,7 @@ namespace Napi {
       /// Assigns a value to the property. The type of value can be
       /// anything supported by `Object::Set`.
       template <typename ValueType>
+      __attribute__((visibility("hidden")))
       PropertyLValue& operator =(ValueType value);
 
     private:
@@ -533,6 +537,7 @@ namespace Napi {
 
     /// Sets a property.
     template <typename ValueType>
+    __attribute__((visibility("hidden")))
     void Set(
       napi_value key,  ///< Property key primitive
       const ValueType& value ///< Property value primitive
@@ -540,6 +545,7 @@ namespace Napi {
 
     /// Sets a property.
     template <typename ValueType>
+    __attribute__((visibility("hidden")))
     void Set(
       Value key,  ///< Property key
       const ValueType& value ///< Property value
@@ -547,6 +553,7 @@ namespace Napi {
 
     /// Sets a named property.
     template <typename ValueType>
+    __attribute__((visibility("hidden")))
     void Set(
       const char* utf8name, ///< UTF-8 encoded null-terminated property name
       const ValueType& value
@@ -554,6 +561,7 @@ namespace Napi {
 
     /// Sets a named property.
     template <typename ValueType>
+    __attribute__((visibility("hidden")))
     void Set(
       const std::string& utf8name, ///< UTF-8 encoded property name
       const ValueType& value             ///< Property value primitive
@@ -901,6 +909,7 @@ namespace Napi {
     /// Callable must implement operator() accepting a const CallbackInfo&
     /// and return either void or Value.
     template <typename Callable>
+    __attribute__((visibility("hidden")))
     static Function New(napi_env env,
                         Callable cb,
                         const char* utf8name = nullptr,
@@ -908,6 +917,7 @@ namespace Napi {
     /// Callable must implement operator() accepting a const CallbackInfo&
     /// and return either void or Value.
     template <typename Callable>
+    __attribute__((visibility("hidden")))
     static Function New(napi_env env,
                         Callable cb,
                         const std::string& utf8name,
@@ -918,11 +928,17 @@ namespace Napi {
 
     Value operator ()(const std::initializer_list<napi_value>& args) const;
 
+    __attribute__((visibility("hidden")))
     Value Call(const std::initializer_list<napi_value>& args) const;
+    __attribute__((visibility("hidden")))
     Value Call(const std::vector<napi_value>& args) const;
+    __attribute__((visibility("hidden")))
     Value Call(size_t argc, const napi_value* args) const;
+    __attribute__((visibility("hidden")))
     Value Call(napi_value recv, const std::initializer_list<napi_value>& args) const;
+    __attribute__((visibility("hidden")))
     Value Call(napi_value recv, const std::vector<napi_value>& args) const;
+    __attribute__((visibility("hidden")))
     Value Call(napi_value recv, size_t argc, const napi_value* args) const;
 
     Value MakeCallback(napi_value recv,
@@ -1004,6 +1020,7 @@ namespace Napi {
   template <typename T>
   class Reference {
   public:
+    __attribute__((visibility("hidden")))
     static Reference<T> New(const T& value, uint32_t initialRefcount = 0);
 
     Reference();
@@ -1024,6 +1041,7 @@ namespace Napi {
 
     // Note when getting the value of a Reference it is usually correct to do so
     // within a HandleScope so that the value handle gets cleaned up efficiently.
+    __attribute__((visibility("hidden")))
     T Value() const;
 
     uint32_t Ref();
@@ -1100,10 +1118,15 @@ namespace Napi {
 
     Napi::Value operator ()(const std::initializer_list<napi_value>& args) const;
 
+    __attribute__((visibility("hidden")))
     Napi::Value Call(const std::initializer_list<napi_value>& args) const;
+    __attribute__((visibility("hidden")))
     Napi::Value Call(const std::vector<napi_value>& args) const;
+    __attribute__((visibility("hidden")))
     Napi::Value Call(napi_value recv, const std::initializer_list<napi_value>& args) const;
+    __attribute__((visibility("hidden")))
     Napi::Value Call(napi_value recv, const std::vector<napi_value>& args) const;
+    __attribute__((visibility("hidden")))
     Napi::Value Call(napi_value recv, size_t argc, const napi_value* args) const;
 
     Napi::Value MakeCallback(napi_value recv,
@@ -1129,6 +1152,7 @@ namespace Napi {
   // Shortcuts to creating a new reference with inferred type and refcount = 1.
   template <typename T> Reference<T> Persistent(T value);
   ObjectReference Persistent(Object value);
+  __attribute__((visibility("hidden")))
   FunctionReference Persistent(Function value);
 
   /// A persistent reference to a JavaScript error object. Use of this class depends somewhat
@@ -1225,10 +1249,14 @@ namespace Napi {
 #endif // NAPI_CPP_EXCEPTIONS
     {
   public:
+    __attribute__((visibility("hidden")))
     static Error New(napi_env env);
+    __attribute__((visibility("hidden")))
     static Error New(napi_env env, const char* message);
+    __attribute__((visibility("hidden")))
     static Error New(napi_env env, const std::string& message);
 
+    __attribute__((visibility("hidden")))
     static NAPI_NO_RETURN void Fatal(const char* location, const char* message);
 
     Error();
@@ -1241,6 +1269,7 @@ namespace Napi {
     Error& operator =(Error&);
 
     const std::string& Message() const NAPI_NOEXCEPT;
+    __attribute__((visibility("hidden")))
     void ThrowAsJavaScriptException() const;
 
 #ifdef NAPI_CPP_EXCEPTIONS
@@ -1252,6 +1281,7 @@ namespace Napi {
     typedef napi_status (*create_error_fn)(napi_env envb, napi_value code, napi_value msg, napi_value* result);
 
     template <typename TError>
+    __attribute__((visibility("hidden")))
     static TError New(napi_env env,
                       const char* message,
                       size_t length,
@@ -1358,21 +1388,25 @@ namespace Napi {
                                        napi_property_attributes attributes = napi_default,
                                        void* data = nullptr);
     template <typename Callable>
+    __attribute__((visibility("hidden")))
     static PropertyDescriptor Function(const char* utf8name,
                                        Callable cb,
                                        napi_property_attributes attributes = napi_default,
                                        void* data = nullptr);
     template <typename Callable>
+    __attribute__((visibility("hidden")))
     static PropertyDescriptor Function(const std::string& utf8name,
                                        Callable cb,
                                        napi_property_attributes attributes = napi_default,
                                        void* data = nullptr);
     template <typename Callable>
+    __attribute__((visibility("hidden")))
     static PropertyDescriptor Function(napi_value name,
                                        Callable cb,
                                        napi_property_attributes attributes = napi_default,
                                        void* data = nullptr);
     template <typename Callable>
+    __attribute__((visibility("hidden")))
     static PropertyDescriptor Function(Name name,
                                        Callable cb,
                                        napi_property_attributes attributes = napi_default,
@@ -1720,8 +1754,10 @@ namespace Napi {
 
     Napi::Env Env() const;
 
+    __attribute__((visibility("hidden")))
     void Queue();
     void Cancel();
+    __attribute__((visibility("hidden")))
     void SuppressDestruct();
 
     ObjectReference& Receiver();
@@ -1748,10 +1784,13 @@ namespace Napi {
     virtual void OnOK();
     virtual void OnError(const Error& e);
 
+    __attribute__((visibility("hidden")))
     void SetError(const std::string& error);
 
   private:
+    __attribute__((visibility("hidden")))
     static void OnExecute(napi_env env, void* this_pointer);
+    __attribute__((visibility("hidden")))
     static void OnWorkComplete(napi_env env,
                                napi_status status,
                                void* this_pointer);

This obviously addresses the use case of running the test, however, in general, we should mark all symbols as hidden.

Gabriel Schulhof added 4 commits February 13, 2019 15:59
Add method `SuppressDestruct()` to `AsyncWorker`, which will cause an
instance of the class to remain allocated even after the `OnOK`
callback fires. Such an instance must be explicitly `delete`-ed from
user code.

Re: nodejs#231
Re: nodejs/abi-stable-node#353
gabrielschulhof pushed a commit to gabrielschulhof/node-gyp that referenced this pull request Mar 11, 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
gabrielschulhof pushed a commit to gabrielschulhof/node-gyp that referenced this pull request Mar 11, 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
gabrielschulhof pushed a commit to gabrielschulhof/node-gyp that referenced this pull request Mar 12, 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
gabrielschulhof pushed a commit to gabrielschulhof/node-gyp that referenced this pull request Mar 19, 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
@mhdawson
Copy link
Member

I think this can be closed now, as a PR went in to address the issue.

@gabrielschulhof
Copy link
Contributor Author

I think we've established the issue with OSX and arrived at a solution.

gabrielschulhof pushed a commit to gabrielschulhof/node-gyp that referenced this pull request Jun 4, 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
rvagg pushed a commit to nodejs/node-gyp 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 to nodejs/node-gyp 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 to nodejs/node-gyp 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 pushed a commit to nodejs/node-gyp 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 to nodejs/node-gyp 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 pushed a commit to nodejs/node-gyp 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 to nodejs/node-gyp 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 to nodejs/node-gyp 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 to nodejs/node-gyp 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>
@gabrielschulhof gabrielschulhof deleted the illustrate-osx-crash branch December 17, 2019 01:36
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

Successfully merging this pull request may close these issues.

None yet

2 participants