diff options
author | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-26 00:14:27 +0000 |
---|---|---|
committer | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-26 00:14:27 +0000 |
commit | cbd5fd5ead41910dce8a20ec53ce1195548440d5 (patch) | |
tree | 13e0a2a823ba8ae31d829e7098763ebd1a7d0a68 /chrome | |
parent | 0c22345d5e500ad60e51b7a4c4da29fe3cf6ff64 (diff) | |
download | chromium_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.cc | 110 | ||||
-rw-r--r-- | chrome/app/breakpad_linux.h | 7 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_crash_handler_host_linux.cc | 16 | ||||
-rw-r--r-- | chrome/chrome.gyp | 14 | ||||
-rw-r--r-- | chrome/common/child_process_host.cc | 14 |
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() { |