Menu

#1170 curl_easy_recv() ends in crash within Curl_recv_plain

closed-works-for-me
libcurl (356)
5
2013-06-21
2012-12-10
Con Kolivas
No

In the cgminer project ( https://github.com/ckolivas/cgminer ) I am using libcurl version 7.28.1 compiled for mingw32 and using curl easy recv on the raw socket returned. Dropping internet connection on windows* with this compiled version I get a reproducible crash on the following line:
sendf.c:353
failf(conn->data, "Recv failure: %s", Curl_strerror(conn, err));
Debugging is disabled in the build, but this line reliably crashes on mingw32. Commenting out the line entirely the crash goes away. This can be reproduced without dropping internet connection on windows by killing the tcp connection with currports. I don't know the exact mechanism of the crash without digging further but I suspect conn->data is dereferenced.

Discussion

  • Daniel Stenberg

    Daniel Stenberg - 2012-12-10

    Can you help us and produce a smallish stand-alone program that can repeat the problem? In the case of the failure, can you use a debugger/printf and see what 'conn' and 'data' point to at the time of the problem?

     
  • Daniel Stenberg

    Daniel Stenberg - 2012-12-10
    • summary: Mingw32 crash on calling failf in Curl_recv_plain --> curl_easy_recv() ends in crash within Curl_recv_plain
     
  • Con Kolivas

    Con Kolivas - 2012-12-11

    I poked around a bit further and found the exact line responsible

    sendf.c: 170
    snprintf(data->set.errorbuffer, CURL_ERROR_SIZE, "%s", data->state.buffer);

    If I printf data->state.buffer to stdout it is a valid string, and data->set.errorbuffer points to an address, but writing to data->set.errorbuffer crashes.

    Note this usually happens the second time the tcp connection is reset, with a reused curl handle. This happens regardless of whether debugging is built into libcurl or not, or whether CURLOPT_VERBOSE is enabled or not. It does NOT happen on linux, only mingw32.

     
  • Daniel Stenberg

    Daniel Stenberg - 2012-12-11

    Thanks, but that can't be the end of the story.

    The snprintf() function you see used, is an internal function in libcurl called curl_msnprintf() in lib/mprint.c and you can continue down into that function to find the actual place it crashes.

    And still, snprintf() is used in NUMEROUS places within libcurl on a large amount of different platforms. Why would mingw32 have a problem with this particular call?

     
  • Con Kolivas

    Con Kolivas - 2012-12-11

    gdb session eliciting bug

     
  • Con Kolivas

    Con Kolivas - 2012-12-11

    I've uploaded a gdb session with a debug build of libcurl dll. I put a break point in the Curl_failf function. You can see it hits it twice on startup of my application and then the next 2 times it hits this function is when I close the tcp socket forcefully with currports to simulate the dropout that occurs. You can see the string in that looks corrupt on the last entry and I step through vsnprintf and you can see it become an invalid address. No idea why, but that's it in action...

     
  • Daniel Stenberg

    Daniel Stenberg - 2012-12-11

    Hm, looking from the bottom it clearly has gotten bad values in 'data' and 'fm' and that will of course lead to major badness. But how did the bad values end up in those variables?

    Is the vsnprintf() call on line 167 (in lib/sendf.c) that destroys them?

     
  • Con Kolivas

    Con Kolivas - 2012-12-11

    gdb session with mprintf.c stepping

     
  • Con Kolivas

    Con Kolivas - 2012-12-11

    Added gdb session with mprintf.c loaded

    I have no idea how those variables got trashed :s

     
  • Daniel Stenberg

    Daniel Stenberg - 2012-12-13

    Still, as I can't reproduce this problem I'm hoping you can keep looking and digging and see what particular code that breaks things...

     
  • Con Kolivas

    Con Kolivas - 2012-12-14

    I've tried what I normally try on linux on windows and I have no idea how to proceed. A segfault makes the stacktrace become invalid even under gdb, even when stepping through the application. Coredumps have never once worked. Drmingw has only once returned a stacktrace pointing to curl_formget which is how I got this far. The rest of the time it gives invalid addresses and register values that are meaningless to me. Debugging mingw stuff on windows is so awkward that I really have no idea where to go from here and I've spent many many hours on it already.

     
  • Daniel Stenberg

    Daniel Stenberg - 2012-12-14

    I read you. But unfortunately I still can't reproduce it on anything I have.

     
  • Daniel Stenberg

    Daniel Stenberg - 2013-01-09

    Any news?

     
  • Con Kolivas

    Con Kolivas - 2013-01-10

    Alas even the workaround I had used of disabling the debugging code did not make it stable, it just delayed it and the memory trashing seemed to move elsewhere. Since my code was in production I could no longer afford these random crashes and gave up, moving from curl_easy_recv to just using plain recv() which fixed all my problems, so I have been unable to debug it any further.

     
  • Daniel Stenberg

    Daniel Stenberg - 2013-01-10

    As you're not pursuing this and I can't repeat it, this issue will get closed soon unless someone else provides feedback. Thanks anyway!

     
  • Daniel Stenberg

    Daniel Stenberg - 2013-01-10
    • status: open --> pending
     
  • Daniel Stenberg

    Daniel Stenberg - 2013-01-20
    • status: pending --> closed-works-for-me
     
MongoDB Logo MongoDB