From b1d502ae57e6ef3538318e72fc925f28b4e1b48a Mon Sep 17 00:00:00 2001 From: Jon Turney Date: Sat, 5 Mar 2016 12:48:05 +0000 Subject: [PATCH 02/19] Link minidump_upload and sym_upload with curl Don't link with -ldl and use dlopen to use libcurl.so, but just link with libcurl This has the advantage of not needing to know the precise name of the curl shared object on every platform... This effectively reverts commit 68b4798e See also https://bugs.chromium.org/p/google-breakpad/issues/detail?id=225 XXX: Perhaps retaining linking with -dl and just teaching it the name of curl shared object on Cygwin would be more upstreamable, although the reasons for solving the bug above like this are obscure to me ... Signed-off-by: Jon Turney --- Makefile.am | 4 +- src/common/linux/http_upload.cc | 101 ++++++-------------------------- 2 files changed, 21 insertions(+), 84 deletions(-) diff --git a/Makefile.am b/Makefile.am index dcef735d..904a9a77 100644 --- a/Makefile.am +++ b/Makefile.am @@ -610,7 +610,7 @@ src_tools_linux_md2core_minidump_2_core_SOURCES = \ src_tools_linux_symupload_minidump_upload_SOURCES = \ src/common/linux/http_upload.cc \ src/tools/linux/symupload/minidump_upload.cc -src_tools_linux_symupload_minidump_upload_LDADD = -ldl +src_tools_linux_symupload_minidump_upload_LDADD = -lcurl src_tools_linux_symupload_sym_upload_SOURCES = \ src/common/linux/http_upload.cc \ @@ -618,7 +618,7 @@ src_tools_linux_symupload_sym_upload_SOURCES = \ src/common/linux/symbol_upload.cc \ src/common/linux/symbol_upload.h \ src/tools/linux/symupload/sym_upload.cc -src_tools_linux_symupload_sym_upload_LDADD = -ldl +src_tools_linux_symupload_sym_upload_LDADD = -lcurl src_tools_mac_dump_syms_dump_syms_mac_SOURCES = \ src/common/dwarf_cfi_to_module.cc \ diff --git a/src/common/linux/http_upload.cc b/src/common/linux/http_upload.cc index c62b0cf0..3d215810 100644 --- a/src/common/linux/http_upload.cc +++ b/src/common/linux/http_upload.cc @@ -30,7 +30,6 @@ #include "common/linux/http_upload.h" #include -#include #include #include @@ -70,52 +69,13 @@ bool HTTPUpload::SendRequest(const string &url, if (!CheckParameters(parameters)) return false; - // We may have been linked statically; if curl_easy_init is in the - // current binary, no need to search for a dynamic version. - void* curl_lib = dlopen(NULL, RTLD_NOW); - if (!CheckCurlLib(curl_lib)) { - fprintf(stderr, - "Failed to open curl lib from binary, use libcurl.so instead\n"); - dlerror(); // Clear dlerror before attempting to open libraries. - dlclose(curl_lib); - curl_lib = NULL; - } - if (!curl_lib) { - curl_lib = dlopen("libcurl.so", RTLD_NOW); - } - if (!curl_lib) { - if (error_description != NULL) - *error_description = dlerror(); - curl_lib = dlopen("libcurl.so.4", RTLD_NOW); - } - if (!curl_lib) { - // Debian gives libcurl a different name when it is built against GnuTLS - // instead of OpenSSL. - curl_lib = dlopen("libcurl-gnutls.so.4", RTLD_NOW); - } - if (!curl_lib) { - curl_lib = dlopen("libcurl.so.3", RTLD_NOW); - } - if (!curl_lib) { - return false; - } - - CURL* (*curl_easy_init)(void); - *(void**) (&curl_easy_init) = dlsym(curl_lib, "curl_easy_init"); - CURL *curl = (*curl_easy_init)(); + CURL *curl = curl_easy_init(); if (error_description != NULL) *error_description = "No Error"; - if (!curl) { - dlclose(curl_lib); - return false; - } - CURLcode err_code = CURLE_OK; - CURLcode (*curl_easy_setopt)(CURL *, CURLoption, ...); - *(void**) (&curl_easy_setopt) = dlsym(curl_lib, "curl_easy_setopt"); - (*curl_easy_setopt)(curl, CURLOPT_URL, url.c_str()); - (*curl_easy_setopt)(curl, CURLOPT_USERAGENT, kUserAgent); + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_USERAGENT, kUserAgent); // Support multithread by disabling timeout handling, would get SIGSEGV with // Curl_resolv_timeout in stack trace otherwise. // See https://curl.haxx.se/libcurl/c/threadsafe.html @@ -132,83 +92,60 @@ bool HTTPUpload::SendRequest(const string &url, struct curl_httppost *formpost = NULL; struct curl_httppost *lastptr = NULL; // Add form data. - CURLFORMcode (*curl_formadd)(struct curl_httppost **, struct curl_httppost **, ...); - *(void**) (&curl_formadd) = dlsym(curl_lib, "curl_formadd"); map::const_iterator iter = parameters.begin(); for (; iter != parameters.end(); ++iter) - (*curl_formadd)(&formpost, &lastptr, + curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, iter->first.c_str(), CURLFORM_COPYCONTENTS, iter->second.c_str(), CURLFORM_END); // Add form files. for (iter = files.begin(); iter != files.end(); ++iter) { - (*curl_formadd)(&formpost, &lastptr, + curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, iter->first.c_str(), CURLFORM_FILE, iter->second.c_str(), CURLFORM_END); } - (*curl_easy_setopt)(curl, CURLOPT_HTTPPOST, formpost); + curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); // Disable 100-continue header. struct curl_slist *headerlist = NULL; char buf[] = "Expect:"; - struct curl_slist* (*curl_slist_append)(struct curl_slist *, const char *); - *(void**) (&curl_slist_append) = dlsym(curl_lib, "curl_slist_append"); - headerlist = (*curl_slist_append)(headerlist, buf); - (*curl_easy_setopt)(curl, CURLOPT_HTTPHEADER, headerlist); + headerlist = curl_slist_append(headerlist, buf); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); if (response_body != NULL) { - (*curl_easy_setopt)(curl, CURLOPT_WRITEFUNCTION, WriteCallback); - (*curl_easy_setopt)(curl, CURLOPT_WRITEDATA, + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, reinterpret_cast(response_body)); } // Fail if 400+ is returned from the web server. - (*curl_easy_setopt)(curl, CURLOPT_FAILONERROR, 1); + curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1); - CURLcode (*curl_easy_perform)(CURL *); - *(void**) (&curl_easy_perform) = dlsym(curl_lib, "curl_easy_perform"); - err_code = (*curl_easy_perform)(curl); + err_code = curl_easy_perform(curl); if (response_code != NULL) { - CURLcode (*curl_easy_getinfo)(CURL *, CURLINFO, ...); - *(void**) (&curl_easy_getinfo) = dlsym(curl_lib, "curl_easy_getinfo"); - (*curl_easy_getinfo)(curl, CURLINFO_RESPONSE_CODE, response_code); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, response_code); } - const char* (*curl_easy_strerror)(CURLcode); - *(void**) (&curl_easy_strerror) = dlsym(curl_lib, "curl_easy_strerror"); #ifndef NDEBUG if (err_code != CURLE_OK) fprintf(stderr, "Failed to send http request to %s, error: %s\n", url.c_str(), - (*curl_easy_strerror)(err_code)); + curl_easy_strerror(err_code)); #endif if (error_description != NULL) - *error_description = (*curl_easy_strerror)(err_code); + *error_description = curl_easy_strerror(err_code); - void (*curl_easy_cleanup)(CURL *); - *(void**) (&curl_easy_cleanup) = dlsym(curl_lib, "curl_easy_cleanup"); - (*curl_easy_cleanup)(curl); + curl_easy_cleanup(curl); if (formpost != NULL) { - void (*curl_formfree)(struct curl_httppost *); - *(void**) (&curl_formfree) = dlsym(curl_lib, "curl_formfree"); - (*curl_formfree)(formpost); + curl_formfree(formpost); } if (headerlist != NULL) { - void (*curl_slist_free_all)(struct curl_slist *); - *(void**) (&curl_slist_free_all) = dlsym(curl_lib, "curl_slist_free_all"); - (*curl_slist_free_all)(headerlist); + curl_slist_free_all(headerlist); } - dlclose(curl_lib); - return err_code == CURLE_OK; -} -// static -bool HTTPUpload::CheckCurlLib(void* curl_lib) { - return curl_lib && - dlsym(curl_lib, "curl_easy_init") && - dlsym(curl_lib, "curl_easy_setopt"); + return err_code == CURLE_OK; } // static -- 2.28.0