Discussion:
Correct use of curl_easy_getinfo
Till Elsner
2011-12-05 12:45:30 UTC
Permalink
Hi,

I keep running into trouble with using curl_easy_getinfo:
I'm using the same CURL handle for multiple connections. Before
every new connection request, I reset the handle using
curl_easy_reset. Afterwards, I set the options for the handle
using curl_easy_setopt (CURLOPT_URL, CURLOPT_FOLLOWLOCATION to
1, CURLOPT_WRITEFUNCTION, CURLOPT_WRITEDATA,
CURLOPT_ERRORBUFFER) and call curl_easy_perform. So far, this
works fine. But when I call curl_easy_getinfo on the handle
after having fetched the site to get the effective URL, I still
works for the FIRST connection. However, on the next connection
using the same handle, the program receives segmentation fault
while performing curl_easy_perform. The following backtrace from
gdb shows what's going on (or does it?):

#0 0x00007ffff740d933 in malloc_consolidate () from
/lib64/libc.so.6
#1 0x00007ffff740f655 in _int_malloc () from /lib64/libc.so.6
#2 0x00007ffff7413222 in calloc () from /lib64/libc.so.6
#3 0x00007ffff7b8a25b in allocate_conn (data=0x6a0be0) at
url.c:3527
#4 0x00007ffff7b8c43e in create_conn (data=0x6a0be0,
in_connect=0x7fffffffdd58, async=0x7fffffffdd0b) at url.c:4719
#5 0x00007ffff7b8cf3c in Curl_connect (data=0x6a0be0,
in_connect=0x7fffffffdd58, asyncp=0x7fffffffdd0b,
protocol_done=0x7fffffffdd0a) at url.c:5148
#6 0x00007ffff7b9ca18 in connect_host (data=0x6a0be0,
conn=0x7fffffffdd58) at transfer.c:1971
#7 0x00007ffff7b9ccf7 in Curl_do_perform (data=0x6a0be0) at
transfer.c:2105
#8 0x00007ffff7b9d067 in Curl_perform (data=0x6a0be0) at
transfer.c:2251
#9 0x00007ffff7b9d9de in curl_easy_perform (curl=0x6a0be0) at
easy.c:567
#10 0x000000000040336e in open_url (url=0x6dc4e0 "code/",
curl=0x6a0be0) at url.c:25
#11 0x00000000004020b6 in main (argc=2, argv=0x7fffffffe078) at
main.c:209

(Don't get confused by url.c in #10, this is from my own source
code, it's not the url.c from libcurl).

Where is my mistake? How is libcurl (curl_easy_getinfo) used
correctly?

Thanks and regards
Till
--
Till Elsner []
***@0xAA55.org (Email & XMPP) []
irc.0xaa55.org #praty [][][]

############################## GPG ###############################
# KeyID=0xFCFF4656 #
# fingerprint: 1A1E 3B61 6956 07E3 2CB8 D0F8 791F 52F8 FCFF 4656 #
##################################################################

() ascii ribbon campaign - against html e-mail
/\ www.asciiribbon.org - against proprietary attachments
Daniel Stenberg
2011-12-05 14:35:03 UTC
Permalink
But when I call curl_easy_getinfo on the handle after having fetched the
site to get the effective URL, I still works for the FIRST connection.
However, on the next connection using the same handle, the program receives
segmentation fault while performing curl_easy_perform.
Are you using a recent libcurl version?

Any chance you can provide source code to a little example we can use to
repeat this problem?
--
/ daniel.haxx.se
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Till Elsner
2011-12-05 15:08:33 UTC
Permalink
Post by Daniel Stenberg
But when I call curl_easy_getinfo on the handle after having fetched the
site to get the effective URL, I still works for the FIRST connection.
However, on the next connection using the same handle, the program receives
segmentation fault while performing curl_easy_perform.
Are you using a recent libcurl version?
I'm using 7.21.4.
Post by Daniel Stenberg
Any chance you can provide source code to a little example we can use to
repeat this problem?
Basically, the function I use to retrieve a URL is the
following:

01 struct doc_info_st *open_url(const char *url, CURL *curl)
02 {
03 struct doc_info_st *doc_info=doc_info_init();
04 curl_easy_reset(curl);
05 /* prepare error buffer */
06 doc_info->error=(char *)malloc(CURL_ERROR_SIZE);
07 memset(doc_info->error, 0, CURL_ERROR_SIZE);
08 /* fetch content: prepare cURL handler */
09 curl_easy_setopt(curl, CURLOPT_URL, url);
10 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
11 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &curl_write);
12 curl_easy_setopt(curl, CURLOPT_WRITEDATA, doc_info);
13 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, doc_info->error);
14 /* ...fire */
15 doc_info->loaded=1;
16 if (curl_easy_perform(curl)!=0)
17 {
18 doc_info->loaded=0;
19 }
20 else {
21 /* set url */
22 curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &doc_info->url);
23 /* parse source */
24 if (parse_html(doc_info)==-1)
25 {
26 doc_info->loaded=0;
27 memcpy(doc_info->error, "Invalid HTML!", 14);
28 }
29 }
30 return doc_info;
31 }

