| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include <string> | |
| 6 | |
| 7 #include <unistd.h> | |
| 8 #include <sys/socket.h> | |
| 9 #include <sys/uio.h> | |
| 10 | |
| 11 #include "base/eintr_wrapper.h" | |
| 12 #include "breakpad/linux/exception_handler.h" | |
| 13 #include "breakpad/linux/linux_libc_support.h" | |
| 14 #include "breakpad/linux/linux_syscall_support.h" | |
| 15 | |
| 16 // This is defined in chrome/renderer/renderer_logging_linux.cc, it's the | |
| 17 // static string containing the current active URL. We send this in the crash | |
| 18 // report. | |
| 19 namespace renderer_logging { | |
| 20 extern std::string active_url; | |
| 21 } | |
| 22 | |
| 23 static bool | |
| 24 CrashHandler(const void* crash_context, size_t crash_context_size, | |
| 25 void* context) { | |
| 26 const int fd = (int) context; | |
| 27 int fds[2]; | |
| 28 pipe(fds); | |
| 29 | |
| 30 // The length of the control message: | |
| 31 static const unsigned kControlMsgSize = | |
| 32 CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(struct ucred)); | |
| 33 | |
| 34 union { | |
| 35 struct kernel_msghdr msg; | |
| 36 struct msghdr sys_msg; | |
| 37 }; | |
| 38 my_memset(&msg, 0, sizeof(struct kernel_msghdr)); | |
| 39 struct kernel_iovec iov[2]; | |
| 40 iov[0].iov_base = const_cast<void*>(crash_context); | |
| 41 iov[0].iov_len = crash_context_size; | |
| 42 iov[1].iov_base = const_cast<char*>(renderer_logging::active_url.data()); | |
| 43 iov[1].iov_len = renderer_logging::active_url.size(); | |
| 44 | |
| 45 msg.msg_iov = iov; | |
| 46 msg.msg_iovlen = 2; | |
| 47 char cmsg[kControlMsgSize]; | |
| 48 memset(cmsg, 0, kControlMsgSize); | |
| 49 msg.msg_control = cmsg; | |
| 50 msg.msg_controllen = sizeof(cmsg); | |
| 51 | |
| 52 struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); | |
| 53 hdr->cmsg_level = SOL_SOCKET; | |
| 54 hdr->cmsg_type = SCM_RIGHTS; | |
| 55 hdr->cmsg_len = CMSG_LEN(sizeof(int)); | |
| 56 *((int*) CMSG_DATA(hdr)) = fds[1]; | |
| 57 hdr = CMSG_NXTHDR(&sys_msg, hdr); | |
| 58 hdr->cmsg_level = SOL_SOCKET; | |
| 59 hdr->cmsg_type = SCM_CREDENTIALS; | |
| 60 hdr->cmsg_len = CMSG_LEN(sizeof(struct ucred)); | |
| 61 struct ucred *cred = reinterpret_cast<struct ucred*>(CMSG_DATA(hdr)); | |
| 62 cred->uid = getuid(); | |
| 63 cred->gid = getgid(); | |
| 64 cred->pid = getpid(); | |
| 65 | |
| 66 HANDLE_EINTR(sys_sendmsg(fd, &msg, 0)); | |
| 67 sys_close(fds[1]); | |
| 68 | |
| 69 char b; | |
| 70 HANDLE_EINTR(sys_read(fds[0], &b, 1)); | |
| 71 | |
| 72 return true; | |
| 73 } | |
| 74 | |
| 75 void EnableRendererCrashDumping() { | |
| 76 // When the browser forks off our process, it installs the crash signal file | |
| 77 // descriptor in this slot: | |
| 78 static const int kMagicCrashSignalFd = 4; | |
| 79 | |
| 80 // We deliberately leak this object. | |
| 81 google_breakpad::ExceptionHandler* handler = | |
| 82 new google_breakpad::ExceptionHandler("" /* unused */, NULL, NULL, | |
| 83 (void*) kMagicCrashSignalFd, true); | |
| 84 handler->set_crash_handler(CrashHandler); | |
| 85 } | |
| OLD | NEW |