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 |