Buy commercial curl support. We
help you work out your issues, debug your libcurl applications, use the API,
port to new platforms, add new features and more. With a team lead by the
curl founder Daniel himself.
curl_easy_perform hangs in poll
- Contemporary messages sorted: [ by date ] [ by thread ] [ by subject ] [ by author ] [ by messages with attachments ]
From: Wyatt Ayers via curl-library <curl-library_at_lists.haxx.se>
Date: Thu, 4 Jun 2026 15:30:38 -0700
Hello,
I'm looking into an issue I am observing when running curl_easy_perform in a loop. After some amount of iterations, the program becomes stuck inside of poll.
The stack trace looks like this with gdb:
#0 0x00007f9b88b25e84 in poll () from /lib64/libc.so.6
#1 0x000000000047b1fd in Curl_poll (ufds=0x7ffdd0fcd6d0, nfds=2, timeout_ms=1000) at select.c:313
#2 0x000000000046fbc9 in multi_wait (multi=0x319033c8, extra_fds=0x0, extra_nfds=0, timeout_ms=1000, ret=0x0, extrawait=true, use_wakeup=true) at multi.c:1366
#3 0x000000000046fe65 in curl_multi_poll (multi=0x319033c8, extra_fds=0x0, extra_nfds=0, timeout_ms=1000, ret=0x0) at multi.c:1509
#4 0x0000000000461bfb in easy_transfer (multi=0x319033c8) at easy.c:698
#5 0x0000000000461e14 in easy_perform (data=0x31900e48, events=false) at easy.c:796
#6 0x0000000000461e4c in curl_easy_perform (data=0x31900e48) at easy.c:815
#7 0x0000000000460d19 in main (argc=1, argv=0x7ffdd0fcd9a8) at curl_test.c:24
And with strace:
recvfrom(6, "g}\10\341C=\7\260\336\256I&\1\362\225CBw\37\200\17\272~W\261\273/E/hGr"..., 16384, 0, NULL, NULL) = 1448
recvfrom(6, 0x1783298, 16384, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=6, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
poll([{fd=6, events=POLLIN}, {fd=3, events=POLLIN}], 2, 1000) = 0 (Timeout)
recvfrom(6, 0x1783298, 16384, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=6, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
poll([{fd=6, events=POLLIN}, {fd=3, events=POLLIN}], 2, 1000) = 1 ([{fd=6, revents=POLLIN}])
recvfrom(6, "\211\277\231_at_\240\373\367\330\212\214\317\233\37\212\201\246[\276{\375\214?\222K\317|\247\n~>b\230"..., 16384, 0, NULL, NULL) = 1448
recvfrom(6, 0x1783298, 16384, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=6, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
poll([{fd=6, events=POLLIN}, {fd=3, events=POLLIN}], 2, 1000) = 0 (Timeout)
recvfrom(6, 0x1783298, 16384, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=6, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
poll([{fd=6, events=POLLIN}, {fd=3, events=POLLIN}], 2, 1000) = 1 ([{fd=6, revents=POLLIN}])
recvfrom(6, "ub\v\37\321\1\6\317\217\305c\221K\306\177\243\315\261\4\337\276|\354*\315\201\355\316\257\306'D"..., 16384, 0, NULL, NULL) = 1448
recvfrom(6, 0x1783298, 16384, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=6, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
poll([{fd=6, events=POLLIN}, {fd=3, events=POLLIN}], 2, 1000) = 0 (Timeout)
I've so far tested this with an FTP server via vsftpd v2.3.4 using curl v8.20. I tested on a fedora linux machine I initially thought this was related to my use of CURLOPT_FORBID_REUSE = 1, but I reproduced this behavior using CURLOPT_FRESH_CONNECT = 1 instead (i.e. FRESH_CONNECT = 1, FORBID_REUSE = 0). I can't say for certain whether or not this is a bug with my ancient FTP server. I can get around the hang by using a nonzero CURLOPT_TIMEOUT, though this is not addressing the root cause. I've included the source of a simple C program to reproduce this and a logfile produced with CURLOPT_VERBOSE. After a while of being in this state, I observe with netstat that the client machine has a socket to port 21 on the server machine that is in a CLOSE_WAIT state. Is this a problem seen elsewhere? I'm curious if this is a misuse of the curl_easy API and if I ought to use the curl_multi API for this "many repeat transfers" task. I've trimmed the curl log to 100 lines for the sake of brevity.
Thanks,
Wyatt
Received on 2026-06-05
Date: Thu, 4 Jun 2026 15:30:38 -0700
Hello,
I'm looking into an issue I am observing when running curl_easy_perform in a loop. After some amount of iterations, the program becomes stuck inside of poll.
The stack trace looks like this with gdb:
#0 0x00007f9b88b25e84 in poll () from /lib64/libc.so.6
#1 0x000000000047b1fd in Curl_poll (ufds=0x7ffdd0fcd6d0, nfds=2, timeout_ms=1000) at select.c:313
#2 0x000000000046fbc9 in multi_wait (multi=0x319033c8, extra_fds=0x0, extra_nfds=0, timeout_ms=1000, ret=0x0, extrawait=true, use_wakeup=true) at multi.c:1366
#3 0x000000000046fe65 in curl_multi_poll (multi=0x319033c8, extra_fds=0x0, extra_nfds=0, timeout_ms=1000, ret=0x0) at multi.c:1509
#4 0x0000000000461bfb in easy_transfer (multi=0x319033c8) at easy.c:698
#5 0x0000000000461e14 in easy_perform (data=0x31900e48, events=false) at easy.c:796
#6 0x0000000000461e4c in curl_easy_perform (data=0x31900e48) at easy.c:815
#7 0x0000000000460d19 in main (argc=1, argv=0x7ffdd0fcd9a8) at curl_test.c:24
And with strace:
recvfrom(6, "g}\10\341C=\7\260\336\256I&\1\362\225CBw\37\200\17\272~W\261\273/E/hGr"..., 16384, 0, NULL, NULL) = 1448
recvfrom(6, 0x1783298, 16384, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=6, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
poll([{fd=6, events=POLLIN}, {fd=3, events=POLLIN}], 2, 1000) = 0 (Timeout)
recvfrom(6, 0x1783298, 16384, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=6, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
poll([{fd=6, events=POLLIN}, {fd=3, events=POLLIN}], 2, 1000) = 1 ([{fd=6, revents=POLLIN}])
recvfrom(6, "\211\277\231_at_\240\373\367\330\212\214\317\233\37\212\201\246[\276{\375\214?\222K\317|\247\n~>b\230"..., 16384, 0, NULL, NULL) = 1448
recvfrom(6, 0x1783298, 16384, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=6, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
poll([{fd=6, events=POLLIN}, {fd=3, events=POLLIN}], 2, 1000) = 0 (Timeout)
recvfrom(6, 0x1783298, 16384, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=6, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
poll([{fd=6, events=POLLIN}, {fd=3, events=POLLIN}], 2, 1000) = 1 ([{fd=6, revents=POLLIN}])
recvfrom(6, "ub\v\37\321\1\6\317\217\305c\221K\306\177\243\315\261\4\337\276|\354*\315\201\355\316\257\306'D"..., 16384, 0, NULL, NULL) = 1448
recvfrom(6, 0x1783298, 16384, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=6, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
poll([{fd=6, events=POLLIN}, {fd=3, events=POLLIN}], 2, 1000) = 0 (Timeout)
I've so far tested this with an FTP server via vsftpd v2.3.4 using curl v8.20. I tested on a fedora linux machine I initially thought this was related to my use of CURLOPT_FORBID_REUSE = 1, but I reproduced this behavior using CURLOPT_FRESH_CONNECT = 1 instead (i.e. FRESH_CONNECT = 1, FORBID_REUSE = 0). I can't say for certain whether or not this is a bug with my ancient FTP server. I can get around the hang by using a nonzero CURLOPT_TIMEOUT, though this is not addressing the root cause. I've included the source of a simple C program to reproduce this and a logfile produced with CURLOPT_VERBOSE. After a while of being in this state, I observe with netstat that the client machine has a socket to port 21 on the server machine that is in a CLOSE_WAIT state. Is this a problem seen elsewhere? I'm curious if this is a misuse of the curl_easy API and if I ought to use the curl_multi API for this "many repeat transfers" task. I've trimmed the curl log to 100 lines for the sake of brevity.
Thanks,
Wyatt
-- Unsubscribe: https://lists.haxx.se/mailman/listinfo/curl-library Etiquette: https://curl.se/mail/etiquette.html
- text/x-csrc attachment: curl-test.c
- text/plain attachment: curl_log_trimmed.txt