[pacman-dev] segfault after curl_easy_cleanup via progress callback

Dan McGee dpmcgee at gmail.com
Wed Aug 10 20:15:49 EDT 2011

On Wed, Aug 10, 2011 at 5:48 PM, Dave Reisner <d at falconindy.com> wrote:
> Hi all,
> I received a bug report with backtrace [1] for a curl powered app that I
> work on. It shows a segfault in a progress callback, which is triggered
> _after_ curl_easy_cleanup has been called. Unfortunately, I can't
> reproduce this, and it's still a development version of pacman with a
> limited userbase. There's a half dozen devs using this on a daily basis,
> and this is a routine operation that one of us would have surely run
> into by now.
> That said, the bug reporter was able to find another bug report[2] with
> a very similar backtrace. Note that this bug report uses an earlier
> version of curl, I believe 7.20, while we're using 7.21.7.
> The documentation for curl_easy_cleanup states that further calls to the
> handle are invalid after this call so I'm a bit confused as to why curl
> would be hitting the progress callback at this point. This indirectly
> _insists_ that the application touches the handle. Am I misunderstanding
> the expectation of curl_easy_cleanup that it's _possible_ due to an
> unfinished transfer that the progress callback may be hit one final
> time?
> In case it's relevant, I'll point to the where the majority of our curl
> implementation lies [3], but I'm somewhat confident that pacman "does
> the right thing" here.
> If anyone can point me in the right direction, I've be hugely
> appreciative.
> Thanks,
> Dave Reisner
> [1] http://pastebin.com/Pef1Qedq
> [2] http://www.crosswire.org/bugs/browse/API-128
> [3] https://github.com/falconindy/pacman/blob/master/lib/libalpm/dload.c#L180

Took a stab at this. Taking the stacktrace from [1], the only missing
values that make sense and I can reconstruct are like the following:
#1  0xb7dd8776 in Curl_pgrsUpdate () from /usr/lib/libcurl.so.4
#2  0xb7e12275 in Curl_pp_easy_statemach () from /usr/lib/libcurl.so.4
#3  0xb7de2088 in ?? () from /usr/lib/libcurl.so.4 (***ftp_easy_statemach)
#4  0xb7de21a9 in ?? () from /usr/lib/libcurl.so.4 (***ftp_quit
inlined in ftp_disconnect)
#5  0xb7de8547 in Curl_disconnect () from /usr/lib/libcurl.so.4#1
0xb7dd8776 in Curl_pgrsUpdate () from /usr/lib/libcurl.so.4

I don't see anywhere we explicitly disconnect progress meters from
connections, so my stab at that is below. I still think there is some
sort of underlying state machine problem though as we shouldn't ever
be calling progress from the state where we are calling QUIT on an FTP

-Dan McGee

$ git diff | cat
diff --git a/lib/url.c b/lib/url.c
index f888c1d..c9d4bc9 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -435,6 +435,9 @@ CURLcode Curl_close(struct SessionHandle *data)

   Curl_expire(data, 0); /* shut off timers */
+  /* disconnect any progress callback */
+  data->set.fprogress = NULL;
+  data->progress.callback = FALSE;

     /* This handle is still part of a multi handle, take care of this first

More information about the pacman-dev mailing list