summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-26 00:14:27 +0000
committerthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-26 00:14:27 +0000
commitcbd5fd5ead41910dce8a20ec53ce1195548440d5 (patch)
tree13e0a2a823ba8ae31d829e7098763ebd1a7d0a68 /chrome
parent0c22345d5e500ad60e51b7a4c4da29fe3cf6ff64 (diff)
downloadchromium_src-cbd5fd5ead41910dce8a20ec53ce1195548440d5.zip
chromium_src-cbd5fd5ead41910dce8a20ec53ce1195548440d5.tar.gz
chromium_src-cbd5fd5ead41910dce8a20ec53ce1195548440d5.tar.bz2
Allow Chromium Linux to be built with Breakpad. Enable Linux CHROME_HEADLESS support. (Try 2)
TEST=none BUG=19663 Original Review URL: http://codereview.chromium.org/173095 Review URL: http://codereview.chromium.org/173397 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@24378 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/app/breakpad_linux.cc110
-rw-r--r--chrome/app/breakpad_linux.h7
-rw-r--r--chrome/browser/renderer_host/render_crash_handler_host_linux.cc16
-rw-r--r--chrome/chrome.gyp14
-rw-r--r--chrome/common/child_process_host.cc14
5 files changed, 101 insertions, 60 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
diff --git a/chrome/app/breakpad_linux.h b/chrome/app/breakpad_linux.h
index d06c9a2..53f43a1 100644
--- a/chrome/app/breakpad_linux.h
+++ b/chrome/app/breakpad_linux.h
@@ -9,7 +9,7 @@
extern void InitCrashReporter();
-#if defined(GOOGLE_CHROME_BUILD)
+#if defined(USE_LINUX_BREAKPAD)
static const size_t kMaxActiveURLSize = 1024;
static const size_t kGuidSize = 32; // 128 bits = 32 chars in hex.
static const size_t kDistroSize = 128;
@@ -24,10 +24,13 @@ struct BreakpadInfo {
unsigned guid_length;
const char* distro;
unsigned distro_length;
+ bool upload;
};
-extern int UploadCrashDump(const BreakpadInfo& info);
+extern int HandleCrashDump(const BreakpadInfo& info);
+#endif // defined(USE_LINUX_BREAKPAD)
+#if defined(GOOGLE_CHROME_BUILD)
// Checks that the kernel's core filename pattern is "core" and moves the
// current working directory to a temp directory.
// Returns true iff core dumping has been successfully enabled for the current
diff --git a/chrome/browser/renderer_host/render_crash_handler_host_linux.cc b/chrome/browser/renderer_host/render_crash_handler_host_linux.cc
index 5c99e5f..ec83663 100644
--- a/chrome/browser/renderer_host/render_crash_handler_host_linux.cc
+++ b/chrome/browser/renderer_host/render_crash_handler_host_linux.cc
@@ -10,15 +10,18 @@
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/uio.h>
+#include <stdlib.h>
#include <unistd.h>
#include <string>
#include <vector>
#include "base/eintr_wrapper.h"
+#include "base/file_path.h"
#include "base/format_macros.h"
#include "base/logging.h"
#include "base/message_loop.h"
+#include "base/path_service.h"
#include "base/rand_util.h"
#include "base/string_util.h"
#include "breakpad/linux/exception_handler.h"
@@ -26,6 +29,7 @@
#include "breakpad/linux/minidump_writer.h"
#include "chrome/app/breakpad_linux.h"
#include "chrome/browser/chrome_thread.h"
+#include "chrome/common/chrome_paths.h"
// expected prefix of the target of the /proc/self/fd/%d link for a socket
static const char kSocketLinkPrefix[] = "socket:[";
@@ -303,9 +307,16 @@ void RenderCrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) {
return;
}
+ bool upload = true;
+ FilePath dumps_path("/tmp");
+ if (getenv("CHROME_HEADLESS")) {
+ upload = false;
+ PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path);
+ }
const uint64 rand = base::RandUint64();
const std::string minidump_filename =
- StringPrintf("/tmp/chromium-renderer-minidump-%016" PRIx64 ".dmp", rand);
+ StringPrintf("%s/chromium-renderer-minidump-%016" PRIx64 ".dmp",
+ dumps_path.value().c_str(), rand);
if (!google_breakpad::WriteMinidump(minidump_filename.c_str(),
crashing_pid, crash_context,
kCrashContextSize)) {
@@ -334,7 +345,8 @@ void RenderCrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) {
info.guid_length = strlen(guid);
info.distro = distro;
info.distro_length = strlen(distro);
- UploadCrashDump(info);
+ info.upload = upload;
+ HandleCrashDump(info);
}
void RenderCrashHandlerHostLinux::WillDestroyCurrentMessageLoop() {
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 6fc8676..99c9a0a 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -4727,20 +4727,6 @@
}, # target chrome_dll
], # targets
}], # OS=="mac" or OS=="win"
- ['OS=="linux"', {
- 'conditions': [
- # Only Chrome builds get breakpad since crash processing is internal.
- ['branding=="Chrome"', {
- 'variables': {
- 'linux_breakpad%': 1,
- },
- }, {
- 'variables': {
- 'linux_breakpad%': 0,
- },
- }],
- ],
- }],
['OS=="mac"',
{ 'targets': [
{
diff --git a/chrome/common/child_process_host.cc b/chrome/common/child_process_host.cc
index 1fa91f9..cf67d15 100644
--- a/chrome/common/child_process_host.cc
+++ b/chrome/common/child_process_host.cc
@@ -145,18 +145,18 @@ std::wstring ChildProcessHost::GetChildPath() {
// static
void ChildProcessHost::SetCrashReporterCommandLine(CommandLine* command_line) {
-#if defined(OS_POSIX)
- if (GoogleUpdateSettings::GetCollectStatsConsent()) {
-#if defined(OS_LINUX)
+#if defined(USE_LINUX_BREAKPAD)
+ const bool unattended = (getenv("CHROME_HEADLESS") != NULL);
+ if (unattended || GoogleUpdateSettings::GetCollectStatsConsent()) {
command_line->AppendSwitchWithValue(switches::kEnableCrashReporter,
ASCIIToWide(google_update::linux_guid +
"," +
base::GetLinuxDistro()));
-#else // !OS_LINUX
- command_line->AppendSwitch(switches::kEnableCrashReporter);
-#endif // !OS_LINUX
}
-#endif // OS_POSIX
+#elif defined(OS_MACOSX)
+ if (GoogleUpdateSettings::GetCollectStatsConsent())
+ command_line->AppendSwitch(switches::kEnableCrashReporter);
+#endif // OS_MACOSX
}
bool ChildProcessHost::CreateChannel() {