簡體   English   中英

libuv + C ++段錯誤

[英]libuv + C++ segfaults

我正在用libuv為C ++中的流編寫包裝器,但是它存在段錯誤,我不知道為什么。 流類:

class Stream{
  public:
  Stream(int fd);

  void Write(const std::string& data, const std::function<void(void)>& callback);


  const static int STDIN = 0;
  const static int STDOUT = 1;
  private:
  static void OnWrite(uv_write_t *req, int status);
  uv_pipe_t pipe;
};

並執行

Stream::Stream(int fd){
  uv_pipe_init(uv_default_loop(), &pipe, 0);
  uv_pipe_open(&pipe, fd);
}

void Stream::Write(const std::string& data, const std::function<void(void)>& callback){
  uv_write_t request;
  uv_buf_t buffer = uv_buf_init((char*)malloc(data.length()*sizeof(char)), data.length());
  strcpy(buffer.base, data.c_str());
  buffer.len = data.length();
  uv_write(&request, (uv_stream_t*)&pipe, &buffer, 1, OnWrite);
}

void Stream::OnWrite(uv_write_t *req, int status){

}

在主文件中,我這樣做:

Stream* out = new Stream(Stream::STDOUT);
  out->Write("Hello, World!", []() {
});

uv_run(uv_default_loop(), RUN_DEFAULT);

但是,一旦運行此命令,它就會在uv_run語句上出現段uv_run 回溯:

#0  0x00007ffff7bcac94 in uv__write_callbacks (stream=stream@entry=0x603010) at src/unix/stream.c:907
#1  0x00007ffff7bcb0a1 in uv__stream_io (loop=<optimized out>, w=0x603098, events=<optimized out>) at src/unix/stream.c:1243
#2  0x00007ffff7bc31eb in uv__run_pending (loop=0x7ffff7dd98c0 <default_loop_struct>) at src/unix/core.c:710
#3  uv_run (loop=0x7ffff7dd98c0 <default_loop_struct>, mode=UV_RUN_DEFAULT) at src/unix/core.c:316
#4  0x0000000000400fcd in main ()

但是,如果我將uv_run放在Stream::Write方法中,它就可以正常工作。 我怎樣才能解決這個問題?


編輯

現在,我在堆上而不是在堆棧上分配管道,但是它仍然給我一個段錯誤。 我改變uv_pipe_t在標題中uv_pipe_t* ,現在執行改為這個:

Stream::Stream(int fd){
  pipe = new uv_pipe_t;
  uv_pipe_init(uv_default_loop(), pipe, 0);
  uv_pipe_open(pipe, fd);
}

void Stream::Write(const std::string& data, const std::function<void(void)>& callback){
  uv_write_t request;
  uv_buf_t buffer = uv_buf_init((char*)data.c_str(), data.length());
  uv_write(&request, (uv_stream_t*)pipe, &buffer, 1, OnWrite);
}

void Stream::OnWrite(uv_write_t *req, int status){
  delete req;
}

來自GDB的回溯:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7bcac94 in uv__write_callbacks (stream=stream@entry=0x603030) at src/unix/stream.c:907
907         uv__req_unregister(stream->loop, req);
(gdb) backtrace
#0  0x00007ffff7bcac94 in uv__write_callbacks (stream=stream@entry=0x603030) at src/unix/stream.c:907
#1  0x00007ffff7bcb0a1 in uv__stream_io (loop=<optimized out>, w=0x6030b8, events=<optimized out>) at src/unix/stream.c:1243
#2  0x00007ffff7bc31eb in uv__run_pending (loop=0x7ffff7dd98c0 <default_loop_struct>) at src/unix/core.c:710
#3  uv_run (loop=0x7ffff7dd98c0 <default_loop_struct>, mode=UV_RUN_DEFAULT) at src/unix/core.c:316
#4  0x0000000000400f4d in main ()

您的“寫請求”( uv_write_t )被分配在堆棧上,並且當libuv嘗試將其指針傳遞給寫回調函數時(或者實際上,當libuv本身嘗試使用它時)將不存在。)請記住,所有內容都是異步的在libuv; 這可能就是您使用它的原因!

您應該在堆上分配uv_write_t (或作為全局/類變量或從池中分配),並記住在寫回調中釋放它。

您的程序中還有另一個內存/生命周期錯誤,但這不是崩潰錯誤,而是會產生垃圾的錯誤。 您不需要malloc放入uv_buffer_t的緩沖區,並且可以在調用后立即釋放它(這是同步的!)實際上,您甚至不需要分配單獨的緩沖區;因此,您無需分配緩沖區。 您只需將data.c_str()作為第一個參數傳遞給uv_buf_init()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM