| 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 |