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.
Re: valgrind drd shows potential data race in curl_easy_init
- Contemporary messages sorted: [ by date ] [ by thread ] [ by subject ] [ by author ] [ by messages with attachments ]
From: Henrik Holst via curl-library <curl-library_at_lists.haxx.se>
Date: Thu, 20 Nov 2025 07:13:02 +0100
well that is good :). Hard to say without knowing which row in curl that is
throwing this error in valgrind since it only gives back the local memory
address. Don't know if there is any way to install debuginfo for libcurl on
Ubuntu, in any case since the warning is for a load of size 4 and you get
this with the correct example code as well I would say that this is
probably loading some shared variable somewhere that is set
by curl_global_init() and which is therefore safe to load afterwards since
it is never changed but valgrind does not know this and only sees that
multiple threads can read it at the same time.
/HH
Den tors 20 nov. 2025 kl 01:52 skrev Aman Grewal <aman_at_atakama.com>:
> I'm calling it. This is a minimal example where I'm able to reproduce it.
>
> ```
> #include <pthread.h>
> #include <stdlib.h>
> #include <string.h>
> #include <unistd.h>
>
> #include <curl/curl.h>
>
> static pthread_t thread1;
> static pthread_t thread2;
>
> struct storage {
> char *response;
> size_t size;
> };
>
> size_t cb_for_curl_easy_perform(char *data, size_t size, size_t nmemb,
> void *storage) {
> size_t realsize = size * nmemb;
> struct storage *mem = (struct storage *)storage;
>
> char *ptr = realloc(mem->response, mem->size + realsize + 1);
>
> mem->response = ptr;
> memcpy(&(mem->response[mem->size]), data, realsize);
> mem->size += realsize;
> mem->response[mem->size] = 0;
>
> return realsize;
> }
>
> void *thread_func(void *arg __attribute__((unused))) {
> for (int i = 0; i < 2; ++i) {
> CURL *handle = curl_easy_init();
> CURLcode res = curl_easy_setopt(handle, CURLOPT_URL, "
> http://localhost:8888/test.c");
> res = curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION,
> cb_for_curl_easy_perform);
> struct storage resp = { .response = NULL, .size = 0 };
> res = curl_easy_setopt(handle, CURLOPT_WRITEDATA, &resp);
> res = curl_easy_perform(handle);
> curl_easy_cleanup(handle);
> }
> }
>
> int main(int argc, char** argv) {
> printf("HELLO, WORLD!\n");
> fflush(stdout);
> curl_global_init(CURL_GLOBAL_NOTHING);
> pthread_create(&thread1, NULL, thread_func, NULL);
> pthread_create(&thread2, NULL, thread_func, NULL);
> pthread_join(thread1, NULL);
> pthread_join(thread2, NULL);
> printf("GOODBYE, WORLD!\n");
> fflush(stdout);
> }
> ```
>
>
> On Wed, Nov 19, 2025 at 6:43 PM Henrik Holst <henrik.holst_at_millistream.com>
> wrote:
>
>> looks like you don't call curl_global_init() before starting your threads
>>
>> /HH
>>
>> Den tors 20 nov. 2025 kl 00:36 skrev Aman Grewal via curl-library <
>> curl-library_at_lists.haxx.se>:
>>
>>> Hi all,
>>>
>>> I'm running my library under valgrind to try to find any bugs. I'm
>>> seeing this warning stemming from `curl_easy_init` when running drd.
>>>
>>> Command: `valgrind --tool=drd --read-var-info=yes --check-stack-var=yes
>>> --free-is-write=yes -s --gen-suppressions=all /test`
>>>
>>> Truncated Output:
>>> ==8== Thread 3:
>>> ==8== Conflicting load by thread 3 at 0x04949724 size 4
>>> ==8== at 0x48B8FA2: curl_easy_init (in
>>> /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.8.0)
>>> ==8== by 0x40014C1: thread_func (test.c:33)
>>> ==8== by 0x485B948: vgDrd_thread_wrapper
>>> (drd_pthread_intercepts.c:512)
>>> ==8== by 0x49E6AA3: start_thread (pthread_create.c:447)
>>> ==8== by 0x4A73A63: clone (clone.S:100)
>>> ==8== Allocation context: BSS section of
>>> /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.8.0
>>> ==8== Other segment start (thread 2)
>>> ==8== at 0x4A73A56: clone (clone.S:83)
>>> ==8== by 0x49E671F: ??? (allocatestack.c:605)
>>> ==8== by 0x67036BF: ???
>>> ==8== Other segment end (thread 2)
>>> ==8== at 0x4A759DB: connect (connect.c:26)
>>> ==8== by 0x48A7DEC: ??? (in
>>> /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.8.0)
>>> ==8== by 0x48B42E7: ??? (in
>>> /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.8.0)
>>> ==8== by 0x48B517F: ??? (in
>>> /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.8.0)
>>> ==8== by 0x48A8FC5: ??? (in
>>> /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.8.0)
>>> ==8== by 0x48EAED7: ??? (in
>>> /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.8.0)
>>> ==8== by 0x48ED5D9: curl_multi_perform (in
>>> /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.8.0)
>>> ==8== by 0x48BBE3A: curl_easy_perform (in
>>> /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.8.0)
>>> ==8== by 0x4001553: thread_func (test.c:38)
>>> ==8== by 0x485B948: vgDrd_thread_wrapper
>>> (drd_pthread_intercepts.c:512)
>>> ==8== by 0x49E6AA3: start_thread (pthread_create.c:447)
>>> ==8== by 0x4A73A63: clone (clone.S:100)
>>> ==8==
>>>
>>> When I run the same valgrind command on the sample code in
>>> https://curl.se/libcurl/c/threaded-ssl.html, I see similar warnings, so
>>> I'm hoping this is a spurious warning. Has anyone seen this before? Is it
>>> safe to add it to my suppressions file?
>>>
>>>
>>> I'm running this on Ubuntu 24.04 (LTS), and I'm using the libcurl3t64-gnutls
>>> package.
>>>
>>>
>>>
>>> Thanks,
>>> Aman Grewal
>>>
>>>
>>>
>>> --
>>> Unsubscribe: https://lists.haxx.se/mailman/listinfo/curl-library
>>> Etiquette: https://curl.se/mail/etiquette.html
>>>
>>
Date: Thu, 20 Nov 2025 07:13:02 +0100
well that is good :). Hard to say without knowing which row in curl that is
throwing this error in valgrind since it only gives back the local memory
address. Don't know if there is any way to install debuginfo for libcurl on
Ubuntu, in any case since the warning is for a load of size 4 and you get
this with the correct example code as well I would say that this is
probably loading some shared variable somewhere that is set
by curl_global_init() and which is therefore safe to load afterwards since
it is never changed but valgrind does not know this and only sees that
multiple threads can read it at the same time.
/HH
Den tors 20 nov. 2025 kl 01:52 skrev Aman Grewal <aman_at_atakama.com>:
> I'm calling it. This is a minimal example where I'm able to reproduce it.
>
> ```
> #include <pthread.h>
> #include <stdlib.h>
> #include <string.h>
> #include <unistd.h>
>
> #include <curl/curl.h>
>
> static pthread_t thread1;
> static pthread_t thread2;
>
> struct storage {
> char *response;
> size_t size;
> };
>
> size_t cb_for_curl_easy_perform(char *data, size_t size, size_t nmemb,
> void *storage) {
> size_t realsize = size * nmemb;
> struct storage *mem = (struct storage *)storage;
>
> char *ptr = realloc(mem->response, mem->size + realsize + 1);
>
> mem->response = ptr;
> memcpy(&(mem->response[mem->size]), data, realsize);
> mem->size += realsize;
> mem->response[mem->size] = 0;
>
> return realsize;
> }
>
> void *thread_func(void *arg __attribute__((unused))) {
> for (int i = 0; i < 2; ++i) {
> CURL *handle = curl_easy_init();
> CURLcode res = curl_easy_setopt(handle, CURLOPT_URL, "
> http://localhost:8888/test.c");
> res = curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION,
> cb_for_curl_easy_perform);
> struct storage resp = { .response = NULL, .size = 0 };
> res = curl_easy_setopt(handle, CURLOPT_WRITEDATA, &resp);
> res = curl_easy_perform(handle);
> curl_easy_cleanup(handle);
> }
> }
>
> int main(int argc, char** argv) {
> printf("HELLO, WORLD!\n");
> fflush(stdout);
> curl_global_init(CURL_GLOBAL_NOTHING);
> pthread_create(&thread1, NULL, thread_func, NULL);
> pthread_create(&thread2, NULL, thread_func, NULL);
> pthread_join(thread1, NULL);
> pthread_join(thread2, NULL);
> printf("GOODBYE, WORLD!\n");
> fflush(stdout);
> }
> ```
>
>
> On Wed, Nov 19, 2025 at 6:43 PM Henrik Holst <henrik.holst_at_millistream.com>
> wrote:
>
>> looks like you don't call curl_global_init() before starting your threads
>>
>> /HH
>>
>> Den tors 20 nov. 2025 kl 00:36 skrev Aman Grewal via curl-library <
>> curl-library_at_lists.haxx.se>:
>>
>>> Hi all,
>>>
>>> I'm running my library under valgrind to try to find any bugs. I'm
>>> seeing this warning stemming from `curl_easy_init` when running drd.
>>>
>>> Command: `valgrind --tool=drd --read-var-info=yes --check-stack-var=yes
>>> --free-is-write=yes -s --gen-suppressions=all /test`
>>>
>>> Truncated Output:
>>> ==8== Thread 3:
>>> ==8== Conflicting load by thread 3 at 0x04949724 size 4
>>> ==8== at 0x48B8FA2: curl_easy_init (in
>>> /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.8.0)
>>> ==8== by 0x40014C1: thread_func (test.c:33)
>>> ==8== by 0x485B948: vgDrd_thread_wrapper
>>> (drd_pthread_intercepts.c:512)
>>> ==8== by 0x49E6AA3: start_thread (pthread_create.c:447)
>>> ==8== by 0x4A73A63: clone (clone.S:100)
>>> ==8== Allocation context: BSS section of
>>> /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.8.0
>>> ==8== Other segment start (thread 2)
>>> ==8== at 0x4A73A56: clone (clone.S:83)
>>> ==8== by 0x49E671F: ??? (allocatestack.c:605)
>>> ==8== by 0x67036BF: ???
>>> ==8== Other segment end (thread 2)
>>> ==8== at 0x4A759DB: connect (connect.c:26)
>>> ==8== by 0x48A7DEC: ??? (in
>>> /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.8.0)
>>> ==8== by 0x48B42E7: ??? (in
>>> /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.8.0)
>>> ==8== by 0x48B517F: ??? (in
>>> /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.8.0)
>>> ==8== by 0x48A8FC5: ??? (in
>>> /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.8.0)
>>> ==8== by 0x48EAED7: ??? (in
>>> /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.8.0)
>>> ==8== by 0x48ED5D9: curl_multi_perform (in
>>> /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.8.0)
>>> ==8== by 0x48BBE3A: curl_easy_perform (in
>>> /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.8.0)
>>> ==8== by 0x4001553: thread_func (test.c:38)
>>> ==8== by 0x485B948: vgDrd_thread_wrapper
>>> (drd_pthread_intercepts.c:512)
>>> ==8== by 0x49E6AA3: start_thread (pthread_create.c:447)
>>> ==8== by 0x4A73A63: clone (clone.S:100)
>>> ==8==
>>>
>>> When I run the same valgrind command on the sample code in
>>> https://curl.se/libcurl/c/threaded-ssl.html, I see similar warnings, so
>>> I'm hoping this is a spurious warning. Has anyone seen this before? Is it
>>> safe to add it to my suppressions file?
>>>
>>>
>>> I'm running this on Ubuntu 24.04 (LTS), and I'm using the libcurl3t64-gnutls
>>> package.
>>>
>>>
>>>
>>> Thanks,
>>> Aman Grewal
>>>
>>>
>>>
>>> --
>>> Unsubscribe: https://lists.haxx.se/mailman/listinfo/curl-library
>>> Etiquette: https://curl.se/mail/etiquette.html
>>>
>>
-- Unsubscribe: https://lists.haxx.se/mailman/listinfo/curl-library Etiquette: https://curl.se/mail/etiquette.htmlReceived on 2025-11-20