charto / nbind

:sparkles: Magical headers that make your C++ library accessible from JavaScript :rocket:
MIT License
1.98k stars 119 forks source link

Floating Point Exception #103

Closed BotellaA closed 6 years ago

BotellaA commented 6 years ago

I get a floating point exception while executing my script:

Thread 1 "nodejs" received signal SIGFPE, Arithmetic exception.
0x0000000000fab867 in v8::internal::Object::ConvertToInt32(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>) ()
(gdb) where
#0  0x0000000000fab867 in v8::internal::Object::ConvertToInt32(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>) ()
#1  0x0000000000af73ab in v8::Value::Int32Value(v8::Local<v8::Context>) const ()
#2  0x0000000000b0c264 in v8::Value::Int32Value() const ()
#3  0x0000000001224a93 in node::EmitExit(node::Environment*) ()
#4  0x000000000122c23e in node::Start(uv_loop_s*, int, char const* const*, int, char const* const*) ()
#5  0x0000000001224d03 in node::Start(int, char**) ()
#6  0x00007ffff6b63830 in __libc_start_main (main=0x8acef0 <main>, argc=2, argv=0x7fffffffd9f8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, 
    stack_end=0x7fffffffd9e8) at ../csu/libc-start.c:291
#7  0x00000000008aee41 in _start ()

This exception can be reproduced by modifying your hello example in nbind-examples like this:

#include <string>
#include <iostream>
#include <cfenv>

struct Greeter {
  static void sayHello(
    std::string name
  ) {            
    feenableexcept(FE_INVALID);  // Activation of Floating Point Exception
    std::cout
      << "Hello, "
      << name << "!\n";
  }
};

#include "nbind/nbind.h"

NBIND_CLASS(Greeter) {
  method(sayHello);
}

Is it forbidden to use FPE?

jjrv commented 6 years ago

It seems the representation of integers in the V8 JavaScript engine is incompatible with FE_INVALID. I tried adding the code to Node's hello world example as follows:

#include <node.h>
#include <v8.h>
#include <cfenv>

using namespace v8;

void Method(const v8::FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);
  feenableexcept(FE_INVALID);
  args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world"));
}

void Init(Handle<Object> exports) {
  Isolate* isolate = Isolate::GetCurrent();
  exports->Set(String::NewFromUtf8(isolate, "hello"),
      FunctionTemplate::New(isolate, Method)->GetFunction());
}

NODE_MODULE(hello, Init)

It also throws the exception:

#0  0x0000000001025304 in v8::internal::Object::ConvertToInt32(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>) ()
#1  0x0000000000aa4d35 in v8::Value::Int32Value(v8::Local<v8::Context>) const ()
#2  0x0000000000ab8e46 in v8::Value::Int32Value() const ()
#3  0x0000000001371ddf in node::EmitExit(node::Environment*) ()
#4  0x0000000001377e40 in node::Start(uv_loop_s*, int, char const* const*, int, char const* const*) ()
#5  0x0000000001371f5e in node::Start(int, char**) ()
#6  0x00007ffff6b63830 in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6
#7  0x00000000008ec861 in _start ()

I don't think there's anything nbind can do about this.

BotellaA commented 6 years ago

Thanks for your reply. Should I report this to node directly?

jjrv commented 6 years ago

Actually it's probably a design issue in the V8 JavaScript engine so the relevant code would be maintained by Google.

BotellaA commented 6 years ago

Ok, I will look into it and see if there is an issue tracker for V8.

BotellaA commented 6 years ago

Link to the issue: https://bugs.chromium.org/p/v8/issues/detail?id=7342