-
-
Notifications
You must be signed in to change notification settings - Fork 7.1k
Closed
Labels
Description
This setup:
- We are using libcurl in our in-house software.
- The code uses SFTP with libssh2 via the curl_easy interface.
- We are setting the transfer timeout using
CURLOPT_TIMEOUT.
Problem:
We observe a serious memory leak. I have tracked it down to libssh2_session_free never being called.
- Our code calls
curl_easy_cleanup. - We get to the code in l
ibssh2.c:ssh_statemach_actthat handlesSSH_SFTP_SHUTDOWN. - This calls
libssh2_sftp_shutdownand that givesEWOULDBLOCK. - The backtrace here is:
#1 0x00007ffff7f76cc1 in ssh_block_statemach (data=0x5555555a60c8, conn=0x5555555bca08,
duringconnect=false) at vssh/libssh2.c:2954
#2 0x00007ffff7f77a4c in sftp_disconnect (data=0x5555555a60c8, conn=0x5555555bca08,
dead_connection=false) at vssh/libssh2.c:3473
#3 0x00007ffff7f54724 in Curl_disconnect (data=0x5555555a60c8, conn=0x5555555bca08,
dead_connection=false) at url.c:855
#4 0x00007ffff7ede9d5 in Curl_conncache_close_all_connections (connc=0x5555555babf8)
at conncache.c:556
#5 0x00007ffff7f269e2 in curl_multi_cleanup (multi=0x5555555baaf8) at multi.c:2596
#6 0x00007ffff7f53172 in Curl_close (datap=0x7fffffffde28) at url.c:380
#7 0x00007ffff7ef08d3 in curl_easy_cleanup (data=0x0) at easy.c:742
#8 0x0000555555555ef2 in sftp_upload (url=0x7fffffffe5ba "sftp://benny@localhost:1122/tmp/testing",
private_key=0x7fffffffe5ec "/home/benny/Projects/cds_c/src/libs/libmecomcurl/testsrc/sshd/clientkey.rsa", request=0x7ffff79935f0 <__GI__IO_fread>, request_size=0, request_userp=0x55555559ed20)
at sftpcurl.c:159
#9 0x0000555555555ff1 in test_curl (url=0x7fffffffe5ba "sftp://benny@localhost:1122/tmp/testing",
requestFileName=0x7fffffffe5e2 "/dev/null",
key=0x7fffffffe5ec "/home/benny/Projects/cds_c/src/libs/libmecomcurl/testsrc/sshd/clientkey.rsa",
debug=0) at tSftp.c:58
#10 0x00005555555560a8 in test_curl_memory_leak (count=12,
url=0x7fffffffe5ba "sftp://benny@localhost:1122/tmp/testing",
--Type <RET> for more, q to quit, c to continue without paging--c
ull", key=0x7fffffffe5ec "/home/benny/Projects/cds_c/src/libs/libmecomcurl/testsrc/sshd/clientkey.rsa") at tSftp.c:83
#11 0x00005555555562db in main (argc=6, argv=0x7fffffffe2a8) at tSftp.c:149
- I.e.
ssh_statemach_actis called fromssh_block_statemach. - In
ssh_block_statemachthe reaction to this is thatconnect.c:Curl_timeleftgets called. Curl_timeleftfails (returns a negative number), becausedata->set.timeoutis set to a timeout, butdata->progress.t_startopis 0.- After that
ssh_block_statemachreturns and all the data allocated by libssh2 is abandoned.
It seems that the CURL handle that is used in Curl_conncache_close_all_connections is not the same as the one used during the SFTP data transfer. This code probably does not expect that there is more network traffic during the disconnect handler that would need timeout handling. It is not quite clear where the correct value for data->progress.t_startop would come from. sftp_disconnect could of course just set it to the current time, but that might not be entirely correct.
A couple of additional thoughts:
- Even if the timeout issue were real, the resources allocated by libssh2 should still be freed.
- The debug function that we set with
CURLOPT_DEBUGFUNCTIONin the top-level handle is not set in the second CURL handle. This means that the call tofailfinssh_block_statemachdoes not show up anywhere.
Reactions are currently unavailable