Closed rcoup closed 6 months ago
@rcoup hopefully https://github.com/OSGeo/gdal/pull/9681 should solve your issue?
AFAICS there's nothing to prevent race conditions wrt setting/restoring the SIGPIPE handler across multiple threads?
true, this all area is rather fragile. I don't think there's a real way of dealing with signals in a thread-safe way. The man page of signal() says "the effects of signal() in a multithreaded process are unspecified"... Ideally openssl shouldn't cause SIGPIPE to be triggered at all.
I don't know whether it's simpler just to save/restore one handler when curl is active, but I'm maybe missing some context where SIGPIPE is used elsewhere?
yes, installing signal() just once is perhaps safer (but only if signal() affects all threads). I don't think the rest of GDAL cares about SIGPIPE, but an application using GDAL might... We should probably have a GDAL_CURL_NOSIGNAL config option that an application could set so that GDAL doesn't try to mess with curl/openssl related signals...
Sorry, been tied up with some other stuff. Thanks — I'll roll that change into an app build and let you know whether it eliminates it.
What is the bug?
We've recently run into a new curl/libssl/SIGPIPE issue with gdalwarp:
In this case
in.vrt
is a VRT around a single RGB GTiff on S3 via/vsis3/
and the VRT applies a CRS transform. It gets right to the end of the warp, outputs 100% progress, and then gets a SIGPIPE and quits (13
).This doesn't happen reliably, but often enough doing hundreds of warps. Seems to help when the node is under load or doing many such warps in parallel.
Backtrace from GDB
Steps to reproduce the issue
The libcurl thread safety docs have:
Which is fine, GDAL sets
CURLOPT_NOSIGNAL=1
and has its ownCPLHTTPIgnoreSigPipe()
andCPLHTTPRestoreSigPipeHandler()
. The last sentence above was added after GDAL's handlers were written.Poking about in
cpl_vsil_curl.cpp
...SIGPIPE
handler across multiple threads? But that doesn't seem like the exact issue we're encountering.curl_multi_cleanup()
is called afterCPLHTTPRestoreSigPipeHandler()
inVSICurlHandle::AdviseRead()
SIGPIPE
handling inCachedConnection::clear()
or callerscurl_easy_cleanup()
calls which don't appear to be wrapped either.I don't know whether it's simpler just to save/restore one handler when curl is active, but I'm maybe missing some context where
SIGPIPE
is used elsewhere?Versions and provenance
Additional context
No response