Chromium Code Reviews| 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 "chrome/browser/nacl_host/nacl_process_host.h" | 5 #include "chrome/browser/nacl_host/nacl_process_host.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 103 handles_for_sel_ldr->push_back(channel); | 103 handles_for_sel_ldr->push_back(channel); |
| 104 #endif | 104 #endif |
| 105 return true; | 105 return true; |
| 106 } | 106 } |
| 107 | 107 |
| 108 } // namespace | 108 } // namespace |
| 109 | 109 |
| 110 struct NaClProcessHost::NaClInternal { | 110 struct NaClProcessHost::NaClInternal { |
| 111 std::vector<nacl::Handle> sockets_for_renderer; | 111 std::vector<nacl::Handle> sockets_for_renderer; |
| 112 std::vector<nacl::Handle> sockets_for_sel_ldr; | 112 std::vector<nacl::Handle> sockets_for_sel_ldr; |
| 113 std::vector<nacl::FileDescriptor> handles_for_renderer; | |
| 113 }; | 114 }; |
| 114 | 115 |
| 115 // ----------------------------------------------------------------------------- | 116 // ----------------------------------------------------------------------------- |
| 116 | 117 |
| 117 NaClProcessHost::NaClProcessHost(const GURL& manifest_url) | 118 NaClProcessHost::NaClProcessHost(const GURL& manifest_url) |
| 118 : manifest_url_(manifest_url), | 119 : manifest_url_(manifest_url), |
| 119 #if defined(OS_WIN) | 120 #if defined(OS_WIN) |
| 120 process_launched_by_broker_(false), | 121 process_launched_by_broker_(false), |
| 121 #elif defined(OS_LINUX) | 122 #elif defined(OS_LINUX) |
| 122 wait_for_nacl_gdb_(false), | 123 wait_for_nacl_gdb_(false), |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 515 bool handled = true; | 516 bool handled = true; |
| 516 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) | 517 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) |
| 517 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate, | 518 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate, |
| 518 OnQueryKnownToValidate) | 519 OnQueryKnownToValidate) |
| 519 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, | 520 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, |
| 520 OnSetKnownToValidate) | 521 OnSetKnownToValidate) |
| 521 #if defined(OS_WIN) | 522 #if defined(OS_WIN) |
| 522 IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_AttachDebugExceptionHandler, | 523 IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_AttachDebugExceptionHandler, |
| 523 OnAttachDebugExceptionHandler) | 524 OnAttachDebugExceptionHandler) |
| 524 #endif | 525 #endif |
| 526 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelCreated, | |
| 527 OnPpapiChannelCreated) | |
| 525 IPC_MESSAGE_UNHANDLED(handled = false) | 528 IPC_MESSAGE_UNHANDLED(handled = false) |
| 526 IPC_END_MESSAGE_MAP() | 529 IPC_END_MESSAGE_MAP() |
| 527 return handled; | 530 return handled; |
| 528 } | 531 } |
| 529 | 532 |
| 530 void NaClProcessHost::OnProcessCrashed(int exit_code) { | 533 void NaClProcessHost::OnProcessCrashed(int exit_code) { |
| 531 std::string message = base::StringPrintf( | 534 std::string message = base::StringPrintf( |
| 532 "NaCl process exited with status %i (0x%x)", exit_code, exit_code); | 535 "NaCl process exited with status %i (0x%x)", exit_code, exit_code); |
| 533 LOG(ERROR) << message; | 536 LOG(ERROR) << message; |
| 534 } | 537 } |
| 535 | 538 |
| 536 void NaClProcessHost::OnProcessLaunched() { | 539 void NaClProcessHost::OnProcessLaunched() { |
| 537 if (!StartWithLaunchedProcess()) | 540 if (!StartWithLaunchedProcess()) |
| 538 delete this; | 541 delete this; |
| 539 } | 542 } |
| 540 | 543 |
| 541 // The asynchronous attempt to get the IRT file open has completed. | 544 // The asynchronous attempt to get the IRT file open has completed. |
| 542 void NaClProcessHost::IrtReady() { | 545 void NaClProcessHost::IrtReady() { |
| 543 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 546 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
| 544 if (!nacl_browser->IrtAvailable() || !SendStart()) { | 547 if (!nacl_browser->IrtAvailable() || !SendStart()) { |
| 545 DLOG(ERROR) << "Cannot launch NaCl process"; | 548 DLOG(ERROR) << "Cannot launch NaCl process"; |
| 546 delete this; | 549 delete this; |
| 547 } | 550 } |
| 548 } | 551 } |
| 549 | 552 |
| 550 bool NaClProcessHost::ReplyToRenderer() { | 553 bool NaClProcessHost::SendStart() { |
| 551 std::vector<nacl::FileDescriptor> handles_for_renderer; | |
| 552 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { | 554 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { |
| 553 #if defined(OS_WIN) | 555 #if defined(OS_WIN) |
| 554 // Copy the handle into the renderer process. | 556 // Copy the handle into the renderer process. |
| 555 HANDLE handle_in_renderer; | 557 HANDLE handle_in_renderer; |
| 556 if (!DuplicateHandle(base::GetCurrentProcessHandle(), | 558 if (!DuplicateHandle(base::GetCurrentProcessHandle(), |
| 557 reinterpret_cast<HANDLE>( | 559 reinterpret_cast<HANDLE>( |
| 558 internal_->sockets_for_renderer[i]), | 560 internal_->sockets_for_renderer[i]), |
| 559 chrome_render_message_filter_->peer_handle(), | 561 chrome_render_message_filter_->peer_handle(), |
| 560 &handle_in_renderer, | 562 &handle_in_renderer, |
| 561 0, // Unused given DUPLICATE_SAME_ACCESS. | 563 0, // Unused given DUPLICATE_SAME_ACCESS. |
| 562 FALSE, | 564 FALSE, |
| 563 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { | 565 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { |
| 564 DLOG(ERROR) << "DuplicateHandle() failed"; | 566 DLOG(ERROR) << "DuplicateHandle() failed"; |
| 565 return false; | 567 return false; |
| 566 } | 568 } |
| 567 handles_for_renderer.push_back( | 569 internal_->handles_for_renderer.push_back( |
| 568 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer)); | 570 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer)); |
| 569 #else | 571 #else |
| 570 // No need to dup the imc_handle - we don't pass it anywhere else so | 572 // No need to dup the imc_handle - we don't pass it anywhere else so |
| 571 // it cannot be closed. | 573 // it cannot be closed. |
| 572 nacl::FileDescriptor imc_handle; | 574 nacl::FileDescriptor imc_handle; |
| 573 imc_handle.fd = internal_->sockets_for_renderer[i]; | 575 imc_handle.fd = internal_->sockets_for_renderer[i]; |
| 574 imc_handle.auto_close = true; | 576 imc_handle.auto_close = true; |
| 575 handles_for_renderer.push_back(imc_handle); | 577 internal_->handles_for_renderer.push_back(imc_handle); |
| 576 #endif | 578 #endif |
| 577 } | 579 } |
| 578 | 580 |
| 581 const ChildProcessData& data = process_->GetData(); | |
| 579 #if defined(OS_WIN) | 582 #if defined(OS_WIN) |
| 580 // If we are on 64-bit Windows, the NaCl process's sandbox is | 583 // If we are on 64-bit Windows, the NaCl process's sandbox is |
| 581 // managed by a different process from the renderer's sandbox. We | 584 // managed by a different process from the renderer's sandbox. We |
| 582 // need to inform the renderer's sandbox about the NaCl process so | 585 // need to inform the renderer's sandbox about the NaCl process so |
| 583 // that the renderer can send handles to the NaCl process using | 586 // that the renderer can send handles to the NaCl process using |
| 584 // BrokerDuplicateHandle(). | 587 // BrokerDuplicateHandle(). |
| 585 if (RunningOnWOW64()) { | 588 if (RunningOnWOW64()) { |
| 586 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) { | 589 if (!content::BrokerAddTargetPeer(data.handle)) { |
| 587 DLOG(ERROR) << "Failed to add NaCl process PID"; | 590 DLOG(ERROR) << "Failed to add NaCl process PID"; |
| 588 return false; | 591 return false; |
| 589 } | 592 } |
| 590 } | 593 } |
| 591 #endif | 594 #endif |
| 592 | 595 |
| 593 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams( | |
| 594 reply_msg_, handles_for_renderer); | |
| 595 chrome_render_message_filter_->Send(reply_msg_); | |
| 596 chrome_render_message_filter_ = NULL; | |
| 597 reply_msg_ = NULL; | |
| 598 internal_->sockets_for_renderer.clear(); | |
| 599 return true; | |
| 600 } | |
| 601 | |
| 602 bool NaClProcessHost::StartNaClExecution() { | |
| 603 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 596 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
| 604 | 597 |
| 605 nacl::NaClStartParams params; | 598 nacl::NaClStartParams params; |
| 606 params.validation_cache_key = | 599 params.validation_cache_key = |
| 607 nacl_browser->validation_cache.GetValidationCacheKey(); | 600 nacl_browser->validation_cache.GetValidationCacheKey(); |
| 608 params.version = chrome::VersionInfo().CreateVersionString(); | 601 params.version = chrome::VersionInfo().CreateVersionString(); |
| 609 params.enable_exception_handling = enable_exception_handling_; | 602 params.enable_exception_handling = enable_exception_handling_; |
| 610 | 603 |
|
dmichael (off chromium)
2012/05/23 21:24:12
I think you need to set params.enable_ipc_proxy he
bbudge
2012/05/23 21:42:20
Done. Thanks for tracking this down.
| |
| 611 base::PlatformFile irt_file = nacl_browser->IrtFile(); | 604 base::PlatformFile irt_file = nacl_browser->IrtFile(); |
| 612 CHECK_NE(irt_file, base::kInvalidPlatformFileValue); | 605 CHECK_NE(irt_file, base::kInvalidPlatformFileValue); |
| 613 | 606 |
| 614 const ChildProcessData& data = process_->GetData(); | |
| 615 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { | 607 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { |
| 616 if (!ShareHandleToSelLdr(data.handle, | 608 if (!ShareHandleToSelLdr(data.handle, |
| 617 internal_->sockets_for_sel_ldr[i], true, | 609 internal_->sockets_for_sel_ldr[i], true, |
| 618 ¶ms.handles)) { | 610 ¶ms.handles)) { |
| 619 return false; | 611 return false; |
| 620 } | 612 } |
| 621 } | 613 } |
| 622 | 614 |
| 623 // Send over the IRT file handle. We don't close our own copy! | 615 // Send over the IRT file handle. We don't close our own copy! |
| 624 if (!ShareHandleToSelLdr(data.handle, irt_file, false, ¶ms.handles)) | 616 if (!ShareHandleToSelLdr(data.handle, irt_file, false, ¶ms.handles)) |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 640 nacl::FileDescriptor memory_fd; | 632 nacl::FileDescriptor memory_fd; |
| 641 memory_fd.fd = dup(memory_buffer.handle().fd); | 633 memory_fd.fd = dup(memory_buffer.handle().fd); |
| 642 if (memory_fd.fd < 0) { | 634 if (memory_fd.fd < 0) { |
| 643 DLOG(ERROR) << "Failed to dup() a file descriptor"; | 635 DLOG(ERROR) << "Failed to dup() a file descriptor"; |
| 644 return false; | 636 return false; |
| 645 } | 637 } |
| 646 memory_fd.auto_close = true; | 638 memory_fd.auto_close = true; |
| 647 params.handles.push_back(memory_fd); | 639 params.handles.push_back(memory_fd); |
| 648 #endif | 640 #endif |
| 649 | 641 |
| 642 // The start message should only be sent once we are sure we won't delete | |
| 643 // ourselves. | |
| 650 process_->Send(new NaClProcessMsg_Start(params)); | 644 process_->Send(new NaClProcessMsg_Start(params)); |
| 651 | 645 |
| 652 internal_->sockets_for_sel_ldr.clear(); | 646 internal_->sockets_for_sel_ldr.clear(); |
| 647 | |
| 648 // If we aren't creating the IPC channel, send the reply message without | |
| 649 // waiting for the NaCl process to signal that it's ready. | |
| 650 if (!CommandLine::ForCurrentProcess()->HasSwitch( | |
| 651 switches::kEnableNaClIPCProxy)) { | |
| 652 OnPpapiChannelCreated(IPC::ChannelHandle()); | |
| 653 } | |
| 654 | |
| 653 return true; | 655 return true; |
| 654 } | 656 } |
| 655 | 657 |
| 656 bool NaClProcessHost::SendStart() { | 658 void NaClProcessHost::OnPpapiChannelCreated( |
| 657 return ReplyToRenderer() && StartNaClExecution(); | 659 const IPC::ChannelHandle& channel_handle) { |
| 660 // Now that the server end of the channel has been created, send the reply to | |
| 661 // the renderer. | |
| 662 base::ProcessId nacl_process_id = base::GetProcId(process_->GetData().handle); | |
| 663 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams( | |
| 664 reply_msg_, internal_->handles_for_renderer, channel_handle, | |
| 665 nacl_process_id); | |
| 666 chrome_render_message_filter_->Send(reply_msg_); | |
| 667 chrome_render_message_filter_ = NULL; | |
| 668 reply_msg_ = NULL; | |
| 669 | |
| 670 internal_->sockets_for_renderer.clear(); | |
| 671 internal_->handles_for_renderer.clear(); | |
| 658 } | 672 } |
| 659 | 673 |
| 660 bool NaClProcessHost::StartWithLaunchedProcess() { | 674 bool NaClProcessHost::StartWithLaunchedProcess() { |
| 661 #if defined(OS_LINUX) | 675 #if defined(OS_LINUX) |
| 662 if (wait_for_nacl_gdb_) { | 676 if (wait_for_nacl_gdb_) { |
| 663 if (LaunchNaClGdb(base::GetProcId(process_->GetData().handle))) { | 677 if (LaunchNaClGdb(base::GetProcId(process_->GetData().handle))) { |
| 664 // We will be called with wait_for_nacl_gdb_ = false once debugger is | 678 // We will be called with wait_for_nacl_gdb_ = false once debugger is |
| 665 // attached to the program. | 679 // attached to the program. |
| 666 return true; | 680 return true; |
| 667 } | 681 } |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 749 } else { | 763 } else { |
| 750 NaClStartDebugExceptionHandlerThread( | 764 NaClStartDebugExceptionHandlerThread( |
| 751 process_handle.Take(), info, | 765 process_handle.Take(), info, |
| 752 base::MessageLoopProxy::current(), | 766 base::MessageLoopProxy::current(), |
| 753 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, | 767 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, |
| 754 weak_factory_.GetWeakPtr())); | 768 weak_factory_.GetWeakPtr())); |
| 755 return true; | 769 return true; |
| 756 } | 770 } |
| 757 } | 771 } |
| 758 #endif | 772 #endif |
| OLD | NEW |