OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/renderer_host/render_crash_handler_host_linux.h" | 5 #include "chrome/browser/renderer_host/render_crash_handler_host_linux.h" |
6 | 6 |
7 #include <dirent.h> | 7 #include <dirent.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 #include <string.h> | 9 #include <string.h> |
10 #include <sys/socket.h> | 10 #include <sys/socket.h> |
11 #include <sys/types.h> | 11 #include <sys/types.h> |
12 #include <sys/uio.h> | 12 #include <sys/uio.h> |
13 #include <unistd.h> | 13 #include <unistd.h> |
14 | 14 |
| 15 #include <string> |
15 #include <vector> | 16 #include <vector> |
16 | 17 |
17 #include "base/eintr_wrapper.h" | 18 #include "base/eintr_wrapper.h" |
18 #include "base/format_macros.h" | 19 #include "base/format_macros.h" |
19 #include "base/logging.h" | 20 #include "base/logging.h" |
20 #include "base/message_loop.h" | 21 #include "base/message_loop.h" |
21 #include "base/rand_util.h" | 22 #include "base/rand_util.h" |
22 #include "base/string_util.h" | 23 #include "base/string_util.h" |
23 #include "breakpad/linux/exception_handler.h" | 24 #include "breakpad/linux/exception_handler.h" |
24 #include "breakpad/linux/linux_dumper.h" | 25 #include "breakpad/linux/linux_dumper.h" |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 // block so that they can't lie about their pid. | 196 // block so that they can't lie about their pid. |
196 | 197 |
197 // The length of the control message: | 198 // The length of the control message: |
198 static const unsigned kControlMsgSize = | 199 static const unsigned kControlMsgSize = |
199 CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(struct ucred)); | 200 CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(struct ucred)); |
200 // The length of the regular payload: | 201 // The length of the regular payload: |
201 static const unsigned kCrashContextSize = | 202 static const unsigned kCrashContextSize = |
202 sizeof(google_breakpad::ExceptionHandler::CrashContext); | 203 sizeof(google_breakpad::ExceptionHandler::CrashContext); |
203 | 204 |
204 struct msghdr msg = {0}; | 205 struct msghdr msg = {0}; |
205 struct iovec iov[3]; | 206 struct iovec iov[4]; |
206 char crash_context[kCrashContextSize]; | 207 char crash_context[kCrashContextSize]; |
207 char guid[kGuidSize + 1]; | 208 char guid[kGuidSize + 1]; |
208 char crash_url[kMaxActiveURLSize + 1]; | 209 char crash_url[kMaxActiveURLSize + 1]; |
| 210 char distro[kDistroSize + 1]; |
209 char control[kControlMsgSize]; | 211 char control[kControlMsgSize]; |
210 const ssize_t expected_msg_size = sizeof(crash_context) + sizeof(guid) + | 212 const ssize_t expected_msg_size = sizeof(crash_context) + sizeof(guid) + |
211 sizeof(crash_url); | 213 sizeof(crash_url) + sizeof(distro); |
212 | 214 |
213 iov[0].iov_base = crash_context; | 215 iov[0].iov_base = crash_context; |
214 iov[0].iov_len = sizeof(crash_context); | 216 iov[0].iov_len = sizeof(crash_context); |
215 iov[1].iov_base = guid; | 217 iov[1].iov_base = guid; |
216 iov[1].iov_len = sizeof(guid); | 218 iov[1].iov_len = sizeof(guid); |
217 iov[2].iov_base = crash_url; | 219 iov[2].iov_base = crash_url; |
218 iov[2].iov_len = sizeof(crash_url); | 220 iov[2].iov_len = sizeof(crash_url); |
| 221 iov[3].iov_base = distro; |
| 222 iov[3].iov_len = sizeof(distro); |
219 msg.msg_iov = iov; | 223 msg.msg_iov = iov; |
220 msg.msg_iovlen = 3; | 224 msg.msg_iovlen = 4; |
221 msg.msg_control = control; | 225 msg.msg_control = control; |
222 msg.msg_controllen = kControlMsgSize; | 226 msg.msg_controllen = kControlMsgSize; |
223 | 227 |
224 const ssize_t msg_size = HANDLE_EINTR(recvmsg(browser_socket_, &msg, 0)); | 228 const ssize_t msg_size = HANDLE_EINTR(recvmsg(browser_socket_, &msg, 0)); |
225 if (msg_size != expected_msg_size) { | 229 if (msg_size != expected_msg_size) { |
226 LOG(ERROR) << "Error reading from death signal socket. Crash dumping" | 230 LOG(ERROR) << "Error reading from death signal socket. Crash dumping" |
227 << " is disabled." | 231 << " is disabled." |
228 << " msg_size:" << msg_size | 232 << " msg_size:" << msg_size |
229 << " errno:" << errno; | 233 << " errno:" << errno; |
230 file_descriptor_watcher_.StopWatchingFileDescriptor(); | 234 file_descriptor_watcher_.StopWatchingFileDescriptor(); |
(...skipping 13 matching lines...) Expand all Loading... |
244 // Walk the control payload an extract the file descriptor and validated pid. | 248 // Walk the control payload an extract the file descriptor and validated pid. |
245 pid_t crashing_pid = -1; | 249 pid_t crashing_pid = -1; |
246 int signal_fd = -1; | 250 int signal_fd = -1; |
247 for (struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); hdr; | 251 for (struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); hdr; |
248 hdr = CMSG_NXTHDR(&msg, hdr)) { | 252 hdr = CMSG_NXTHDR(&msg, hdr)) { |
249 if (hdr->cmsg_level != SOL_SOCKET) | 253 if (hdr->cmsg_level != SOL_SOCKET) |
250 continue; | 254 continue; |
251 if (hdr->cmsg_type == SCM_RIGHTS) { | 255 if (hdr->cmsg_type == SCM_RIGHTS) { |
252 const unsigned len = hdr->cmsg_len - | 256 const unsigned len = hdr->cmsg_len - |
253 (((uint8_t*)CMSG_DATA(hdr)) - (uint8_t*)hdr); | 257 (((uint8_t*)CMSG_DATA(hdr)) - (uint8_t*)hdr); |
254 DCHECK(len % sizeof(int) == 0); | 258 DCHECK_EQ(len % sizeof(int), 0u); |
255 const unsigned num_fds = len / sizeof(int); | 259 const unsigned num_fds = len / sizeof(int); |
256 if (num_fds > 1 || num_fds == 0) { | 260 if (num_fds > 1 || num_fds == 0) { |
257 // A nasty renderer could try and send us too many descriptors and | 261 // A nasty renderer could try and send us too many descriptors and |
258 // force a leak. | 262 // force a leak. |
259 LOG(ERROR) << "Death signal contained too many descriptors;" | 263 LOG(ERROR) << "Death signal contained too many descriptors;" |
260 << " num_fds:" << num_fds; | 264 << " num_fds:" << num_fds; |
261 for (unsigned i = 0; i < num_fds; ++i) | 265 for (unsigned i = 0; i < num_fds; ++i) |
262 HANDLE_EINTR(close(reinterpret_cast<int*>(CMSG_DATA(hdr))[i])); | 266 HANDLE_EINTR(close(reinterpret_cast<int*>(CMSG_DATA(hdr))[i])); |
263 return; | 267 return; |
264 } else { | 268 } else { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 memset(&msg, 0, sizeof(msg)); | 317 memset(&msg, 0, sizeof(msg)); |
314 struct iovec done_iov; | 318 struct iovec done_iov; |
315 done_iov.iov_base = const_cast<char*>("\x42"); | 319 done_iov.iov_base = const_cast<char*>("\x42"); |
316 done_iov.iov_len = 1; | 320 done_iov.iov_len = 1; |
317 msg.msg_iov = &done_iov; | 321 msg.msg_iov = &done_iov; |
318 msg.msg_iovlen = 1; | 322 msg.msg_iovlen = 1; |
319 | 323 |
320 HANDLE_EINTR(sendmsg(signal_fd, &msg, MSG_DONTWAIT | MSG_NOSIGNAL)); | 324 HANDLE_EINTR(sendmsg(signal_fd, &msg, MSG_DONTWAIT | MSG_NOSIGNAL)); |
321 HANDLE_EINTR(close(signal_fd)); | 325 HANDLE_EINTR(close(signal_fd)); |
322 | 326 |
323 UploadCrashDump(minidump_filename.c_str(), | 327 BreakpadInfo info; |
324 "renderer", 8, | 328 info.filename = minidump_filename.c_str(); |
325 crash_url, strlen(crash_url), | 329 info.process_type = "renderer"; |
326 guid, strlen(guid)); | 330 info.process_type_length = 8; |
| 331 info.crash_url = crash_url; |
| 332 info.crash_url_length = strlen(crash_url); |
| 333 info.guid = guid; |
| 334 info.guid_length = strlen(guid); |
| 335 info.distro = distro; |
| 336 info.distro_length = strlen(distro); |
| 337 UploadCrashDump(info); |
327 } | 338 } |
328 | 339 |
329 void RenderCrashHandlerHostLinux::WillDestroyCurrentMessageLoop() { | 340 void RenderCrashHandlerHostLinux::WillDestroyCurrentMessageLoop() { |
330 file_descriptor_watcher_.StopWatchingFileDescriptor(); | 341 file_descriptor_watcher_.StopWatchingFileDescriptor(); |
331 } | 342 } |
OLD | NEW |