| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "components/crash/content/browser/crash_handler_host_linux.h" | 5 #include "components/crash/content/browser/crash_handler_host_linux.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <stdint.h> | 9 #include <stdint.h> |
| 10 #include <stdlib.h> | 10 #include <stdlib.h> |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 | 50 |
| 51 const size_t kNumFDs = 1; | 51 const size_t kNumFDs = 1; |
| 52 // The length of the control message: | 52 // The length of the control message: |
| 53 const size_t kControlMsgSize = | 53 const size_t kControlMsgSize = |
| 54 CMSG_SPACE(kNumFDs * sizeof(int)) + CMSG_SPACE(sizeof(struct ucred)); | 54 CMSG_SPACE(kNumFDs * sizeof(int)) + CMSG_SPACE(sizeof(struct ucred)); |
| 55 // The length of the regular payload: | 55 // The length of the regular payload: |
| 56 const size_t kCrashContextSize = sizeof(ExceptionHandler::CrashContext); | 56 const size_t kCrashContextSize = sizeof(ExceptionHandler::CrashContext); |
| 57 | 57 |
| 58 // Handles the crash dump and frees the allocated BreakpadInfo struct. | 58 // Handles the crash dump and frees the allocated BreakpadInfo struct. |
| 59 void CrashDumpTask(CrashHandlerHostLinux* handler, | 59 void CrashDumpTask(CrashHandlerHostLinux* handler, |
| 60 scoped_ptr<BreakpadInfo> info) { | 60 std::unique_ptr<BreakpadInfo> info) { |
| 61 if (handler->IsShuttingDown() && info->upload) { | 61 if (handler->IsShuttingDown() && info->upload) { |
| 62 base::DeleteFile(base::FilePath(info->filename), false); | 62 base::DeleteFile(base::FilePath(info->filename), false); |
| 63 #if defined(ADDRESS_SANITIZER) | 63 #if defined(ADDRESS_SANITIZER) |
| 64 base::DeleteFile(base::FilePath(info->log_filename), false); | 64 base::DeleteFile(base::FilePath(info->log_filename), false); |
| 65 #endif | 65 #endif |
| 66 return; | 66 return; |
| 67 } | 67 } |
| 68 | 68 |
| 69 HandleCrashDump(*info); | 69 HandleCrashDump(*info); |
| 70 delete[] info->filename; | 70 delete[] info->filename; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 // A process has crashed and has signaled us by writing a datagram | 143 // A process has crashed and has signaled us by writing a datagram |
| 144 // to the death signal socket. The datagram contains the crash context needed | 144 // to the death signal socket. The datagram contains the crash context needed |
| 145 // for writing the minidump as well as a file descriptor and a credentials | 145 // for writing the minidump as well as a file descriptor and a credentials |
| 146 // block so that they can't lie about their pid. | 146 // block so that they can't lie about their pid. |
| 147 // | 147 // |
| 148 // The message sender is in components/crash/content/app/breakpad_linux.cc. | 148 // The message sender is in components/crash/content/app/breakpad_linux.cc. |
| 149 | 149 |
| 150 struct msghdr msg = {0}; | 150 struct msghdr msg = {0}; |
| 151 struct iovec iov[kCrashIovSize]; | 151 struct iovec iov[kCrashIovSize]; |
| 152 | 152 |
| 153 scoped_ptr<char[]> crash_context(new char[kCrashContextSize]); | 153 std::unique_ptr<char[]> crash_context(new char[kCrashContextSize]); |
| 154 #if defined(ADDRESS_SANITIZER) | 154 #if defined(ADDRESS_SANITIZER) |
| 155 scoped_ptr<char[]> asan_report(new char[kMaxAsanReportSize + 1]); | 155 std::unique_ptr<char[]> asan_report(new char[kMaxAsanReportSize + 1]); |
| 156 #endif | 156 #endif |
| 157 | 157 |
| 158 scoped_ptr<CrashKeyStorage> crash_keys(new CrashKeyStorage); | 158 std::unique_ptr<CrashKeyStorage> crash_keys(new CrashKeyStorage); |
| 159 google_breakpad::SerializedNonAllocatingMap* serialized_crash_keys; | 159 google_breakpad::SerializedNonAllocatingMap* serialized_crash_keys; |
| 160 size_t crash_keys_size = crash_keys->Serialize( | 160 size_t crash_keys_size = crash_keys->Serialize( |
| 161 const_cast<const google_breakpad::SerializedNonAllocatingMap**>( | 161 const_cast<const google_breakpad::SerializedNonAllocatingMap**>( |
| 162 &serialized_crash_keys)); | 162 &serialized_crash_keys)); |
| 163 | 163 |
| 164 char* tid_buf_addr = NULL; | 164 char* tid_buf_addr = NULL; |
| 165 int tid_fd = -1; | 165 int tid_fd = -1; |
| 166 uint64_t uptime; | 166 uint64_t uptime; |
| 167 size_t oom_size; | 167 size_t oom_size; |
| 168 char control[kControlMsgSize]; | 168 char control[kControlMsgSize]; |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 // trust the TID passed by the crashing process. | 292 // trust the TID passed by the crashing process. |
| 293 LOG(WARNING) << "Could not translate tid - assuming crashing thread is " | 293 LOG(WARNING) << "Could not translate tid - assuming crashing thread is " |
| 294 "thread group leader; syscall_supported=" << syscall_supported; | 294 "thread group leader; syscall_supported=" << syscall_supported; |
| 295 crashing_tid = crashing_pid; | 295 crashing_tid = crashing_pid; |
| 296 } | 296 } |
| 297 | 297 |
| 298 ExceptionHandler::CrashContext* bad_context = | 298 ExceptionHandler::CrashContext* bad_context = |
| 299 reinterpret_cast<ExceptionHandler::CrashContext*>(crash_context.get()); | 299 reinterpret_cast<ExceptionHandler::CrashContext*>(crash_context.get()); |
| 300 bad_context->tid = crashing_tid; | 300 bad_context->tid = crashing_tid; |
| 301 | 301 |
| 302 scoped_ptr<BreakpadInfo> info(new BreakpadInfo); | 302 std::unique_ptr<BreakpadInfo> info(new BreakpadInfo); |
| 303 | 303 |
| 304 info->fd = -1; | 304 info->fd = -1; |
| 305 info->process_type_length = process_type_.length(); | 305 info->process_type_length = process_type_.length(); |
| 306 // Freed in CrashDumpTask(). | 306 // Freed in CrashDumpTask(). |
| 307 char* process_type_str = new char[info->process_type_length + 1]; | 307 char* process_type_str = new char[info->process_type_length + 1]; |
| 308 process_type_.copy(process_type_str, info->process_type_length); | 308 process_type_.copy(process_type_str, info->process_type_length); |
| 309 process_type_str[info->process_type_length] = '\0'; | 309 process_type_str[info->process_type_length] = '\0'; |
| 310 info->process_type = process_type_str; | 310 info->process_type = process_type_str; |
| 311 | 311 |
| 312 // Memory released from scoped_ptrs below are also freed in CrashDumpTask(). | 312 // Memory released from std::unique_ptrs below are also freed in |
| 313 // CrashDumpTask(). |
| 313 info->crash_keys = crash_keys.release(); | 314 info->crash_keys = crash_keys.release(); |
| 314 #if defined(ADDRESS_SANITIZER) | 315 #if defined(ADDRESS_SANITIZER) |
| 315 asan_report[kMaxAsanReportSize] = '\0'; | 316 asan_report[kMaxAsanReportSize] = '\0'; |
| 316 info->asan_report_str = asan_report.release(); | 317 info->asan_report_str = asan_report.release(); |
| 317 info->asan_report_length = strlen(info->asan_report_str); | 318 info->asan_report_length = strlen(info->asan_report_str); |
| 318 #endif | 319 #endif |
| 319 | 320 |
| 320 info->process_start_time = uptime; | 321 info->process_start_time = uptime; |
| 321 info->oom_size = oom_size; | 322 info->oom_size = oom_size; |
| 322 #if defined(OS_ANDROID) | 323 #if defined(OS_ANDROID) |
| 323 // Nothing gets uploaded in android. | 324 // Nothing gets uploaded in android. |
| 324 info->upload = false; | 325 info->upload = false; |
| 325 #else | 326 #else |
| 326 info->upload = upload_; | 327 info->upload = upload_; |
| 327 #endif | 328 #endif |
| 328 | 329 |
| 329 | 330 |
| 330 BrowserThread::GetBlockingPool()->PostSequencedWorkerTask( | 331 BrowserThread::GetBlockingPool()->PostSequencedWorkerTask( |
| 331 worker_pool_token_, | 332 worker_pool_token_, |
| 332 FROM_HERE, | 333 FROM_HERE, |
| 333 base::Bind(&CrashHandlerHostLinux::WriteDumpFile, | 334 base::Bind(&CrashHandlerHostLinux::WriteDumpFile, |
| 334 base::Unretained(this), | 335 base::Unretained(this), |
| 335 base::Passed(&info), | 336 base::Passed(&info), |
| 336 base::Passed(&crash_context), | 337 base::Passed(&crash_context), |
| 337 crashing_pid, | 338 crashing_pid, |
| 338 signal_fd.release())); | 339 signal_fd.release())); |
| 339 } | 340 } |
| 340 | 341 |
| 341 void CrashHandlerHostLinux::WriteDumpFile(scoped_ptr<BreakpadInfo> info, | 342 void CrashHandlerHostLinux::WriteDumpFile(std::unique_ptr<BreakpadInfo> info, |
| 342 scoped_ptr<char[]> crash_context, | 343 std::unique_ptr<char[]> crash_context, |
| 343 pid_t crashing_pid, | 344 pid_t crashing_pid, |
| 344 int signal_fd) { | 345 int signal_fd) { |
| 345 DCHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread( | 346 DCHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread( |
| 346 worker_pool_token_)); | 347 worker_pool_token_)); |
| 347 | 348 |
| 348 // Set |info->distro| here because base::GetLinuxDistro() needs to run on a | 349 // Set |info->distro| here because base::GetLinuxDistro() needs to run on a |
| 349 // blocking thread. | 350 // blocking thread. |
| 350 std::string distro = base::GetLinuxDistro(); | 351 std::string distro = base::GetLinuxDistro(); |
| 351 info->distro_length = distro.length(); | 352 info->distro_length = distro.length(); |
| 352 // Freed in CrashDumpTask(). | 353 // Freed in CrashDumpTask(). |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 info->pid = crashing_pid; | 398 info->pid = crashing_pid; |
| 398 | 399 |
| 399 BrowserThread::PostTask( | 400 BrowserThread::PostTask( |
| 400 BrowserThread::IO, FROM_HERE, | 401 BrowserThread::IO, FROM_HERE, |
| 401 base::Bind(&CrashHandlerHostLinux::QueueCrashDumpTask, | 402 base::Bind(&CrashHandlerHostLinux::QueueCrashDumpTask, |
| 402 base::Unretained(this), | 403 base::Unretained(this), |
| 403 base::Passed(&info), | 404 base::Passed(&info), |
| 404 signal_fd)); | 405 signal_fd)); |
| 405 } | 406 } |
| 406 | 407 |
| 407 void CrashHandlerHostLinux::QueueCrashDumpTask(scoped_ptr<BreakpadInfo> info, | 408 void CrashHandlerHostLinux::QueueCrashDumpTask( |
| 408 int signal_fd) { | 409 std::unique_ptr<BreakpadInfo> info, |
| 410 int signal_fd) { |
| 409 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 411 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 410 | 412 |
| 411 // Send the done signal to the process: it can exit now. | 413 // Send the done signal to the process: it can exit now. |
| 412 struct msghdr msg = {0}; | 414 struct msghdr msg = {0}; |
| 413 struct iovec done_iov; | 415 struct iovec done_iov; |
| 414 done_iov.iov_base = const_cast<char*>("\x42"); | 416 done_iov.iov_base = const_cast<char*>("\x42"); |
| 415 done_iov.iov_len = 1; | 417 done_iov.iov_len = 1; |
| 416 msg.msg_iov = &done_iov; | 418 msg.msg_iov = &done_iov; |
| 417 msg.msg_iovlen = 1; | 419 msg.msg_iovlen = 1; |
| 418 | 420 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 431 // no-ops. | 433 // no-ops. |
| 432 shutting_down_ = true; | 434 shutting_down_ = true; |
| 433 uploader_thread_->Stop(); | 435 uploader_thread_->Stop(); |
| 434 } | 436 } |
| 435 | 437 |
| 436 bool CrashHandlerHostLinux::IsShuttingDown() const { | 438 bool CrashHandlerHostLinux::IsShuttingDown() const { |
| 437 return shutting_down_; | 439 return shutting_down_; |
| 438 } | 440 } |
| 439 | 441 |
| 440 } // namespace breakpad | 442 } // namespace breakpad |
| OLD | NEW |