summaryrefslogtreecommitdiffstats
path: root/o3d/breakpad
diff options
context:
space:
mode:
authorzhurunz@google.com <zhurunz@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-22 05:41:50 +0000
committerzhurunz@google.com <zhurunz@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-22 05:41:50 +0000
commit1fcab653da84a27ca76229bcf94fdd799cbd40c6 (patch)
tree153bca8dd000bcea29cd7411f3f42e65a32841ed /o3d/breakpad
parent5e1ed6dcace94125b65e1061e2219672fda9ba1f (diff)
downloadchromium_src-1fcab653da84a27ca76229bcf94fdd799cbd40c6.zip
chromium_src-1fcab653da84a27ca76229bcf94fdd799cbd40c6.tar.gz
chromium_src-1fcab653da84a27ca76229bcf94fdd799cbd40c6.tar.bz2
Add breakpad.
Review URL: http://codereview.chromium.org/2092021 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@47987 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/breakpad')
-rw-r--r--o3d/breakpad/breakpad.gyp19
-rw-r--r--o3d/breakpad/linux/breakpad.cc215
-rw-r--r--o3d/breakpad/linux/breakpad.h129
3 files changed, 363 insertions, 0 deletions
diff --git a/o3d/breakpad/breakpad.gyp b/o3d/breakpad/breakpad.gyp
index 68e64ae..9623efd 100644
--- a/o3d/breakpad/breakpad.gyp
+++ b/o3d/breakpad/breakpad.gyp
@@ -68,6 +68,25 @@
],
},
],
+ ['OS=="linux"',
+ {
+ 'targets': [
+ {
+ 'target_name': 'o3dBreakpad',
+ 'type': 'static_library',
+ 'sources': [
+ 'linux/breakpad.cc',
+ 'linux/breakpad.h',
+ ],
+ 'direct_dependent_settings': {
+ 'include_dirs': [
+ '../../breakpad/src',
+ ],
+ },
+ },
+ ],
+ },
+ ],
],
}
diff --git a/o3d/breakpad/linux/breakpad.cc b/o3d/breakpad/linux/breakpad.cc
new file mode 100644
index 0000000..92656dd
--- /dev/null
+++ b/o3d/breakpad/linux/breakpad.cc
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2010, 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.
+ */
+
+#include "breakpad.h"
+
+#if defined(LINUX)
+#include <sys/stat.h>
+#endif // defined(LINUX)
+
+namespace o3d {
+#if defined(WIN32)
+static const std::string kBreakpadProduct = "Google_O3D_Plugin";
+#elif defined(OSX)
+static const std::string kBreakpadProduct = "Google_O3D_Plugin_Mac";
+#elif defined(LINUX)
+static const std::string kBreakpadProduct = "Google_O3D_Plugin_Linux";
+#endif
+static const std::string kBreakpadVersion = "unknown";
+static const std::string kBreakpadGUID = "unknown";
+static const std::string kBreakpadEmail = "unknown";
+#ifdef _DEBUG
+static const std::string kBreakpadServer =
+ "http://clients2.google.com/cr/staging_report";
+#else
+static const std::string kBreakpadServer =
+ "http://clients2.google.com/cr/report";
+#endif
+static const std::string kBreakpadDumpFilenameTemplate =
+ "/tmp/google-o3d-plugin-minidump-XXXXXX";
+
+//TODO(zhurunz): Add/use decent path utility functions.
+
+bool Breakpad::Initialize() {
+ if (NULL != breakpad_)
+ return true;
+
+ // Set default configuration.
+ set_product(kBreakpadProduct);
+ set_version(kBreakpadVersion);
+ set_guid(kBreakpadGUID);
+ set_email(kBreakpadEmail);
+ set_path("/tmp/");
+ set_server(kBreakpadServer);
+
+ // TODO(zhurunz): consider using HANDLE_CRASHES
+ // Setup callback.
+ breakpad_ = new
+ google_breakpad::ExceptionHandler(path_.c_str(),
+ NULL, /* filter callback */
+ BreakpadCallback,
+ this,
+ true /* install handlers */);
+
+ return (NULL != breakpad_);
+}
+
+bool Breakpad::Shutdown() {
+ delete breakpad_;
+ breakpad_ = NULL;
+ return true;
+}
+
+#if defined(LINUX)
+bool Breakpad::BuildDumpFilename(char* filename,
+ int len,
+ const char* dump_path,
+ const char* minidump_id) {
+ const int dump_path_len = strlen(dump_path);
+ const int minidump_id_len = strlen(minidump_id);
+ int len_needed = dump_path_len + minidump_id_len +
+ 4 /* ".dmp" */ + 1 /* NUL */;
+ if (len_needed > len)
+ return false;
+
+ filename[0] = '\0';
+ std::strcat(filename, dump_path);
+ std::strcat(filename, minidump_id);
+ std::strcat(filename, ".dmp");
+
+ return true;
+}
+
+bool Breakpad::SendDumpFile(const char* filename) {
+ struct stat st;
+ if (stat(filename, &st) != 0 || st.st_size <= 0)
+ return false;
+
+ google_breakpad::GoogleCrashdumpUploader
+ uploader(product_.c_str(),
+ version_.c_str(),
+ guid_.c_str(),
+ ptime_.c_str(),
+ ctime_.c_str(),
+ email_.c_str(),
+ comments_.c_str(),
+ filename,
+ server_.c_str(),
+ proxy_.c_str(),
+ passwd_.c_str());
+ return uploader.Upload();
+}
+
+bool Breakpad::GenerateAndSendDumpFile(
+ const std::map<std::string, std::string>* extra_params) {
+
+ // Create pipe.
+ int fds[2];
+ if (0 != pipe(fds))
+ return false;
+
+ std::string filename = kBreakpadDumpFilenameTemplate;
+ if (NULL == mktemp(const_cast<char*>(filename.c_str()))) {
+ close(fds[0]);
+ close(fds[1]);
+ return false;
+ }
+
+ // We must breakpad minidump the child process.
+ // Minidump ourself would crash in breakpad.
+ const pid_t child = fork();
+ if (0 == child) {
+ close(fds[1]);
+ char b;
+ HANDLE_EINTR(read(fds[0], &b, sizeof(b)));
+ close(fds[0]);
+ syscall(__NR_exit);
+ }
+ if (-1 == child) {
+ close(fds[0]);
+ close(fds[1]);
+ return false;
+ }
+
+ close(fds[0]);
+
+ // Create minidump.
+ google_breakpad::ExceptionHandler::CrashContext context;
+ memset(&context, 0, sizeof(context));
+ if (!WriteMinidump(filename.c_str(), child,
+ &context, sizeof(context))) {
+ close(fds[1]);
+ return false;
+ }
+
+ // Upload minidump.
+ bool ret = SendDumpFile(filename.c_str());
+ unlink(filename.c_str());
+ close(fds[1]);
+ return ret;
+}
+
+bool Breakpad::OnBreakpadCallback(const char* dump_path,
+ const char* minidump_id,
+ bool succeeded) {
+ // WARNING: this code runs in a compromised context. It may not call into
+ // libc nor allocate memory normally.
+ if (!succeeded)
+ return succeeded;
+
+ // Build dump filename.
+ char filename[256];
+ if (!BuildDumpFilename(filename, sizeof(filename),
+ dump_path, minidump_id))
+ return false;
+
+ // TODO(zhurunz): Change in-proc upload to out-proc upload.
+ // TODO(zhurunz): Sync with other teams in ChromeOS and figure out if
+ // we could have a GC proc to upload all dumps on ChromeOS/Linux.
+ bool ret = SendDumpFile(filename);
+ unlink(filename);
+
+ return ret;
+}
+#endif // defined(LINUX)
+
+bool BreakpadCallback(const char* dump_path,
+ const char* minidump_id,
+ void* context,
+ bool succeeded) {
+ Breakpad* breakpad = reinterpret_cast<Breakpad*>(context);
+ if (NULL == breakpad)
+ return false;
+
+ return breakpad->OnBreakpadCallback(dump_path, minidump_id, succeeded);
+}
+
+} // namespace o3d
diff --git a/o3d/breakpad/linux/breakpad.h b/o3d/breakpad/linux/breakpad.h
new file mode 100644
index 0000000..cbba468
--- /dev/null
+++ b/o3d/breakpad/linux/breakpad.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2010, 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.
+ */
+
+
+#ifndef O3D_LINUX_BREAKPAD_H_
+#define O3D_LINUX_BREAKPAD_H_
+
+#include <string>
+
+#if defined(LINUX)
+#include "client/linux/handler/exception_handler.h"
+#include "client/linux/minidump_writer/minidump_writer.h"
+#include "common/linux/linux_syscall_support.h"
+#include "common/linux/google_crashdump_uploader.h"
+#endif // defined(LINUX)
+
+namespace o3d {
+class Breakpad {
+ public:
+ const std::string& product() const { return product_; }
+ void set_product(const std::string & product) { product_ = product; }
+
+ const std::string& version() const { return version_; }
+ void set_version(const std::string & version) { version_ = version; }
+
+ const std::string& guid() const { return guid_; }
+ void set_guid(const std::string & guid) { guid_ = guid; }
+
+ const std::string& email() const { return email_; }
+ void set_email(const std::string & email) { email_ = email; }
+
+ const std::string& path() const { return path_; }
+ void set_path(const std::string & path) { path_ = path; }
+
+ const std::string& server() const { return server_; }
+ void set_server(const std::string & server) { server_ = server; }
+
+ bool Initialize();
+ bool Shutdown();
+ // Any data in extra_params is currently discarded.
+ bool GenerateAndSendDumpFile(
+ const std::map<std::string, std::string>* extra_params);
+
+ private:
+ static bool BuildDumpFilename(char* filename,
+ int len,
+ const char* dump_path,
+ const char* minidump_id);
+
+ // This is virtual to allow unittest to overwirte it and not sending
+ // out minidump file in test.
+ virtual bool SendDumpFile(const char* filename);
+
+ // Invoked by friend function BreakpadCallback
+ bool OnBreakpadCallback(const char* dump_path,
+ const char* minidump_id,
+ bool succeeded);
+
+ friend bool BreakpadCallback(const char* dump_path,
+ const char* minidump_id,
+ void* context,
+ bool succeeded);
+
+ std::string product_;
+ std::string version_;
+ std::string guid_;
+ std::string ptime_;
+ std::string ctime_;
+ std::string email_;
+ std::string comments_;
+ std::string path_;
+ std::string server_;
+ std::string proxy_;
+ std::string passwd_;
+
+ google_breakpad::ExceptionHandler* breakpad_;
+};
+
+// Breakpad minidump callback
+// A friend function of Breakpad to invoke OnBreakpadCallback.
+bool BreakpadCallback(const char* dump_path,
+ const char* minidump_id,
+ void* context,
+ bool succeeded);
+
+
+#if defined(LINUX)
+// This provides a wrapper around system calls which may be
+// interrupted by a signal and return EINTR. See man 7 signal.
+#define HANDLE_EINTR(x) ({ \
+ typeof(x) __eintr_result__; \
+ do { \
+ __eintr_result__ = x; \
+ } while (__eintr_result__ == -1 && errno == EINTR); \
+ __eintr_result__;\
+})
+#endif // defined(LINUX)
+
+} // namespace o3d
+
+#endif // O3D_LINUX_BREAKPAD_H_