aboutsummaryrefslogtreecommitdiff
path: root/src/common/linux
diff options
context:
space:
mode:
authorLi Yan <lyan@chromium.org>2016-03-30 13:46:21 -0700
committerLi Yan <lyan@chromium.org>2016-03-30 13:46:21 -0700
commitc77c51fae6796fbe86ecafd6136ef9503251c035 (patch)
tree14a97e8013432c3aad82d7c95c35d96c592488cc /src/common/linux
parentMake EXC_BAD_ACCESS / EXC_I386_GPFLT print nicely in the processor (diff)
downloadbreakpad-c77c51fae6796fbe86ecafd6136ef9503251c035.tar.xz
Refactor sym_upload in tools to extract code into common/linux, and minor fixes
to code calling libcurl. This change may be used to build a tool to dump and upload symbols with multi-thread. BUG= R=mmandlis@chromium.org CC=google-breakpad-dev@googlegroups.com Review URL: https://codereview.chromium.org/1842113002 .
Diffstat (limited to 'src/common/linux')
-rw-r--r--src/common/linux/http_upload.cc15
-rw-r--r--src/common/linux/http_upload.h3
-rw-r--r--src/common/linux/symbol_upload.cc155
-rw-r--r--src/common/linux/symbol_upload.h59
4 files changed, 231 insertions, 1 deletions
diff --git a/src/common/linux/http_upload.cc b/src/common/linux/http_upload.cc
index 4492fe84..702526af 100644
--- a/src/common/linux/http_upload.cc
+++ b/src/common/linux/http_upload.cc
@@ -72,7 +72,9 @@ bool HTTPUpload::SendRequest(const string &url,
// 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 (!curl_lib || dlsym(curl_lib, "curl_easy_init") == NULL) {
+ 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;
@@ -113,6 +115,10 @@ bool HTTPUpload::SendRequest(const string &url,
*(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);
+ // 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
+ (*curl_easy_setopt)(curl, CURLOPT_NOSIGNAL, 1);
// Set proxy information if necessary.
if (!proxy.empty())
(*curl_easy_setopt)(curl, CURLOPT_PROXY, proxy.c_str());
@@ -198,6 +204,13 @@ bool HTTPUpload::SendRequest(const string &url,
}
// static
+bool HTTPUpload::CheckCurlLib(void* curl_lib) {
+ return curl_lib &&
+ dlsym(curl_lib, "curl_easy_init") &&
+ dlsym(curl_lib, "curl_easy_setopt");
+}
+
+// static
bool HTTPUpload::CheckParameters(const map<string, string> &parameters) {
for (map<string, string>::const_iterator pos = parameters.begin();
pos != parameters.end(); ++pos) {
diff --git a/src/common/linux/http_upload.h b/src/common/linux/http_upload.h
index 4f0e452f..bc1d5d57 100644
--- a/src/common/linux/http_upload.h
+++ b/src/common/linux/http_upload.h
@@ -74,6 +74,9 @@ class HTTPUpload {
// any quote (") characters. Returns true if so.
static bool CheckParameters(const map<string, string> &parameters);
+ // Checks the curl_lib parameter points to a valid curl lib.
+ static bool CheckCurlLib(void* curl_lib);
+
// No instances of this class should be created.
// Disallow all constructors, destructors, and operator=.
HTTPUpload();
diff --git a/src/common/linux/symbol_upload.cc b/src/common/linux/symbol_upload.cc
new file mode 100644
index 00000000..bbd3181e
--- /dev/null
+++ b/src/common/linux/symbol_upload.cc
@@ -0,0 +1,155 @@
+// Copyright (c) 2011 Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// symbol_upload.cc: implemented google_breakpad::sym_upload::Start, a helper
+// function for linux symbol upload tool.
+
+#include "common/linux/http_upload.h"
+#include "common/linux/symbol_upload.h"
+
+#include <assert.h>
+#include <stdio.h>
+
+#include <functional>
+#include <vector>
+
+namespace google_breakpad {
+namespace sym_upload {
+
+void TokenizeByChar(const string &source_string, int c,
+ std::vector<string> *results) {
+ assert(results);
+ string::size_type cur_pos = 0, next_pos = 0;
+ while ((next_pos = source_string.find(c, cur_pos)) != string::npos) {
+ if (next_pos != cur_pos)
+ results->push_back(source_string.substr(cur_pos, next_pos - cur_pos));
+ cur_pos = next_pos + 1;
+ }
+ if (cur_pos < source_string.size() && next_pos != cur_pos)
+ results->push_back(source_string.substr(cur_pos));
+}
+
+//=============================================================================
+// Parse out the module line which have 5 parts.
+// MODULE <os> <cpu> <uuid> <module-name>
+bool ModuleDataForSymbolFile(const string &file,
+ std::vector<string> *module_parts) {
+ assert(module_parts);
+ const size_t kModulePartNumber = 5;
+ FILE* fp = fopen(file.c_str(), "r");
+ if (fp) {
+ char buffer[1024];
+ if (fgets(buffer, sizeof(buffer), fp)) {
+ string line(buffer);
+ string::size_type line_break_pos = line.find_first_of('\n');
+ if (line_break_pos == string::npos) {
+ assert(0 && "The file is invalid!");
+ fclose(fp);
+ return false;
+ }
+ line.resize(line_break_pos);
+ const char kDelimiter = ' ';
+ TokenizeByChar(line, kDelimiter, module_parts);
+ if (module_parts->size() != kModulePartNumber)
+ module_parts->clear();
+ }
+ fclose(fp);
+ }
+
+ return module_parts->size() == kModulePartNumber;
+}
+
+//=============================================================================
+string CompactIdentifier(const string &uuid) {
+ std::vector<string> components;
+ TokenizeByChar(uuid, '-', &components);
+ string result;
+ for (size_t i = 0; i < components.size(); ++i)
+ result += components[i];
+ return result;
+}
+
+//=============================================================================
+void Start(Options *options) {
+ std::map<string, string> parameters;
+ options->success = false;
+ std::vector<string> module_parts;
+ if (!ModuleDataForSymbolFile(options->symbolsPath, &module_parts)) {
+ fprintf(stderr, "Failed to parse symbol file!\n");
+ return;
+ }
+
+ string compacted_id = CompactIdentifier(module_parts[3]);
+
+ // Add parameters
+ if (!options->version.empty())
+ parameters["version"] = options->version;
+
+ // MODULE <os> <cpu> <uuid> <module-name>
+ // 0 1 2 3 4
+ parameters["os"] = module_parts[1];
+ parameters["cpu"] = module_parts[2];
+ parameters["debug_file"] = module_parts[4];
+ parameters["code_file"] = module_parts[4];
+ parameters["debug_identifier"] = compacted_id;
+
+ std::map<string, string> files;
+ files["symbol_file"] = options->symbolsPath;
+
+ string response, error;
+ long response_code;
+ bool success = HTTPUpload::SendRequest(options->uploadURLStr,
+ parameters,
+ files,
+ options->proxy,
+ options->proxy_user_pwd,
+ "",
+ &response,
+ &response_code,
+ &error);
+
+ if (!success) {
+ printf("Failed to send symbol file: %s\n", error.c_str());
+ printf("Response code: %ld\n", response_code);
+ printf("Response:\n");
+ printf("%s\n", response.c_str());
+ } else if (response_code == 0) {
+ printf("Failed to send symbol file: No response code\n");
+ } else if (response_code != 200) {
+ printf("Failed to send symbol file: Response code %ld\n", response_code);
+ printf("Response:\n");
+ printf("%s\n", response.c_str());
+ } else {
+ printf("Successfully sent the symbol file.\n");
+ }
+ options->success = success;
+}
+
+} // namespace sym_upload
+} // namespace google_breakpad
diff --git a/src/common/linux/symbol_upload.h b/src/common/linux/symbol_upload.h
new file mode 100644
index 00000000..0a469692
--- /dev/null
+++ b/src/common/linux/symbol_upload.h
@@ -0,0 +1,59 @@
+// -*- mode: c++ -*-
+
+// Copyright (c) 2011 Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// symbol_upload.h: helper functions for linux symbol upload tool.
+
+#ifndef COMMON_LINUX_SYMBOL_UPLOAD_H_
+#define COMMON_LINUX_SYMBOL_UPLOAD_H_
+
+#include <string>
+
+#include "common/using_std_string.h"
+
+namespace google_breakpad {
+namespace sym_upload {
+
+typedef struct {
+ string symbolsPath;
+ string uploadURLStr;
+ string proxy;
+ string proxy_user_pwd;
+ string version;
+ bool success;
+} Options;
+
+// Starts upload to symbol server with options.
+void Start(Options* options);
+
+} // namespace sym_upload
+} // namespace google_breakpad
+
+#endif // COMMON_LINUX_SYMBOL_UPLOAD_H_