OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/browser_child_process_host_impl.h" | 5 #include "content/browser/browser_child_process_host_impl.h" |
6 | 6 |
7 #include "base/base_switches.h" | 7 #include "base/base_switches.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/debug/alias.h" | 10 #include "base/debug/alias.h" |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 const std::string& interface_name, | 305 const std::string& interface_name, |
306 mojo::ScopedMessagePipeHandle interface_pipe) { | 306 mojo::ScopedMessagePipeHandle interface_pipe) { |
307 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 307 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
308 if (!child_connection_) | 308 if (!child_connection_) |
309 return; | 309 return; |
310 | 310 |
311 child_connection_->BindInterface(interface_name, std::move(interface_pipe)); | 311 child_connection_->BindInterface(interface_name, std::move(interface_pipe)); |
312 } | 312 } |
313 | 313 |
314 void BrowserChildProcessHostImpl::HistogramBadMessageTerminated( | 314 void BrowserChildProcessHostImpl::HistogramBadMessageTerminated( |
315 int process_type) { | 315 ProcessType process_type) { |
316 UMA_HISTOGRAM_ENUMERATION("ChildProcess.BadMessgeTerminated", process_type, | 316 UMA_HISTOGRAM_ENUMERATION("ChildProcess.BadMessgeTerminated", process_type, |
317 PROCESS_TYPE_MAX); | 317 PROCESS_TYPE_MAX); |
318 } | 318 } |
319 | 319 |
320 base::TerminationStatus BrowserChildProcessHostImpl::GetTerminationStatus( | 320 base::TerminationStatus BrowserChildProcessHostImpl::GetTerminationStatus( |
321 bool known_dead, int* exit_code) { | 321 bool known_dead, int* exit_code) { |
322 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 322 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
323 if (!child_process_) // If the delegate doesn't use Launch() helper. | 323 if (!child_process_) // If the delegate doesn't use Launch() helper. |
324 return base::GetTerminationStatus(data_.handle, exit_code); | 324 return base::GetTerminationStatus(data_.handle, exit_code); |
325 return child_process_->GetChildTerminationStatus(known_dead, | 325 return child_process_->GetChildTerminationStatus(known_dead, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 | 362 |
363 void BrowserChildProcessHostImpl::OnBadMessageReceived( | 363 void BrowserChildProcessHostImpl::OnBadMessageReceived( |
364 const IPC::Message& message) { | 364 const IPC::Message& message) { |
365 std::string log_message = | 365 std::string log_message = |
366 base::StringPrintf("Bad message received of type: %u", message.type()); | 366 base::StringPrintf("Bad message received of type: %u", message.type()); |
367 TerminateOnBadMessageReceived(log_message); | 367 TerminateOnBadMessageReceived(log_message); |
368 } | 368 } |
369 | 369 |
370 void BrowserChildProcessHostImpl::TerminateOnBadMessageReceived( | 370 void BrowserChildProcessHostImpl::TerminateOnBadMessageReceived( |
371 const std::string& error) { | 371 const std::string& error) { |
372 HistogramBadMessageTerminated(data_.process_type); | 372 HistogramBadMessageTerminated(static_cast<ProcessType>(data_.process_type)); |
373 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 373 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
374 switches::kDisableKillAfterBadIPC)) { | 374 switches::kDisableKillAfterBadIPC)) { |
375 return; | 375 return; |
376 } | 376 } |
377 LOG(ERROR) << "Terminating child process for bad IPC message: " << error; | 377 LOG(ERROR) << "Terminating child process for bad IPC message: " << error; |
378 // Create a memory dump. This will contain enough stack frames to work out | 378 // Create a memory dump. This will contain enough stack frames to work out |
379 // what the bad message was. | 379 // what the bad message was. |
380 base::debug::DumpWithoutCrashing(); | 380 base::debug::DumpWithoutCrashing(); |
381 | 381 |
382 child_process_->GetProcess().Terminate(RESULT_CODE_KILLED_BAD_MESSAGE, false); | 382 child_process_->GetProcess().Terminate(RESULT_CODE_KILLED_BAD_MESSAGE, false); |
(...skipping 19 matching lines...) Expand all Loading... |
402 base::TerminationStatus status = GetTerminationStatus( | 402 base::TerminationStatus status = GetTerminationStatus( |
403 true /* known_dead */, &exit_code); | 403 true /* known_dead */, &exit_code); |
404 switch (status) { | 404 switch (status) { |
405 case base::TERMINATION_STATUS_PROCESS_CRASHED: | 405 case base::TERMINATION_STATUS_PROCESS_CRASHED: |
406 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: { | 406 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: { |
407 delegate_->OnProcessCrashed(exit_code); | 407 delegate_->OnProcessCrashed(exit_code); |
408 BrowserThread::PostTask( | 408 BrowserThread::PostTask( |
409 BrowserThread::UI, FROM_HERE, | 409 BrowserThread::UI, FROM_HERE, |
410 base::Bind(&NotifyProcessCrashed, data_, exit_code)); | 410 base::Bind(&NotifyProcessCrashed, data_, exit_code)); |
411 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Crashed2", | 411 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Crashed2", |
412 data_.process_type, | 412 static_cast<ProcessType>(data_.process_type), |
413 PROCESS_TYPE_MAX); | 413 PROCESS_TYPE_MAX); |
414 break; | 414 break; |
415 } | 415 } |
416 #if defined(OS_ANDROID) | 416 #if defined(OS_ANDROID) |
417 case base::TERMINATION_STATUS_OOM_PROTECTED: | 417 case base::TERMINATION_STATUS_OOM_PROTECTED: |
418 #endif | 418 #endif |
419 #if defined(OS_CHROMEOS) | 419 #if defined(OS_CHROMEOS) |
420 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM: | 420 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM: |
421 #endif | 421 #endif |
422 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: { | 422 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: { |
423 delegate_->OnProcessCrashed(exit_code); | 423 delegate_->OnProcessCrashed(exit_code); |
424 BrowserThread::PostTask( | 424 BrowserThread::PostTask( |
425 BrowserThread::UI, FROM_HERE, | 425 BrowserThread::UI, FROM_HERE, |
426 base::Bind(&NotifyProcessKilled, data_, exit_code)); | 426 base::Bind(&NotifyProcessKilled, data_, exit_code)); |
427 // Report that this child process was killed. | 427 // Report that this child process was killed. |
428 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Killed2", | 428 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Killed2", |
429 data_.process_type, | 429 static_cast<ProcessType>(data_.process_type), |
430 PROCESS_TYPE_MAX); | 430 PROCESS_TYPE_MAX); |
431 break; | 431 break; |
432 } | 432 } |
433 case base::TERMINATION_STATUS_STILL_RUNNING: { | 433 case base::TERMINATION_STATUS_STILL_RUNNING: { |
434 UMA_HISTOGRAM_ENUMERATION("ChildProcess.DisconnectedAlive2", | 434 UMA_HISTOGRAM_ENUMERATION("ChildProcess.DisconnectedAlive2", |
435 data_.process_type, | 435 static_cast<ProcessType>(data_.process_type), |
436 PROCESS_TYPE_MAX); | 436 PROCESS_TYPE_MAX); |
437 } | 437 } |
438 default: | 438 default: |
439 break; | 439 break; |
440 } | 440 } |
441 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Disconnected2", | 441 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Disconnected2", |
442 data_.process_type, | 442 static_cast<ProcessType>(data_.process_type), |
443 PROCESS_TYPE_MAX); | 443 PROCESS_TYPE_MAX); |
444 #if defined(OS_CHROMEOS) | 444 #if defined(OS_CHROMEOS) |
445 if (status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM) { | 445 if (status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM) { |
446 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Killed2.OOM", | 446 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Killed2.OOM", |
447 data_.process_type, | 447 static_cast<ProcessType>(data_.process_type), |
448 PROCESS_TYPE_MAX); | 448 PROCESS_TYPE_MAX); |
449 } | 449 } |
450 #endif | 450 #endif |
451 } | 451 } |
452 channel_ = nullptr; | 452 channel_ = nullptr; |
453 delete delegate_; // Will delete us | 453 delete delegate_; // Will delete us |
454 } | 454 } |
455 | 455 |
456 bool BrowserChildProcessHostImpl::Send(IPC::Message* message) { | 456 bool BrowserChildProcessHostImpl::Send(IPC::Message* message) { |
457 return child_process_host_->Send(message); | 457 return child_process_host_->Send(message); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | 577 scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
578 const std::string& error) { | 578 const std::string& error) { |
579 if (!task_runner->BelongsToCurrentThread()) { | 579 if (!task_runner->BelongsToCurrentThread()) { |
580 task_runner->PostTask( | 580 task_runner->PostTask( |
581 FROM_HERE, base::Bind(&BrowserChildProcessHostImpl::OnMojoError, | 581 FROM_HERE, base::Bind(&BrowserChildProcessHostImpl::OnMojoError, |
582 process, task_runner, error)); | 582 process, task_runner, error)); |
583 return; | 583 return; |
584 } | 584 } |
585 if (!process) | 585 if (!process) |
586 return; | 586 return; |
587 HistogramBadMessageTerminated(process->data_.process_type); | 587 HistogramBadMessageTerminated( |
| 588 static_cast<ProcessType>(process->data_.process_type)); |
588 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 589 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
589 switches::kDisableKillAfterBadIPC)) { | 590 switches::kDisableKillAfterBadIPC)) { |
590 return; | 591 return; |
591 } | 592 } |
592 LOG(ERROR) << "Terminating child process for bad Mojo message: " << error; | 593 LOG(ERROR) << "Terminating child process for bad Mojo message: " << error; |
593 | 594 |
594 // Create a memory dump with the error message aliased. This will make it easy | 595 // Create a memory dump with the error message aliased. This will make it easy |
595 // to determine details about what interface call failed. | 596 // to determine details about what interface call failed. |
596 base::debug::Alias(&error); | 597 base::debug::Alias(&error); |
597 base::debug::DumpWithoutCrashing(); | 598 base::debug::DumpWithoutCrashing(); |
598 process->child_process_->GetProcess().Terminate( | 599 process->child_process_->GetProcess().Terminate( |
599 RESULT_CODE_KILLED_BAD_MESSAGE, false); | 600 RESULT_CODE_KILLED_BAD_MESSAGE, false); |
600 } | 601 } |
601 | 602 |
602 #if defined(OS_WIN) | 603 #if defined(OS_WIN) |
603 | 604 |
604 void BrowserChildProcessHostImpl::OnObjectSignaled(HANDLE object) { | 605 void BrowserChildProcessHostImpl::OnObjectSignaled(HANDLE object) { |
605 OnChildDisconnected(); | 606 OnChildDisconnected(); |
606 } | 607 } |
607 | 608 |
608 #endif | 609 #endif |
609 | 610 |
610 } // namespace content | 611 } // namespace content |
OLD | NEW |