summaryrefslogtreecommitdiffstats
path: root/chrome/app/breakpad_linux.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/app/breakpad_linux.cc')
-rw-r--r--chrome/app/breakpad_linux.cc110
1 files changed, 75 insertions, 35 deletions
diff --git a/chrome/app/breakpad_linux.cc b/chrome/app/breakpad_linux.cc
index 19c82ba..415db89 100644
--- a/chrome/app/breakpad_linux.cc
+++ b/chrome/app/breakpad_linux.cc
@@ -7,6 +7,7 @@
#include <arpa/inet.h>
#include <fcntl.h>
#include <netinet/in.h>
+#include <stdlib.h>
#include <sys/sendfile.h>
#include <sys/socket.h>
#include <sys/uio.h>
@@ -18,6 +19,7 @@
#include "base/command_line.h"
#include "base/eintr_wrapper.h"
+#include "base/file_path.h"
#include "base/file_version_info_linux.h"
#include "base/format_macros.h"
#include "base/global_descriptors_posix.h"
@@ -34,6 +36,7 @@
#include "breakpad/linux/linux_syscall_support.h"
#include "breakpad/linux/memory.h"
#include "chrome/common/chrome_descriptors.h"
+#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/installer/util/google_update_settings.h"
@@ -51,7 +54,7 @@ static void write_uint64_hex(char* output, uint64_t v) {
}
}
-pid_t UploadCrashDump(const BreakpadInfo& info) {
+pid_t HandleCrashDump(const BreakpadInfo& info) {
// WARNING: this code runs in a compromised context. It may not call into
// libc nor allocate memory normally.
@@ -95,29 +98,39 @@ pid_t UploadCrashDump(const BreakpadInfo& info) {
static const char temp_file_template[] =
"/tmp/chromium-upload-XXXXXXXXXXXXXXXX";
- char buf[sizeof(temp_file_template)];
- memcpy(buf, temp_file_template, sizeof(temp_file_template));
-
+ char temp_file[sizeof(temp_file_template)];
int fd = -1;
- for (unsigned i = 0; i < 10; ++i) {
- uint64_t t;
- read(ufd, &t, sizeof(t));
- write_uint64_hex(buf + sizeof(buf) - (16 + 1), t);
-
- fd = sys_open(buf, O_WRONLY | O_CREAT | O_EXCL, 0600);
- if (fd >= 0)
- break;
- }
+ if (info.upload) {
+ memcpy(temp_file, temp_file_template, sizeof(temp_file_template));
- if (fd == -1) {
- static const char msg[] = "Failed to create temporary file in /tmp: cannot "
- "upload crash dump\n";
- sys_write(2, msg, sizeof(msg) - 1);
- sys_close(ufd);
- return -1;
+ for (unsigned i = 0; i < 10; ++i) {
+ uint64_t t;
+ read(ufd, &t, sizeof(t));
+ write_uint64_hex(temp_file + sizeof(temp_file) - (16 + 1), t);
+
+ fd = sys_open(temp_file, O_WRONLY | O_CREAT | O_EXCL, 0600);
+ if (fd >= 0)
+ break;
+ }
+
+ if (fd < 0) {
+ static const char msg[] = "Failed to create temporary file in /tmp: "
+ "cannot upload crash dump\n";
+ sys_write(2, msg, sizeof(msg) - 1);
+ sys_close(ufd);
+ return -1;
+ }
+ } else {
+ fd = sys_open(info.filename, O_WRONLY, 0600);
+ if (fd < 0) {
+ static const char msg[] = "Failed to save crash dump: failed to open\n";
+ sys_write(2, msg, sizeof(msg) - 1);
+ sys_close(ufd);
+ return -1;
+ }
}
- // The MIME boundary is 28 hypens, followed by a 64-bit nonce and a NUL.
+ // The MIME boundary is 28 hyphens, followed by a 64-bit nonce and a NUL.
char mime_boundary[28 + 16 + 1];
my_memset(mime_boundary, '-', 28);
uint64_t boundary_rand;
@@ -373,6 +386,9 @@ pid_t UploadCrashDump(const BreakpadInfo& info) {
sys_close(fd);
+ if (!info.upload)
+ return 0;
+
// The --header argument to wget looks like:
// --header=Content-Type: multipart/form-data; boundary=XYZ
// where the boundary has two fewer leading '-' chars
@@ -389,9 +405,9 @@ pid_t UploadCrashDump(const BreakpadInfo& info) {
// --post-file=/tmp/...
static const char post_file_msg[] = "--post-file=";
char* const post_file = reinterpret_cast<char*>(allocator.Alloc(
- sizeof(post_file_msg) - 1 + sizeof(buf)));
+ sizeof(post_file_msg) - 1 + sizeof(temp_file)));
memcpy(post_file, post_file_msg, sizeof(post_file_msg) - 1);
- memcpy(post_file + sizeof(post_file_msg) - 1, buf, sizeof(buf));
+ memcpy(post_file + sizeof(post_file_msg) - 1, temp_file, sizeof(temp_file));
const pid_t child = sys_fork();
if (!child) {
@@ -441,7 +457,7 @@ pid_t UploadCrashDump(const BreakpadInfo& info) {
sys_write(2, "\n", 1);
}
sys_unlink(info.filename);
- sys_unlink(buf);
+ sys_unlink(temp_file);
sys__exit(0);
}
@@ -458,7 +474,7 @@ pid_t UploadCrashDump(const BreakpadInfo& info) {
NULL,
};
- execv("/usr/bin/wget", const_cast<char**>(args));
+ execv(kWgetBinary, const_cast<char**>(args));
static const char msg[] = "Cannot upload crash dump: cannot exec "
"/usr/bin/wget\n";
sys_write(2, msg, sizeof(msg) - 1);
@@ -483,8 +499,8 @@ extern std::string linux_distro;
static bool CrashDone(const char* dump_path,
const char* minidump_id,
- void* context,
- bool succeeded) {
+ const bool upload,
+ const bool succeeded) {
// WARNING: this code runs in a compromised context. It may not call into
// libc nor allocate memory normally.
if (!succeeded)
@@ -512,16 +528,39 @@ static bool CrashDone(const char* dump_path,
info.guid_length = google_update::linux_guid.length();
info.distro = base::linux_distro.data();
info.distro_length = base::linux_distro.length();
- UploadCrashDump(info);
+ info.upload = upload;
+ HandleCrashDump(info);
return true;
}
-void EnableCrashDumping() {
- // We leak this object.
+// Wrapper script, do not add more code here.
+static bool CrashDoneNoUpload(const char* dump_path,
+ const char* minidump_id,
+ void* context,
+ bool succeeded) {
+ return CrashDone(dump_path, minidump_id, false, succeeded);
+}
+
+// Wrapper script, do not add more code here.
+static bool CrashDoneUpload(const char* dump_path,
+ const char* minidump_id,
+ void* context,
+ bool succeeded) {
+ return CrashDone(dump_path, minidump_id, true, succeeded);
+}
- new google_breakpad::ExceptionHandler("/tmp", NULL, CrashDone, NULL,
- true /* install handlers */);
+void EnableCrashDumping(const bool unattended) {
+ if (unattended) {
+ FilePath dumps_path("/tmp");
+ PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path);
+ new google_breakpad::ExceptionHandler(dumps_path.value().c_str(), NULL,
+ CrashDoneNoUpload, NULL,
+ true /* install handlers */);
+ } else {
+ new google_breakpad::ExceptionHandler("/tmp", NULL, CrashDoneUpload, NULL,
+ true /* install handlers */);
+ }
}
// This is defined in chrome/common/child_process_logging_linux.cc, it's the
@@ -601,11 +640,12 @@ void InitCrashReporter() {
const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
const std::wstring process_type =
parsed_command_line.GetSwitchValue(switches::kProcessType);
+ const bool unattended = (getenv("CHROME_HEADLESS") != NULL);
if (process_type.empty()) {
- if (!GoogleUpdateSettings::GetCollectStatsConsent())
+ if (!(unattended || GoogleUpdateSettings::GetCollectStatsConsent()))
return;
base::GetLinuxDistro(); // Initialize base::linux_distro if needed.
- EnableCrashDumping();
+ EnableCrashDumping(unattended);
} else if (process_type == switches::kRendererProcess ||
process_type == switches::kZygoteProcess) {
// We might be chrooted in a zygote or renderer process so we cannot call
@@ -629,6 +669,7 @@ void InitCrashReporter() {
// -----------------------------------------------------------------------------
+#if defined(GOOGLE_CHROME_BUILD)
bool EnableCoreDumping(std::string* core_dump_directory) {
// First we check that the core files will get dumped to the
// current-directory in a file called 'core'. We could try to support other
@@ -729,9 +770,7 @@ static void UploadCoreFile(const pid_t child, std::string* core_filename) {
header.SetString(L"chrome-version", FILE_VERSION);
header.SetString(L"binary-size", StringPrintf("%" PRIu64, binary_size));
header.SetString(L"user", getenv("USER"));
-#if defined(GOOGLE_CHROME_BUILD)
header.SetBoolean(L"offical-build", true);
-#endif
std::string json;
JSONWriter::Write(&header, true /* pretty print */, &json);
@@ -787,3 +826,4 @@ void MonitorForCoreDumpsAndReport(const std::string& core_dump_directory,
rmdir(core_dump_directory.c_str());
}
+#endif