diff options
author | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-28 20:23:06 +0000 |
---|---|---|
committer | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-28 20:23:06 +0000 |
commit | 1e7377df1449c4e543a50c8a8a1425599c8425f7 (patch) | |
tree | 6e8ee3adcba66e4a043e91e91e0217467682a7fd /chrome/app/breakpad_linux.cc | |
parent | 34cf340da15aceffd59c3d05e0de2a3bc5174a2d (diff) | |
download | chromium_src-1e7377df1449c4e543a50c8a8a1425599c8425f7.zip chromium_src-1e7377df1449c4e543a50c8a8a1425599c8425f7.tar.gz chromium_src-1e7377df1449c4e543a50c8a8a1425599c8425f7.tar.bz2 |
Respect Linux user prefs with regards to crash reporting.
This involves implementing GoogleUpdateSettings::[GS]etCollectStatsConsent, and a whole lot of refactoring.
BUG=none
TEST=delete config dir, run official Linux build, don't enable crash reporting, crash browser -> no crash reporting.
Review URL: http://codereview.chromium.org/115808
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17104 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/app/breakpad_linux.cc')
-rw-r--r-- | chrome/app/breakpad_linux.cc | 97 |
1 files changed, 94 insertions, 3 deletions
diff --git a/chrome/app/breakpad_linux.cc b/chrome/app/breakpad_linux.cc index ca1e91e..237ed98 100644 --- a/chrome/app/breakpad_linux.cc +++ b/chrome/app/breakpad_linux.cc @@ -2,19 +2,25 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <unistd.h> #include <fcntl.h> #include <sys/socket.h> #include <sys/uio.h> +#include <unistd.h> +#include <string> + +#include "base/command_line.h" #include "base/eintr_wrapper.h" -#include "base/rand_util.h" #include "base/file_version_info_linux.h" +#include "base/path_service.h" +#include "base/rand_util.h" #include "breakpad/linux/directory_reader.h" #include "breakpad/linux/exception_handler.h" #include "breakpad/linux/linux_libc_support.h" #include "breakpad/linux/linux_syscall_support.h" #include "breakpad/linux/memory.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/installer/util/google_update_settings.h" static const char kUploadURL[] = "https://clients2.google.com/cr/report"; @@ -349,7 +355,7 @@ pid_t UploadCrashDump(const char* filename, const char* crash_url, }; execv("/usr/bin/wget", const_cast<char**>(args)); - static const char msg[] = "Cannot update crash dump: cannot exec " + static const char msg[] = "Cannot upload crash dump: cannot exec " "/usr/bin/wget\n"; sys_write(2, msg, sizeof(msg) - 1); sys__exit(1); @@ -390,3 +396,88 @@ void EnableCrashDumping() { new google_breakpad::ExceptionHandler("/tmp", NULL, CrashDone, NULL, true /* install handlers */); } + +// This is defined in chrome/renderer/renderer_logging_linux.cc, it's the +// static string containing the current active URL. We send this in the crash +// report. +namespace renderer_logging { +extern std::string active_url; +} + +static bool +RendererCrashHandler(const void* crash_context, size_t crash_context_size, + void* context) { + const int fd = (int) context; + int fds[2]; + pipe(fds); + + // The length of the control message: + static const unsigned kControlMsgSize = + CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(struct ucred)); + + union { + struct kernel_msghdr msg; + struct msghdr sys_msg; + }; + my_memset(&msg, 0, sizeof(struct kernel_msghdr)); + struct kernel_iovec iov[2]; + iov[0].iov_base = const_cast<void*>(crash_context); + iov[0].iov_len = crash_context_size; + iov[1].iov_base = const_cast<char*>(renderer_logging::active_url.data()); + iov[1].iov_len = renderer_logging::active_url.size(); + + msg.msg_iov = iov; + msg.msg_iovlen = 2; + char cmsg[kControlMsgSize]; + memset(cmsg, 0, kControlMsgSize); + msg.msg_control = cmsg; + msg.msg_controllen = sizeof(cmsg); + + struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); + hdr->cmsg_level = SOL_SOCKET; + hdr->cmsg_type = SCM_RIGHTS; + hdr->cmsg_len = CMSG_LEN(sizeof(int)); + *((int*) CMSG_DATA(hdr)) = fds[1]; + hdr = CMSG_NXTHDR(&sys_msg, hdr); + hdr->cmsg_level = SOL_SOCKET; + hdr->cmsg_type = SCM_CREDENTIALS; + hdr->cmsg_len = CMSG_LEN(sizeof(struct ucred)); + struct ucred *cred = reinterpret_cast<struct ucred*>(CMSG_DATA(hdr)); + cred->uid = getuid(); + cred->gid = getgid(); + cred->pid = getpid(); + + HANDLE_EINTR(sys_sendmsg(fd, &msg, 0)); + sys_close(fds[1]); + + char b; + HANDLE_EINTR(sys_read(fds[0], &b, 1)); + + return true; +} + +void EnableRendererCrashDumping() { + // When the browser forks off our process, it installs the crash signal file + // descriptor in this slot: + static const int kMagicCrashSignalFd = 4; + + // We deliberately leak this object. + google_breakpad::ExceptionHandler* handler = + new google_breakpad::ExceptionHandler("" /* unused */, NULL, NULL, + (void*) kMagicCrashSignalFd, true); + handler->set_crash_handler(RendererCrashHandler); +} + +void InitCrashReporter() { + if (!GoogleUpdateSettings::GetCollectStatsConsent()) + return; + + // Determine the process type and take appropriate action. + const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); + const std::wstring process_type = + parsed_command_line.GetSwitchValue(switches::kProcessType); + if (process_type.empty()) + EnableCrashDumping(); + else if (process_type == switches::kRendererProcess) + EnableRendererCrashDumping(); +} |