Re: Errors/crashes with FTP using multi interface?
Date: Thu, 28 Mar 2013 16:28:07 +0000
On 13 Feb 2013, at 22:51, Daniel Stenberg <daniel_at_haxx.se> wrote:
> You don't need to convert anything to our "standard test format", but if you want us to really be able to help you debug this then you must help us repeat the problem. The easiest way to do that is for you to write a new and stand-alone libcurl-using app (I'd prefer it being in plain standard C) that repeats your application's behavior and then hopefully(!) also repeats the bug.
For what it's worth, I now have a test case which appears to repeat my crash, or something very similar.
It's a plain C app, but it requires GCD (libdispatch).
For me, it crashes reliably with a single URL input of: ftp://ftptest:email@example.com/crashtest/
The server 10.0.1.32 is running, and has a directory called crashtest which contains some subdirectories.
The test performs some post-quote commands on an ftp (or sftp) url. When the easy handle completes, the test resubmits another request for the same command, so in effect it's just doing the same thing again and again.
This is an attempt to reproduce the situation where I see the crash in my real code - which is just after one easy handle completing and another being adding to a multi, when both are performing post-quote commands on the same server.
The test sets quite a lot of options, and installs lots of callback functions. Again, this was an attempt to reproduce the setup in my real code. It is possible that the crash will reproduce without a lot of those settings, but I've not tested that yet.
The crash happens in a number of different places, but here's an example trace:
* thread #2: tid = 0x3103, 0x000000010003bf2b libcurl.dylib`Curl_pp_readresp(sockfd=4, pp=0x0000000100806508, code=0x0000000100780ad4, size=0x0000000100780b20) + 794 at pingpong.c:379, stop reason = EXC_BAD_ACCESS (code=1, address=0x102800000)
frame #0: 0x000000010003bf2b libcurl.dylib`Curl_pp_readresp(sockfd=4, pp=0x0000000100806508, code=0x0000000100780ad4, size=0x0000000100780b20) + 794 at pingpong.c:379
frame #1: 0x0000000100011e43 libcurl.dylib`ftp_readresp(, ftpcode=0x0000000100780b8c) + 29 at ftp.c:627
frame #2: 0x0000000100011dab libcurl.dylib`Curl_GetFTPResponse(nreadp=0x0000000100780b90, conn=0x0000000100806000) + 227 at ftp.c:759
frame #3: 0x00000001000115ec libcurl.dylib`ftp_done [inlined] ftp_sendquote(, conn=0x0000000100806000) + 86 at ftp.c:3530
frame #4: 0x0000000100011596 libcurl.dylib`ftp_done(conn=0x0000000100806000, status=CURLE_OK, premature=false) + 1258 at ftp.c:3485
frame #5: 0x000000010001c8ed libcurl.dylib`Curl_done(connp=0x0000000101a00038) + 271 at url.c:5425
frame #6: 0x0000000100029eae libcurl.dylib`multi_runsingle(multi=0x0000000100600000, now=(null), easy=0x0000000101a00020) + 1580 at multi.c:1577
frame #7: 0x000000010002b0ee libcurl.dylib`multi_socket(multi=0x0000000100600000, checkall=true, s=-1, running_handles=0x0000000100780d94) + 420 at multi.c:2194
frame #8: 0x000000010002b180 libcurl.dylib`curl_multi_socket_action(multi_handle=0x0000000100600000) + 27 at multi.c:2297
frame #9: 0x000000010000126a crashtest`curl_perform_action(socket=-1, actions=0) + 42 at multi-gcd-crashtest.c:101
frame #10: 0x000000010000209d crashtest`__create_timeout_block_invoke(.block_descriptor=0x0000000100003210) + 29 at multi-gcd-crashtest.c:167
frame #11: 0x00007fff995710b6 libdispatch.dylib`_dispatch_client_callout + 8
frame #12: 0x00007fff9957329b libdispatch.dylib`_dispatch_source_invoke + 691
frame #13: 0x00007fff99572305 libdispatch.dylib`_dispatch_queue_invoke + 72
frame #14: 0x00007fff99572448 libdispatch.dylib`_dispatch_queue_drain + 180
frame #15: 0x00007fff995722f1 libdispatch.dylib`_dispatch_queue_invoke + 52
frame #16: 0x00007fff995721c3 libdispatch.dylib`_dispatch_worker_thread2 + 249
frame #17: 0x00007fff99731d0b libsystem_c.dylib`_pthread_wqthread + 404
frame #18: 0x00007fff9971c1d1 libsystem_c.dylib`start_wqthread + 13
Code versions I'm using are: libcurl/7.30.0-DEV SecureTransport zlib/1.2.5 c-ares/1.9.0-DEV libssh2/1.4.3_DEV
I've also enclosed a much cleaner and simpler version of the test, which doesn't crash, but simply illustrates how to use libcurl with gcd and dispatch sources.
- application/octet-stream attachment: multi-gcd-crashtest.c
- application/octet-stream attachment: multi-gcd.c