1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <string>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include "base/eintr_wrapper.h"
#include "breakpad/linux/exception_handler.h"
#include "breakpad/linux/linux_libc_support.h"
#include "breakpad/linux/linux_syscall_support.h"
// 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
CrashHandler(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(CrashHandler);
}
|