Skip to content

Initial support for javascript callbacks for node >= 0.12 running on linux #34

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

Merged
merged 1 commit into from
Jan 29, 2016

Conversation

lavarsicious
Copy link

Inspired by #11 and updated to support newer versions of Node.js as well as proper handling of cross-thread callbacks.

I haven't had the time to look into what it would take to get it fully implemented for Windows, it would need a dependency or alternative for pthreads and a way to get the stack array from StackWalker.

Regardless, it should still build and run the same as always on Windows, just without callback support.

No9 added a commit that referenced this pull request Jan 29, 2016
Initial support for javascript callbacks for node >= 0.12 running on linux
@No9 No9 merged commit ffbc37e into ddopson:master Jan 29, 2016
@papandreou
Copy link

This breaks with node.js 0.10:

$ npm install
npm WARN package.json [email protected] No license field.

> [email protected] install /home/andreas/work/node-segfault-handler
> node-gyp rebuild

make: Entering directory '/home/andreas/work/node-segfault-handler/build'
  CXX(target) Release/obj.target/segfault-handler/src/segfault-handler.o
../src/segfault-handler.cpp:60:30: error: ‘CopyablePersistentTraits’ is not a member of ‘v8’
     v8::Persistent<Function, v8::CopyablePersistentTraits<Function> >* callback;
                              ^
../src/segfault-handler.cpp:60:30: note: suggested alternatives:
In file included from ../node_modules/nan/nan.h:317:0,
                 from ../src/segfault-handler.cpp:2:
