Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(489)

Side by Side Diff: chrome/browser/nacl_host/nacl_process_host.cc

Issue 18045007: Show more different NaCl loading errors. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: rebase Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/nacl_host/nacl_process_host.h ('k') | chrome/common/nacl_host_messages.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 const base::FilePath& manifest_path) { 282 const base::FilePath& manifest_path) {
283 nacl_host_message_filter_ = nacl_host_message_filter; 283 nacl_host_message_filter_ = nacl_host_message_filter;
284 reply_msg_ = reply_msg; 284 reply_msg_ = reply_msg;
285 manifest_path_ = manifest_path; 285 manifest_path_ = manifest_path;
286 286
287 // Start getting the IRT open asynchronously while we launch the NaCl process. 287 // Start getting the IRT open asynchronously while we launch the NaCl process.
288 // We'll make sure this actually finished in StartWithLaunchedProcess, below. 288 // We'll make sure this actually finished in StartWithLaunchedProcess, below.
289 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 289 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
290 nacl_browser->EnsureAllResourcesAvailable(); 290 nacl_browser->EnsureAllResourcesAvailable();
291 if (!nacl_browser->IsOk()) { 291 if (!nacl_browser->IsOk()) {
292 LOG(ERROR) << "NaCl process launch failed: could not find all the " 292 SendErrorToRenderer("could not find all the resources needed"
293 "resources needed to launch the process"; 293 " to launch the process");
294 delete this; 294 delete this;
295 return; 295 return;
296 } 296 }
297 297
298 // Rather than creating a socket pair in the renderer, and passing 298 // Rather than creating a socket pair in the renderer, and passing
299 // one side through the browser to sel_ldr, socket pairs are created 299 // one side through the browser to sel_ldr, socket pairs are created
300 // in the browser and then passed to the renderer and sel_ldr. 300 // in the browser and then passed to the renderer and sel_ldr.
301 // 301 //
302 // This is mainly for the benefit of Windows, where sockets cannot 302 // This is mainly for the benefit of Windows, where sockets cannot
303 // be passed in messages, but are copied via DuplicateHandle(). 303 // be passed in messages, but are copied via DuplicateHandle().
304 // This means the sandboxed renderer cannot send handles to the 304 // This means the sandboxed renderer cannot send handles to the
305 // browser process. 305 // browser process.
306 306
307 NaClHandle pair[2]; 307 NaClHandle pair[2];
308 // Create a connected socket 308 // Create a connected socket
309 if (NaClSocketPair(pair) == -1) { 309 if (NaClSocketPair(pair) == -1) {
310 LOG(ERROR) << "NaCl process launch failed: could not create a socket pair"; 310 SendErrorToRenderer("NaClSocketPair() failed");
311 delete this; 311 delete this;
312 return; 312 return;
313 } 313 }
314 internal_->socket_for_renderer = pair[0]; 314 internal_->socket_for_renderer = pair[0];
315 internal_->socket_for_sel_ldr = pair[1]; 315 internal_->socket_for_sel_ldr = pair[1];
316 SetCloseOnExec(pair[0]); 316 SetCloseOnExec(pair[0]);
317 SetCloseOnExec(pair[1]); 317 SetCloseOnExec(pair[1]);
318 318
319 // Launch the process 319 // Launch the process
320 if (!LaunchSelLdr()) { 320 if (!LaunchSelLdr()) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 if (!script.empty()) { 386 if (!script.empty()) {
387 cmd_line.AppendArg("--command"); 387 cmd_line.AppendArg("--command");
388 cmd_line.AppendArgNative(script.value()); 388 cmd_line.AppendArgNative(script.value());
389 } 389 }
390 return base::LaunchProcess(cmd_line, base::LaunchOptions(), NULL); 390 return base::LaunchProcess(cmd_line, base::LaunchOptions(), NULL);
391 } 391 }
392 392
393 bool NaClProcessHost::LaunchSelLdr() { 393 bool NaClProcessHost::LaunchSelLdr() {
394 std::string channel_id = process_->GetHost()->CreateChannel(); 394 std::string channel_id = process_->GetHost()->CreateChannel();
395 if (channel_id.empty()) { 395 if (channel_id.empty()) {
396 LOG(ERROR) << "NaCl process launch failed: could not create channel"; 396 SendErrorToRenderer("CreateChannel() failed");
397 return false; 397 return false;
398 } 398 }
399 399
400 CommandLine::StringType nacl_loader_prefix; 400 CommandLine::StringType nacl_loader_prefix;
401 #if defined(OS_POSIX) 401 #if defined(OS_POSIX)
402 nacl_loader_prefix = CommandLine::ForCurrentProcess()->GetSwitchValueNative( 402 nacl_loader_prefix = CommandLine::ForCurrentProcess()->GetSwitchValueNative(
403 switches::kNaClLoaderCmdPrefix); 403 switches::kNaClLoaderCmdPrefix);
404 #endif // defined(OS_POSIX) 404 #endif // defined(OS_POSIX)
405 405
406 // Build command line for nacl. 406 // Build command line for nacl.
(...skipping 14 matching lines...) Expand all
421 #endif 421 #endif
422 422
423 base::FilePath exe_path = ChildProcessHost::GetChildPath(flags); 423 base::FilePath exe_path = ChildProcessHost::GetChildPath(flags);
424 if (exe_path.empty()) 424 if (exe_path.empty())
425 return false; 425 return false;
426 426
427 #if defined(OS_WIN) 427 #if defined(OS_WIN)
428 // On Windows 64-bit NaCl loader is called nacl64.exe instead of chrome.exe 428 // On Windows 64-bit NaCl loader is called nacl64.exe instead of chrome.exe
429 if (RunningOnWOW64()) { 429 if (RunningOnWOW64()) {
430 if (!NaClBrowser::GetInstance()->GetNaCl64ExePath(&exe_path)) { 430 if (!NaClBrowser::GetInstance()->GetNaCl64ExePath(&exe_path)) {
431 SendErrorToRenderer("could not get path to nacl64.exe");
431 return false; 432 return false;
432 } 433 }
433 } 434 }
434 #endif 435 #endif
435 436
436 scoped_ptr<CommandLine> cmd_line(new CommandLine(exe_path)); 437 scoped_ptr<CommandLine> cmd_line(new CommandLine(exe_path));
437 nacl::CopyNaClCommandLineArguments(cmd_line.get()); 438 nacl::CopyNaClCommandLineArguments(cmd_line.get());
438 439
439 cmd_line->AppendSwitchASCII(switches::kProcessType, 440 cmd_line->AppendSwitchASCII(switches::kProcessType,
440 switches::kNaClLoaderProcess); 441 switches::kNaClLoaderProcess);
441 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); 442 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id);
442 if (NaClBrowser::GetDelegate()->DialogsAreSuppressed()) 443 if (NaClBrowser::GetDelegate()->DialogsAreSuppressed())
443 cmd_line->AppendSwitch(switches::kNoErrorDialogs); 444 cmd_line->AppendSwitch(switches::kNoErrorDialogs);
444 445
445 if (!nacl_loader_prefix.empty()) 446 if (!nacl_loader_prefix.empty())
446 cmd_line->PrependWrapper(nacl_loader_prefix); 447 cmd_line->PrependWrapper(nacl_loader_prefix);
447 448
448 // On Windows we might need to start the broker process to launch a new loader 449 // On Windows we might need to start the broker process to launch a new loader
449 #if defined(OS_WIN) 450 #if defined(OS_WIN)
450 if (RunningOnWOW64()) { 451 if (RunningOnWOW64()) {
451 if (!NaClBrokerService::GetInstance()->LaunchLoader( 452 if (!NaClBrokerService::GetInstance()->LaunchLoader(
452 weak_factory_.GetWeakPtr(), channel_id)) { 453 weak_factory_.GetWeakPtr(), channel_id)) {
453 LOG(ERROR) << "NaCl process launch failed: broker service did not launch " 454 SendErrorToRenderer("broker service did not launch process");
454 "process";
455 return false; 455 return false;
456 } 456 }
457 } else { 457 } else {
458 process_->Launch(new NaClSandboxedProcessLauncherDelegate, 458 process_->Launch(new NaClSandboxedProcessLauncherDelegate,
459 cmd_line.release()); 459 cmd_line.release());
460 } 460 }
461 #elif defined(OS_POSIX) 461 #elif defined(OS_POSIX)
462 process_->Launch(nacl_loader_prefix.empty(), // use_zygote 462 process_->Launch(nacl_loader_prefix.empty(), // use_zygote
463 base::EnvironmentVector(), 463 base::EnvironmentVector(),
464 cmd_line.release()); 464 cmd_line.release());
(...skipping 24 matching lines...) Expand all
489 489
490 void NaClProcessHost::OnProcessLaunched() { 490 void NaClProcessHost::OnProcessLaunched() {
491 if (!StartWithLaunchedProcess()) 491 if (!StartWithLaunchedProcess())
492 delete this; 492 delete this;
493 } 493 }
494 494
495 // Called when the NaClBrowser singleton has been fully initialized. 495 // Called when the NaClBrowser singleton has been fully initialized.
496 void NaClProcessHost::OnResourcesReady() { 496 void NaClProcessHost::OnResourcesReady() {
497 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 497 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
498 if (!nacl_browser->IsReady()) { 498 if (!nacl_browser->IsReady()) {
499 LOG(ERROR) << "NaCl process launch failed: could not acquire shared " 499 SendErrorToRenderer("could not acquire shared resources needed by NaCl");
500 "resources needed by NaCl";
501 delete this; 500 delete this;
502 } else if (!SendStart()) { 501 } else if (!SendStart()) {
503 delete this; 502 delete this;
504 } 503 }
505 } 504 }
506 505
507 bool NaClProcessHost::ReplyToRenderer( 506 bool NaClProcessHost::ReplyToRenderer(
508 const IPC::ChannelHandle& channel_handle) { 507 const IPC::ChannelHandle& channel_handle) {
509 #if defined(OS_WIN) 508 #if defined(OS_WIN)
510 // If we are on 64-bit Windows, the NaCl process's sandbox is 509 // If we are on 64-bit Windows, the NaCl process's sandbox is
511 // managed by a different process from the renderer's sandbox. We 510 // managed by a different process from the renderer's sandbox. We
512 // need to inform the renderer's sandbox about the NaCl process so 511 // need to inform the renderer's sandbox about the NaCl process so
513 // that the renderer can send handles to the NaCl process using 512 // that the renderer can send handles to the NaCl process using
514 // BrokerDuplicateHandle(). 513 // BrokerDuplicateHandle().
515 if (RunningOnWOW64()) { 514 if (RunningOnWOW64()) {
516 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) { 515 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) {
517 LOG(ERROR) << "Failed to add NaCl process PID"; 516 SendErrorToRenderer("BrokerAddTargetPeer() failed");
518 return false; 517 return false;
519 } 518 }
520 } 519 }
521 #endif 520 #endif
522 521
523 nacl::FileDescriptor handle_for_renderer; 522 nacl::FileDescriptor handle_for_renderer;
524 #if defined(OS_WIN) 523 #if defined(OS_WIN)
525 // Copy the handle into the renderer process. 524 // Copy the handle into the renderer process.
526 HANDLE handle_in_renderer; 525 HANDLE handle_in_renderer;
527 if (!DuplicateHandle(base::GetCurrentProcessHandle(), 526 if (!DuplicateHandle(base::GetCurrentProcessHandle(),
528 reinterpret_cast<HANDLE>( 527 reinterpret_cast<HANDLE>(
529 internal_->socket_for_renderer), 528 internal_->socket_for_renderer),
530 nacl_host_message_filter_->PeerHandle(), 529 nacl_host_message_filter_->PeerHandle(),
531 &handle_in_renderer, 530 &handle_in_renderer,
532 0, // Unused given DUPLICATE_SAME_ACCESS. 531 0, // Unused given DUPLICATE_SAME_ACCESS.
533 FALSE, 532 FALSE,
534 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { 533 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
535 LOG(ERROR) << "DuplicateHandle() failed"; 534 SendErrorToRenderer("DuplicateHandle() failed");
536 return false; 535 return false;
537 } 536 }
538 handle_for_renderer = reinterpret_cast<nacl::FileDescriptor>( 537 handle_for_renderer = reinterpret_cast<nacl::FileDescriptor>(
539 handle_in_renderer); 538 handle_in_renderer);
540 #else 539 #else
541 // No need to dup the imc_handle - we don't pass it anywhere else so 540 // No need to dup the imc_handle - we don't pass it anywhere else so
542 // it cannot be closed. 541 // it cannot be closed.
543 nacl::FileDescriptor imc_handle; 542 nacl::FileDescriptor imc_handle;
544 imc_handle.fd = internal_->socket_for_renderer; 543 imc_handle.fd = internal_->socket_for_renderer;
545 imc_handle.auto_close = true; 544 imc_handle.auto_close = true;
546 handle_for_renderer = imc_handle; 545 handle_for_renderer = imc_handle;
547 #endif 546 #endif
548 547
549 const ChildProcessData& data = process_->GetData(); 548 const ChildProcessData& data = process_->GetData();
550 NaClHostMsg_LaunchNaCl::WriteReplyParams( 549 SendMessageToRenderer(
551 reply_msg_, handle_for_renderer, 550 nacl::NaClLaunchResult(handle_for_renderer,
552 channel_handle, base::GetProcId(data.handle), data.id); 551 channel_handle,
553 nacl_host_message_filter_->Send(reply_msg_); 552 base::GetProcId(data.handle),
554 nacl_host_message_filter_ = NULL; 553 data.id),
555 reply_msg_ = NULL; 554 std::string() /* error_message */);
556 internal_->socket_for_renderer = NACL_INVALID_HANDLE; 555 internal_->socket_for_renderer = NACL_INVALID_HANDLE;
557 return true; 556 return true;
558 } 557 }
559 558
559 void NaClProcessHost::SendErrorToRenderer(const std::string& error_message) {
560 LOG(ERROR) << "NaCl process launch failed: " << error_message;
561 SendMessageToRenderer(nacl::NaClLaunchResult(), error_message);
562 }
563
564 void NaClProcessHost::SendMessageToRenderer(
565 const nacl::NaClLaunchResult& result,
566 const std::string& error_message) {
567 DCHECK(nacl_host_message_filter_);
568 DCHECK(reply_msg_);
569 if (nacl_host_message_filter_ != NULL && reply_msg_ != NULL) {
570 NaClHostMsg_LaunchNaCl::WriteReplyParams(
571 reply_msg_, result, error_message);
572 nacl_host_message_filter_->Send(reply_msg_);
573 nacl_host_message_filter_ = NULL;
574 reply_msg_ = NULL;
575 }
576 }
577
560 // TCP port we chose for NaCl debug stub. It can be any other number. 578 // TCP port we chose for NaCl debug stub. It can be any other number.
561 static const int kDebugStubPort = 4014; 579 static const int kDebugStubPort = 4014;
562 580
563 #if defined(OS_POSIX) 581 #if defined(OS_POSIX)
564 SocketDescriptor NaClProcessHost::GetDebugStubSocketHandle() { 582 SocketDescriptor NaClProcessHost::GetDebugStubSocketHandle() {
565 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 583 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
566 SocketDescriptor s; 584 SocketDescriptor s;
567 // We allocate currently unused TCP port for debug stub tests. The port 585 // We allocate currently unused TCP port for debug stub tests. The port
568 // number is passed to the test via debug stub port listener. 586 // number is passed to the test via debug stub port listener.
569 if (nacl_browser->HasGdbDebugStubPortListener()) { 587 if (nacl_browser->HasGdbDebugStubPortListener()) {
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 766 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
749 767
750 if (nacl_browser->IsReady()) { 768 if (nacl_browser->IsReady()) {
751 return SendStart(); 769 return SendStart();
752 } else if (nacl_browser->IsOk()) { 770 } else if (nacl_browser->IsOk()) {
753 nacl_browser->WaitForResources( 771 nacl_browser->WaitForResources(
754 base::Bind(&NaClProcessHost::OnResourcesReady, 772 base::Bind(&NaClProcessHost::OnResourcesReady,
755 weak_factory_.GetWeakPtr())); 773 weak_factory_.GetWeakPtr()));
756 return true; 774 return true;
757 } else { 775 } else {
758 LOG(ERROR) << "NaCl process failed to launch: previously failed to acquire " 776 SendErrorToRenderer("previously failed to acquire shared resources");
759 "shared resources";
760 return false; 777 return false;
761 } 778 }
762 } 779 }
763 780
764 void NaClProcessHost::OnQueryKnownToValidate(const std::string& signature, 781 void NaClProcessHost::OnQueryKnownToValidate(const std::string& signature,
765 bool* result) { 782 bool* result) {
766 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 783 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
767 *result = nacl_browser->QueryKnownToValidate(signature, off_the_record_); 784 *result = nacl_browser->QueryKnownToValidate(signature, off_the_record_);
768 } 785 }
769 786
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 } else { 929 } else {
913 NaClStartDebugExceptionHandlerThread( 930 NaClStartDebugExceptionHandlerThread(
914 process_handle.Take(), info, 931 process_handle.Take(), info,
915 base::MessageLoopProxy::current(), 932 base::MessageLoopProxy::current(),
916 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, 933 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker,
917 weak_factory_.GetWeakPtr())); 934 weak_factory_.GetWeakPtr()));
918 return true; 935 return true;
919 } 936 }
920 } 937 }
921 #endif 938 #endif
OLDNEW
« no previous file with comments | « chrome/browser/nacl_host/nacl_process_host.h ('k') | chrome/common/nacl_host_messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698