Although segfault happens in line 16 on the second use, the problem *seems* to
be line 22, as the problem disappears if this line is removed.
Post by Daniel Stenberg
--
/ daniel.haxx.se
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
--
Till Elsner []
***@0xAA55.org (Email & XMPP) []
irc.0xaa55.org #praty [][][]

############################## GPG ###############################
# KeyID=0xFCFF4656 #
# fingerprint: 1A1E 3B61 6956 07E3 2CB8 D0F8 791F 52F8 FCFF 4656 #
##################################################################

() ascii ribbon campaign - against html e-mail
/\ www.asciiribbon.org - against proprietary attachments
Daniel Stenberg
2011-12-05 15:14:20 UTC
Permalink
21 /* set url */
22 curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &doc_info->url);
Ah.

CURLINFO_EFFECTIVE_URL returns a mere pointer to a buffer inside of the easy
handle.

When you reset that handle I would guess the pointer suddenly points to a
either something blank or to memory that previously was allocated and now are
freed.

You probably need to clone the data that pointer points to before you reset or
close the easy handle, then you can use that data to set the URL in the
subsequent request!
--
/ daniel.haxx.se
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Till Elsner
2011-12-05 17:30:14 UTC
Permalink
Post by Daniel Stenberg
21 /* set url */
22 curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &doc_info->url);
Ah.
CURLINFO_EFFECTIVE_URL returns a mere pointer to a buffer inside of the easy
handle.
When you reset that handle I would guess the pointer suddenly points to a
either something blank or to memory that previously was allocated and now are
freed.
So do I need to call curl_easy_init again on an easy handle that
I've resetted using curl_easy_reset? I thought the buffer for
the URL inside the handle would be allocated during
curl_easy_perform or something, maybe this is where I went
wrong.
Post by Daniel Stenberg
You probably need to clone the data that pointer points to before you reset or
close the easy handle, then you can use that data to set the URL in the
subsequent request!
By the time I call reset on the handle, I don't need the data
inside the handle any more. My only trouble is that a subsequent
call of curl_easy_perform on the same handle results in a
segmetation fault.
Post by Daniel Stenberg
--
/ daniel.haxx.se
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
--
Till Elsner []
***@0xAA55.org (Email & XMPP) []
irc.0xaa55.org #praty [][][]

############################## GPG ###############################
# KeyID=0xFCFF4656 #
# fingerprint: 1A1E 3B61 6956 07E3 2CB8 D0F8 791F 52F8 FCFF 4656 #
##################################################################

() ascii ribbon campaign - against html e-mail
/\ www.asciiribbon.org - against proprietary attachments
Daniel Stenberg
2011-12-05 18:03:47 UTC
Permalink
By the time I call reset on the handle, I don't need the data inside the
handle any more. My only trouble is that a subsequent call of
curl_easy_perform on the same handle results in a segmetation fault.
Then the problem is elsewhere.

It would help if you would provide a complete example I can compile and run to
see the problem, then I might be able to tell you more faster.
--
/ daniel.haxx.se
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Till Elsner
2011-12-06 00:28:40 UTC
Permalink
Post by Daniel Stenberg
By the time I call reset on the handle, I don't need the data inside the
handle any more. My only trouble is that a subsequent call of
curl_easy_perform on the same handle results in a segmetation fault.
Then the problem is elsewhere.
It would help if you would provide a complete example I can compile and run to
see the problem, then I might be able to tell you more faster.
Ok, problem has been solved in the meantime. The actual problem
was lying elsewhere, since I've corrupted memory at an earlier
place by freeing the buffer containing the URL before calling
curl_easy_reset, causing a double free on the URL buffer's
address. Kind of tricky to point out ;)

Thanks for your support anyway, sorry to keep you busy for no
reason^^
I guess at least I learned something about some libcurl
internals :D
Post by Daniel Stenberg
--
/ daniel.haxx.se
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
--
Till Elsner []
***@0xAA55.org (Email & XMPP) []
irc.0xaa55.org #praty [][][]

############################## GPG ###############################
# KeyID=0xFCFF4656 #
# fingerprint: 1A1E 3B61 6956 07E3 2CB8 D0F8 791F 52F8 FCFF 4656 #
##################################################################

() ascii ribbon campaign - against html e-mail
/\ www.asciiribbon.org - against proprietary attachments
Loading...