../node_modules/nan/nan_persistent_pre_12_inl.h:129:8: note:   ‘Nan::CopyablePersistentTraits’
 struct CopyablePersistentTraits {
        ^
../node_modules/nan/nan_persistent_pre_12_inl.h:129:8: note:   ‘Nan::CopyablePersistentTraits’
../src/segfault-handler.cpp:60:30: error: ‘CopyablePersistentTraits’ is not a member of ‘v8’
     v8::Persistent<Function, v8::CopyablePersistentTraits<Function> >* callback;
                              ^
../src/segfault-handler.cpp:60:30: note: suggested alternatives:
In file included from ../node_modules/nan/nan.h:317:0,
                 from ../src/segfault-handler.cpp:2:
../node_modules/nan/nan_persistent_pre_12_inl.h:129:8: note:   ‘Nan::CopyablePersistentTraits’
 struct CopyablePersistentTraits {
        ^
../node_modules/nan/nan_persistent_pre_12_inl.h:129:8: note:   ‘Nan::CopyablePersistentTraits’
../src/segfault-handler.cpp:60:67: error: wrong number of template arguments (2, should be 1)
     v8::Persistent<Function, v8::CopyablePersistentTraits<Function> >* callback;
                                                                   ^
In file included from /home/andreas/.node-gyp/0.10.40/src/node.h:62:0,
                 from ../node_modules/nan/nan.h:45,
                 from ../src/segfault-handler.cpp:2:
/home/andreas/.node-gyp/0.10.40/deps/v8/include/v8.h:107:26: note: provided for ‘template<class T> class v8::Persistent’
 template <class T> class Persistent;
                          ^
../src/segfault-handler.cpp:60:69: error: expected unqualified-id before ‘>’ token
     v8::Persistent<Function, v8::CopyablePersistentTraits<Function> >* callback;
                                                                     ^
../src/segfault-handler.cpp:68:44: error: ‘CopyablePersistentTraits’ is not a member of ‘v8’
     callback_args(v8::Persistent<Function, v8::CopyablePersistentTraits<Function> >* callback, void * const* stack, size_t stack_size, int signo, 
                                            ^
../src/segfault-handler.cpp:68:44: note: suggested alternatives:
In file included from ../node_modules/nan/nan.h:317:0,
                 from ../src/segfault-handler.cpp:2:
../node_modules/nan/nan_persistent_pre_12_inl.h:129:8: note:   ‘Nan::CopyablePersistentTraits’
 struct CopyablePersistentTraits {
        ^
../node_modules/nan/nan_persistent_pre_12_inl.h:129:8: note:   ‘Nan::CopyablePersistentTraits’
../src/segfault-handler.cpp:68:44: error: ‘CopyablePersistentTraits’ is not a member of ‘v8’
     callback_args(v8::Persistent<Function, v8::CopyablePersistentTraits<Function> >* callback, void * const* stack, size_t stack_size, int signo, 
                                            ^
../src/segfault-handler.cpp:68:44: note: suggested alternatives:
In file included from ../node_modules/nan/nan.h:317:0,
                 from ../src/segfault-handler.cpp:2:
../node_modules/nan/nan_persistent_pre_12_inl.h:129:8: note:   ‘Nan::CopyablePersistentTraits’
 struct CopyablePersistentTraits {
        ^
../node_modules/nan/nan_persistent_pre_12_inl.h:129:8: note:   ‘Nan::CopyablePersistentTraits’
../src/segfault-handler.cpp:68:81: error: wrong number of template arguments (2, should be 1)
     callback_args(v8::Persistent<Function, v8::CopyablePersistentTraits<Function> >* callback, void * const* stack, size_t stack_size, int signo, 
                                                                                 ^
In file included from /home/andreas/.node-gyp/0.10.40/src/node.h:62:0,
                 from ../node_modules/nan/nan.h:45,
                 from ../src/segfault-handler.cpp:2:
/home/andreas/.node-gyp/0.10.40/deps/v8/include/v8.h:107:26: note: provided for ‘template<class T> class v8::Persistent’
 template <class T> class Persistent;
                          ^
../src/segfault-handler.cpp:68:83: error: expected ‘,’ or ‘...’ before ‘>’ token
     callback_args(v8::Persistent<Function, v8::CopyablePersistentTraits<Function> >* callback, void * const* stack, size_t stack_size, int signo, 
                                                                                   ^
../src/segfault-handler.cpp:82:28: error: ‘CopyablePersistentTraits’ is not a member of ‘v8’
   v8::Persistent<Function, v8::CopyablePersistentTraits<Function> > callback;
                            ^
../src/segfault-handler.cpp:82:28: note: suggested alternatives:
In file included from ../node_modules/nan/nan.h:317:0,
                 from ../src/segfault-handler.cpp:2:
../node_modules/nan/nan_persistent_pre_12_inl.h:129:8: note:   ‘Nan::CopyablePersistentTraits’
 struct CopyablePersistentTraits {
        ^
../node_modules/nan/nan_persistent_pre_12_inl.h:129:8: note:   ‘Nan::CopyablePersistentTraits’
../src/segfault-handler.cpp:82:28: error: ‘CopyablePersistentTraits’ is not a member of ‘v8’
   v8::Persistent<Function, v8::CopyablePersistentTraits<Function> > callback;
                            ^
../src/segfault-handler.cpp:82:28: note: suggested alternatives:
In file included from ../node_modules/nan/nan.h:317:0,
                 from ../src/segfault-handler.cpp:2:
../node_modules/nan/nan_persistent_pre_12_inl.h:129:8: note:   ‘Nan::CopyablePersistentTraits’
 struct CopyablePersistentTraits {
        ^
../node_modules/nan/nan_persistent_pre_12_inl.h:129:8: note:   ‘Nan::CopyablePersistentTraits’
../src/segfault-handler.cpp:82:65: error: wrong number of template arguments (2, should be 1)
   v8::Persistent<Function, v8::CopyablePersistentTraits<Function> > callback;
                                                                 ^
In file included from /home/andreas/.node-gyp/0.10.40/src/node.h:62:0,
                 from ../node_modules/nan/nan.h:45,
                 from ../src/segfault-handler.cpp:2:
/home/andreas/.node-gyp/0.10.40/deps/v8/include/v8.h:107:26: note: provided for ‘template<class T> class v8::Persistent’
 template <class T> class Persistent;
                          ^
../src/segfault-handler.cpp:82:67: error: expected unqualified-id before ‘>’ token
   v8::Persistent<Function, v8::CopyablePersistentTraits<Function> > callback;
                                                                   ^
../src/segfault-handler.cpp: In constructor ‘callback_helper::callback_args::callback_args(int)’:
../src/segfault-handler.cpp:69:5: error: class ‘callback_helper::callback_args’ does not have any field named ‘callback’
     callback(callback), stack(backtrace_symbols(stack, stack_size)), stack_size(stack_size), signo(signo), addr(addr) {
     ^
../src/segfault-handler.cpp:69:14: error: ‘callback’ was not declared in this scope
     callback(callback), stack(backtrace_symbols(stack, stack_size)), stack_size(stack_size), signo(signo), addr(addr) {
              ^
../src/segfault-handler.cpp:69:49: error: invalid conversion from ‘char**’ to ‘void* const*’ [-fpermissive]
     callback(callback), stack(backtrace_symbols(stack, stack_size)), stack_size(stack_size), signo(signo), addr(addr) {
                                                 ^
In file included from ../src/segfault-handler.cpp:21:0:
/usr/include/execinfo.h:32:15: note:   initializing argument 1 of ‘char** backtrace_symbols(void* const*, int)’
 extern char **backtrace_symbols (void *const *__array, int __size)
               ^
../src/segfault-handler.cpp:68:5: warning: ‘callback_helper::callback_args::stack_size’ is initialized with itself [-Winit-self]
     callback_args(v8::Persistent<Function, v8::CopyablePersistentTraits<Function> >* callback, void * const* stack, size_t stack_size, int signo, 
     ^
../src/segfault-handler.cpp:68:5: warning: ‘callback_helper::callback_args::signo’ is initialized with itself [-Winit-self]
../src/segfault-handler.cpp:68:5: warning: ‘callback_helper::callback_args::addr’ is initialized with itself [-Winit-self]
../src/segfault-handler.cpp: In constructor ‘callback_helper::callback_helper(v8::Handle<v8::Function>)’:
../src/segfault-handler.cpp:87:5: error: ‘callback’ was not declared in this scope
     callback.Reset(isolate, func);
     ^
../src/segfault-handler.cpp:93:59: error: invalid conversion from ‘void (*)(uv_async_t*) {aka void (*)(uv_async_s*)}’ to ‘uv_async_cb {aka void (*)(uv_async_s*, int)}’ [-fpermissive]
     uv_async_init(uv_default_loop(), handle, make_callback);
                                                           ^
In file included from ../node_modules/nan/nan.h:44:0,
                 from ../src/segfault-handler.cpp:2:
/home/andreas/.node-gyp/0.10.40/deps/uv/include/uv.h:1211:15: note:   initializing argument 3 of ‘int uv_async_init(uv_loop_t*, uv_async_t*, uv_async_cb)’
 UV_EXTERN int uv_async_init(uv_loop_t*, uv_async_t* async,
               ^
../src/segfault-handler.cpp: In destructor ‘callback_helper::~callback_helper()’:
../src/segfault-handler.cpp:98:5: error: ‘callback’ was not declared in this scope
     callback.Reset();
     ^
../src/segfault-handler.cpp: In member function ‘void callback_helper::send(void* const*, size_t, int, long int)’:
../src/segfault-handler.cpp:106:46: error: ‘callback’ was not declared in this scope
     callback_args* args = new callback_args(&callback, stack, stack_size, signo, addr);
                                              ^
../src/segfault-handler.cpp: In static member function ‘static void callback_helper::make_callback(uv_async_t*)’:
../src/segfault-handler.cpp:140:34: error: no matching function for call to ‘v8::HandleScope::HandleScope(v8::Isolate*&)’
     v8::HandleScope scope(isolate);
                                  ^
In file included from /home/andreas/.node-gyp/0.10.40/src/node.h:62:0,
                 from ../node_modules/nan/nan.h:45,
                 from ../src/segfault-handler.cpp:2:
/home/andreas/.node-gyp/0.10.40/deps/v8/include/v8.h:473:3: note: candidate: v8::HandleScope::HandleScope(const v8::HandleScope&)
   HandleScope(const HandleScope&);
   ^
/home/andreas/.node-gyp/0.10.40/deps/v8/include/v8.h:473:3: note:   no known conversion for argument 1 from ‘v8::Isolate*’ to ‘const v8::HandleScope&’
/home/andreas/.node-gyp/0.10.40/deps/v8/include/v8.h:448:3: note: candidate: v8::HandleScope::HandleScope()
   HandleScope();
   ^
/home/andreas/.node-gyp/0.10.40/deps/v8/include/v8.h:448:3: note:   candidate expects 0 arguments, 1 provided
../src/segfault-handler.cpp:148:65: error: no matching function for call to ‘v8::Array::New(v8::Isolate*&, size_t&)’
     Local<Array> argStack = Array::New(isolate, args->stack_size);
                                                                 ^
In file included from /home/andreas/.node-gyp/0.10.40/src/node.h:62:0,
                 from ../node_modules/nan/nan.h:45,
                 from ../src/segfault-handler.cpp:2:
/home/andreas/.node-gyp/0.10.40/deps/v8/include/v8.h:1762:32: note: candidate: static v8::Local<v8::Array> v8::Array::New(int)
   V8EXPORT static Local<Array> New(int length = 0);
                                ^
/home/andreas/.node-gyp/0.10.40/deps/v8/include/v8.h:1762:32: note:   candidate expects 1 argument, 2 provided
../src/segfault-handler.cpp:150:24: error: ‘NewFromUtf8’ is not a member of ‘v8::String’
       argStack->Set(i, String::NewFromUtf8(isolate, args->stack[i]));
                        ^
../src/segfault-handler.cpp:154:61: error: no matching function for call to ‘v8::Number::New(v8::Isolate*&, int&)’
     Local<Value> argv[3] = {Number::New(isolate, args->signo), Number::New(isolate, args->addr), argStack};
                                                             ^
In file included from /home/andreas/.node-gyp/0.10.40/src/node.h:62:0,
                 from ../node_modules/nan/nan.h:45,
                 from ../src/segfault-handler.cpp:2:
/home/andreas/.node-gyp/0.10.40/deps/v8/include/v8.h:1381:33: note: candidate: static v8::Local<v8::Number> v8::Number::New(double)
   V8EXPORT static Local<Number> New(double value);
                                 ^
/home/andreas/.node-gyp/0.10.40/deps/v8/include/v8.h:1381:33: note:   candidate expects 1 argument, 2 provided
../src/segfault-handler.cpp:154:95: error: no matching function for call to ‘v8::Number::New(v8::Isolate*&, long int&)’
     Local<Value> argv[3] = {Number::New(isolate, args->signo), Number::New(isolate, args->addr), argStack};
                                                                                               ^
In file included from /home/andreas/.node-gyp/0.10.40/src/node.h:62:0,
                 from ../node_modules/nan/nan.h:45,
                 from ../src/segfault-handler.cpp:2:
/home/andreas/.node-gyp/0.10.40/deps/v8/include/v8.h:1381:33: note: candidate: static v8::Local<v8::Number> v8::Number::New(double)
   V8EXPORT static Local<Number> New(double value);
                                 ^
/home/andreas/.node-gyp/0.10.40/deps/v8/include/v8.h:1381:33: note:   candidate expects 1 argument, 2 provided
../src/segfault-handler.cpp:157:42: error: ‘struct callback_helper::callback_args’ has no member named ‘callback’
     Local<Function>::New(isolate, *args->callback)->Call(isolate->GetCurrentContext()->Global(), 3, argv);
                                          ^
../src/segfault-handler.cpp:157:67: error: ‘class v8::Isolate’ has no member named ‘GetCurrentContext’
     Local<Function>::New(isolate, *args->callback)->Call(isolate->GetCurrentContext()->Global(), 3, argv);
                                                                   ^
segfault-handler.target.mk:89: recipe for target 'Release/obj.target/segfault-handler/src/segfault-handler.o' failed
make: *** [Release/obj.target/segfault-handler/src/segfault-handler.o] Error 1

@No9
Copy link
Collaborator

No9 commented Feb 16, 2016

Thanks @papandreou
@lavarsicious From the error it looks like the V8 objects need to be NANified instead of referencing the V8:: namespace directly.
Note I did not push this to NPM yet so we aren't breaking users yet

@lavarsicious
Copy link
Author

Makes sense, I'll take a look at implementing this in a NAN friendly way.

@a-teammate
Copy link

a-teammate commented Jun 30, 2017

a Nan friendly way:

// Globals:

static bool has_user_callback = false;
static Nan::Persistent<v8::Function> user_defined_callback{};

// add to RegisterHandler:

    if (info.Length() > 1) {
      user_defined_callback.Reset(info[1].As<v8::Function>());
      has_user_callback = true;
    }

// add to SEGFAULT_HANDLER:

  if(has_user_callback) {
    Isolate* isolate = Isolate::GetCurrent();
    Local<Function> cb = New(user_defined_callback);

    const unsigned int argc = 3;
    Local<Value> argv[argc] ={String::NewFromUtf8(isolate, "hello world"),
        String::NewFromUtf8(isolate, "hello world"),
        String::NewFromUtf8(isolate, "hello world")
    };
    cb->Call(Null(isolate), argc, argv);

    has_user_callback = false;
    user_defined_callback.Reset(); // destroy persistent object
  }

the bool has_user_callback is probably already integrated in Nan::Persistent and could be replaced (if you're striving for elegance).

for the windows part of this issue i wrote some stuff in #38

tested with node 6.9.4

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.

4 participants