节点Addon libuv文件系统段错误

时间:2015-02-02 13:27:22

标签: c++ node.js segmentation-fault libuv

我试图创建一个包含libuv双工管道的节点插件,用于c ++和节点进程之间的通信。

我已经写完了课程,现在我正在测试它,但是,当我尝试打开管道时:

int fd = uv_fs_open(uv_default_loop(), obj->file_req, "MYFIFO", O_CREAT | O_RDWR, 0644, NULL);

我遇到了分段错误11。

这是我的班级实施:

#include <node.h>
#include <string>
#include <uv.h>
#include <queue>

using namespace v8;

const char* symbol_message = "message";

class rtSocket : public node::ObjectWrap
{
  private:

  public:
    static Persistent<Function> constructor;

    uv_pipe_t * readPipe, * writePipe;
    uv_fs_t * file_req;
    uv_mutex_t message_mutex;
    uv_async_t message_async;

    struct PipeMessage
    {
        unsigned int cb;
        unsigned int value;
    };

    std::queue<PipeMessage*> message_queue;

    rtSocket()
    {
        writePipe = NULL;
        readPipe = NULL;
        uv_mutex_init(&message_mutex);
    }

    ~rtSocket() 
    {
        /*uv_read_stop()???*/
        uv_mutex_destroy(&message_mutex);
    }

    static Handle<Value> New( const Arguments & args)
    {
        HandleScope scope;

        if (!args.IsConstructCall())
        {    
            return ThrowException(v8::Exception::TypeError(
                    v8::String::New("Use the new operator to create instances of this object.")));
        }
        // Invoked as constructor: `new MyObject(...)`
        rtSocket * obj = new rtSocket();
        obj->message_async.data = obj;
        uv_async_init(uv_default_loop(), &obj->message_async, rtSocket::EmitMessage);
        obj->Wrap(args.This());
        return args.This();
    }

    static Handle<Value> Connect(const Arguments & args)
    {
        HandleScope scope;
        rtSocket * obj = ObjectWrap::Unwrap<rtSocket>(args.This());
        int fd, r;
        if (1 > args.Length() || !args[0]->IsString())
        {
            return ThrowException(Exception::TypeError(
                    String::New("First argument must be a string (FIFO name)")));
        }
        v8::String::Utf8Value s (args[0]->ToString());
        std::string p( *s );
        std::string writablePipeName, readablePipeName;

        writablePipeName = readablePipeName = p;
        writablePipeName.resize(writablePipeName.size()+1, 'W');
        readablePipeName.resize(readablePipeName.size()+1, 'R');

        //Open file system Pipe
        fd = uv_fs_open(uv_default_loop(), obj->file_req, readablePipeName.c_str(), O_CREAT | O_RDWR, 0644, NULL);        
        //Initialize reading pipe
        r = uv_pipe_init(uv_default_loop(), obj->readPipe, 0);
        if (r)
        {
            return ThrowException(Exception::TypeError(
                    String::New("Impossible to initialize read pipe!!")));
        }
        //Open pipe
        r = uv_pipe_open(obj->readPipe, fd);
        if (r)
        {
            return ThrowException(Exception::TypeError(
                    String::New("Impossible to open read pipe!!")));
        }
        //Register callbacks
        r = uv_read_start((uv_stream_t*)obj->readPipe, rtSocket::on_alloc_buffer, rtSocket::on_read);   
        if (r)
        {
            return ThrowException(Exception::TypeError(
                    String::New("Impossible to call read start!!")));
        }
        //Open file system Pipe
        fd = uv_fs_open(uv_default_loop(), obj->file_req, writablePipeName.c_str(), O_CREAT | O_RDWR, 0644, NULL);
        //Initialize reading pipe
        r = uv_pipe_init(uv_default_loop(), obj->writePipe, 0);
        if (r)
        {
            return ThrowException(Exception::TypeError(
                    String::New("Impossible to initialize write pipe!!")));
        }
        //Open pipe
        r = uv_pipe_open(obj->writePipe, fd);
        if (r)
        {
            return ThrowException(Exception::TypeError(
                    String::New("Impossible to open write pipe!!")));
        }
        //Don't register callbacks on writable pipe, write from js
        return scope.Close(Undefined());
    }

    static void Init(Handle<Object> exports)
    {
        //Prepare constructor template
        Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
        tpl->InstanceTemplate()->SetInternalFieldCount(1);
        tpl->SetClassName(String::NewSymbol("rtSocket"));
        NODE_SET_PROTOTYPE_METHOD(tpl, "Connect", Connect); 
        constructor = Persistent<Function>::New(tpl->GetFunction());
        exports->Set(String::NewSymbol("rtSocket"), constructor);
    }
};

Persistent<Function> rtSocket::constructor;

extern "C" 
{
    void init (v8::Handle<v8::Object> target)
    {
        rtSocket::Init(target);
    }
    NODE_MODULE(rtSocket, init)
}

很抱歉,但我认为这是必要的背景(EmitMessage,on_alloc_buffer和on_read并不是为了简单起见)。

我正在努力解决这个问题,我认为这与背景和范围有关,但不知道如何解决它。如果有人能够解释我做错了什么,那就太好了!

编辑:我试图猜测node-segfault-handler会发生什么,这是堆栈跟踪,但我不理解它抱怨的内容:

  • PID 4536收到SIGSEGV的地址:0x0
    1. segfault-handler.node 0x0000000100af447f _ZL16segfault_handleriP9__siginfoPv + 287
    2. libsystem_platform.dylib 0x00007fff9649ff1a _sigtramp + 26
    3. ??? 0x00007fff5fbff138 0x0 + 140734799802680
    4. rtSocket.node 0x00000001039469e2 _ZN8rtSocket7ConnectERKN2v89ArgumentsE + 366
    5. 节点0x0000000100153fe3 _ZN2v88internalL21Builtin_HandleApiCallENS0_12_GLOBAL__N_116BuiltinArgumentsILNS0_21BuiltinExtraArgumentsE1EEEPNS0_7IsolateE + 483
    6. ??? 0x00003fe588a06362 0x0 + 70255072273250

0 个答案:

没有答案