Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Crash on windows #645

Closed
mattn opened this Issue Dec 5, 2012 · 9 comments

Comments

Projects
None yet
3 participants
Contributor

mattn commented Dec 5, 2012

I built following code on mingw32.
I used windows xp.

#include <iostream>
#include <uv.h>

int
main() {
  int r;
  uv_tcp_t tcp;
  struct sockaddr_in server_addr;

  server_addr = uv_ip4_addr("127.0.0.1", 80);
  r = uv_tcp_init(uv_default_loop(), &tcp);
  uv_connect_t connect_req;

  r = uv_tcp_connect(&connect_req, &tcp, server_addr,
    [](uv_connect_t *req, int status) {
      std::cout << "connected" << std::endl;

      int r;
      uv_buf_t buf[1];
      uv_stream_t* tcp = req->handle;
      char *req_message = (char*) "GET / HTTP/1.0\r\n\r\n";

      buf[0].len = strlen(req_message);
      buf[0].base = req_message;

      uv_write_t write_req;
      r = uv_write(&write_req, tcp, buf, 1,
        [](uv_write_t* req, int status) {
          int r;
          uv_stream_t* tcp = req->handle;

          std::cout << "written" << std::endl;
          r = uv_read_start((uv_stream_t*)tcp,
            [](uv_handle_t* handle, size_t size) -> uv_buf_t {
              std::cout << "alloc " << size << std::endl;
              uv_buf_t buf;
              buf.base = (char*)malloc(size);
              buf.len = size;
              return buf;
            },
            [](uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
              std::cout << "read" << std::endl;

              if (nread < 0) {
                if (buf.base) {
                  free(buf.base);
                }
                uv_close((uv_handle_t*) tcp,
                  [](uv_handle_t* handle) {
                    std::cout << "closed" << std::endl;
                  }
                );
                return;
              }
              std::cout << buf.base << std::endl;

              free(buf.base);
              return;
            }
          );
        }
      );
    }
  );

  std::cout << "main" << std::endl;
  uv_run(uv_default_loop());
}

build & run

C:\>g++ -std=c++0x -o foo foo.cxx -luv
C:\>foo.exe

crash log

main
connected
Assertion failed: 0, file src/win/stream.c, line 131

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

gdb log

GNU gdb (GDB) 7.5
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from C:\temp\github\libuv\foo.exe...(no debugging symbols found)
...done.
(gdb) run
Starting program: C:\temp\github\libuv\foo.exe
[New Thread 5632.0xed4]
main
connected

Program received signal SIGSEGV, Segmentation fault.
0x64a4f549 in uv_write (req=0x22fd10, handle=0xffffffff, bufs=0x22fd5c,
    bufcnt=1,
    cb=0x4015fa <main::{lambda(uv_connect_s*, int)#1}::operator()(uv_connect_s*, int) const::{lambda(uv_write_s*, int)#1}::_FUN(uv_write_s, int)>)
    at src/win/stream.c:121
warning: Source file is more recent than executable.
121
(gdb) bt
#0  0x64a4f549 in uv_write (req=0x22fd10, handle=0xffffffff, bufs=0x22fd5c, bufcnt=1, cb=0x4015fa <main::{lambda(uv_connect_s*, int)#1}::operator()(uv_connect_s*, int) const::{lambda(uv_write_s*, int)#1}::_FUN(uv_write_s, int)>) at src/win/stream.c:121
#1  0x004016b0 in _fu5___ZSt4cout ()
#2  0x0022fd10 in ?? ()
#3  0x004016e1 in main::{lambda(uv_connect_s*, int)#1}::_FUN(uv_connect_s*, int) ()
#4  0x64a51b6e in uv_process_tcp_connect_req (loop=0x64a74020, handle=0x22fe8c, req=0x22fe58) at src/win/tcp.c:1030
#5  0x64a4f07a in uv_process_reqs (loop=0x64a74020) at src/win/req.c:112
#6  0x64a42247 in uv_run (loop=0x64a74020) at src/win/core.c:265
#7  0x004017cf in _fu6___ZSt4cout ()
#8  0x64a74020 in obj () from C:\temp\github\libuv\uv.dll
#9  0x004040a7 in std::piecewise_construct ()
#10 0x50000002 in ?? ()
#11 0x0100007f in ?? ()
#12 0x00000000 in ?? ()
(gdb)

@mattn mattn referenced this issue in mattn/mruby-uv Dec 5, 2012

Closed

Still active? #5

Member

piscisaureus commented Dec 5, 2012

It seems that the uv_connect_req and uv_write_req are stack-allocated. I have no experience with using lambdas - but are you sure the write req is still valid when the write callback is called?

Member

piscisaureus commented Dec 5, 2012

At the very least the "handle" argument for uv_write_t should not be set to 0xffffffff - that can only be wrong.

Contributor

mattn commented Dec 5, 2012

This problem occur on https://github.com/mattn/mruby-uv also.

Contributor

mattn commented Dec 5, 2012

This example code above was worked correctly on windows at least in few month ago.

Member

piscisaureus commented Dec 5, 2012

@mattn Are you sure uv.a is up-to-date and matches the uv.h header that you are including? I tried your test code and it works:

Bert Belder@piscisaureus2 /d/libuv
$ g++ -std=c++0x -g -o foo foo.cxx uv.a -Iinclude -lws2_32 -liphlpapi -lpsapi

Bert Belder@piscisaureus2 /d/libuv
$ ./foo.exe
main
connected
written
alloc 65536
read
HTTP/1.1 200 OK
Date: Wed, 05 Dec 2012 01:43:22 GMT
Connection: close

hello
alloc 65536
read
closed
Contributor

bnoordhuis commented Dec 5, 2012

As another data point, your test case works for me as well.

warning: Source file is more recent than executable.

That suggests your build is out of date.

Contributor

mattn commented Dec 6, 2012

mingw32 build output libuv.a not uv.a ?

Member

piscisaureus commented Dec 6, 2012

@mattn You're right. That was the line I used when I tried it with the v0.8 branch. However I also built it with master (replace uv.a by libuv.a) and everything works fine here still.

Contributor

mattn commented Dec 6, 2012

Ah, I figured out now. mingw's gcc place libuv.dll.a ahead of libuv.a ...
I was created libuv.dll.a for https://github.com/mattn/go-uv in few weeks ago. Sorry That! :-(

@mattn mattn closed this Dec 6, 2012

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment