summaryrefslogtreecommitdiffstats
path: root/o3d
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
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')
-rw-r--r--o3d/DEPS5
-rw-r--r--o3d/breakpad/breakpad.gyp19
-rw-r--r--o3d/breakpad/linux/breakpad.cc215
-rw-r--r--o3d/breakpad/linux/breakpad.h129
-rw-r--r--o3d/plugin/linux/main_linux.cc9
-rw-r--r--o3d/plugin/plugin.gyp14
6 files changed, 389 insertions, 2 deletions
diff --git a/o3d/DEPS b/o3d/DEPS
index 12ee2f6..3967967 100644
--- a/o3d/DEPS
+++ b/o3d/DEPS
@@ -4,12 +4,13 @@ vars = {
# When updating the chromium rev, you must also update the nss and sqlite
# revs to match the version pulled-in by Chromium's own DEPS in the new rev.
"chromium_rev": "37758",
+ "chromium_breakpad_rev": "47985",
"o3d_code_rev": "190",
"skia_rev": "488",
"gyp_rev": "820",
"gtest_rev": "359",
"gflags_rev": "30",
- "breakpad_rev": "391",
+ "breakpad_rev": "603",
"v8_rev": "3608",
"nacl_rev": "1434",
}
@@ -113,7 +114,7 @@ deps = {
Var("chromium_trunk") + "/src/skia@" + Var("chromium_rev"),
"breakpad":
- Var("chromium_trunk") + "/src/breakpad@" + Var("chromium_rev"),
+ Var("chromium_trunk") + "/src/breakpad@" + Var("chromium_breakpad_rev"),
"base":
Var("chromium_trunk") + "/src/base@" + Var("chromium_rev"),
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_
diff --git a/o3d/plugin/linux/main_linux.cc b/o3d/plugin/linux/main_linux.cc
index 80bd3d5..7e3ffb3 100644
--- a/o3d/plugin/linux/main_linux.cc
+++ b/o3d/plugin/linux/main_linux.cc
@@ -40,6 +40,7 @@
#include "base/command_line.h"
#include "base/logging.h"
#include "base/scoped_ptr.h"
+#include "o3d/breakpad/linux/breakpad.h"
#include "plugin/cross/main.h"
#include "plugin/cross/out_of_memory.h"
#include "plugin/cross/whitelist.h"
@@ -61,6 +62,8 @@ base::AtExitManager g_at_exit_manager;
bool g_xembed_support = false;
+o3d::Breakpad g_breakpad;
+
#ifdef O3D_PLUGIN_ENV_VARS_FILE
static const char *kEnvVarsFilePath = O3D_PLUGIN_ENV_VARS_FILE;
#endif
@@ -622,6 +625,10 @@ NPError InitializePlugin() {
if (!o3d::SetupOutOfMemoryHandler())
return NPERR_MODULE_LOAD_FAILED_ERROR;
+ // Setup breakpad
+ g_breakpad.Initialize();
+ g_breakpad.set_version(O3D_PLUGIN_VERSION);
+
CommandLine::Init(0, NULL);
InitLogging("debug.log",
logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG,
@@ -682,6 +689,8 @@ NPError EXPORT_SYMBOL OSCALL NP_Shutdown(void) {
CommandLine::Reset();
+ g_breakpad.Shutdown();
+
return NPERR_NO_ERROR;
}
diff --git a/o3d/plugin/plugin.gyp b/o3d/plugin/plugin.gyp
index e7092e7..503994f 100644
--- a/o3d/plugin/plugin.gyp
+++ b/o3d/plugin/plugin.gyp
@@ -267,6 +267,10 @@
],
['OS == "linux"',
{
+ 'dependencies': [
+ '../../breakpad/breakpad.gyp:breakpad_client',
+ '../breakpad/breakpad.gyp:o3dBreakpad',
+ ],
'sources': [
'linux/config.cc',
'linux/envvars.cc',
@@ -288,6 +292,7 @@
# the --as-needed flag.
'-lCgGL',
'-lGLEW',
+ '-ldl', # Used by breakpad
'-lrt',
# Directs the linker to only generate dependencies on libraries
# that we actually use. Must come last.
@@ -297,6 +302,15 @@
'<!@(pkg-config --libs-only-l xt)',
],
'conditions' : [
+ ['target_arch=="ia32"',
+ { # Used by breakpad
+ # TODO(zhurunz) Remove the deps on libglog.a
+ 'libraries': [
+ '-Lbreakpad/src/third_party/linux/lib/glog',
+ '-lglog',
+ ],
+ },
+ ],
['plugin_rpath != ""',
{
'ldflags': [