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

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: 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
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("internal error: could not create a channel"
Mark Seaborn 2013/07/17 18:21:49 This error message is actually misleading. NaClSo
halyavin 2013/07/18 09:32:22 Done.
311 " between NaCl and renderer");
311 delete this; 312 delete this;
312 return; 313 return;
313 } 314 }
314 internal_->socket_for_renderer = pair[0]; 315 internal_->socket_for_renderer = pair[0];
315 internal_->socket_for_sel_ldr = pair[1]; 316 internal_->socket_for_sel_ldr = pair[1];
316 SetCloseOnExec(pair[0]); 317 SetCloseOnExec(pair[0]);
317 SetCloseOnExec(pair[1]); 318 SetCloseOnExec(pair[1]);
318 319
319 // Launch the process 320 // Launch the process
320 if (!LaunchSelLdr()) { 321 if (!LaunchSelLdr()) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 if (!script.empty()) { 387 if (!script.empty()) {
387 cmd_line.AppendArg("--command"); 388 cmd_line.AppendArg("--command");
388 cmd_line.AppendArgNative(script.value()); 389 cmd_line.AppendArgNative(script.value());
389 } 390 }
390 return base::LaunchProcess(cmd_line, base::LaunchOptions(), NULL); 391 return base::LaunchProcess(cmd_line, base::LaunchOptions(), NULL);
391 } 392 }
392 393
393 bool NaClProcessHost::LaunchSelLdr() { 394 bool NaClProcessHost::LaunchSelLdr() {
394 std::string channel_id = process_->GetHost()->CreateChannel(); 395 std::string channel_id = process_->GetHost()->CreateChannel();
395 if (channel_id.empty()) { 396 if (channel_id.empty()) {
396 LOG(ERROR) << "NaCl process launch failed: could not create channel"; 397 SendErrorToRenderer("could not create IPC channel to NaCl process");
Mark Seaborn 2013/07/17 18:21:49 Also misleading since it does not connect the IPC
halyavin 2013/07/18 09:32:22 Done.
397 return false; 398 return false;
398 } 399 }
399 400
400 CommandLine::StringType nacl_loader_prefix; 401 CommandLine::StringType nacl_loader_prefix;
401 #if defined(OS_POSIX) 402 #if defined(OS_POSIX)
402 nacl_loader_prefix = CommandLine::ForCurrentProcess()->GetSwitchValueNative( 403 nacl_loader_prefix = CommandLine::ForCurrentProcess()->GetSwitchValueNative(
403 switches::kNaClLoaderCmdPrefix); 404 switches::kNaClLoaderCmdPrefix);
404 #endif // defined(OS_POSIX) 405 #endif // defined(OS_POSIX)
405 406
406 // Build command line for nacl. 407 // Build command line for nacl.
(...skipping 14 matching lines...) Expand all
421 #endif 422 #endif
422 423
423 base::FilePath exe_path = ChildProcessHost::GetChildPath(flags); 424 base::FilePath exe_path = ChildProcessHost::GetChildPath(flags);
424 if (exe_path.empty()) 425 if (exe_path.empty())
425 return false; 426 return false;
426 427
427 #if defined(OS_WIN) 428 #if defined(OS_WIN)
428 // On Windows 64-bit NaCl loader is called nacl64.exe instead of chrome.exe 429 // On Windows 64-bit NaCl loader is called nacl64.exe instead of chrome.exe
429 if (RunningOnWOW64()) { 430 if (RunningOnWOW64()) {
430 if (!NaClBrowser::GetInstance()->GetNaCl64ExePath(&exe_path)) { 431 if (!NaClBrowser::GetInstance()->GetNaCl64ExePath(&exe_path)) {
432 SendErrorToRenderer("could not get path to nacl64.exe");
431 return false; 433 return false;
432 } 434 }
433 } 435 }
434 #endif 436 #endif
435 437
436 scoped_ptr<CommandLine> cmd_line(new CommandLine(exe_path)); 438 scoped_ptr<CommandLine> cmd_line(new CommandLine(exe_path));
437 nacl::CopyNaClCommandLineArguments(cmd_line.get()); 439 nacl::CopyNaClCommandLineArguments(cmd_line.get());
438 440
439 cmd_line->AppendSwitchASCII(switches::kProcessType, 441 cmd_line->AppendSwitchASCII(switches::kProcessType,
440 switches::kNaClLoaderProcess); 442 switches::kNaClLoaderProcess);
441 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); 443 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id);
442 if (NaClBrowser::GetDelegate()->DialogsAreSuppressed()) 444 if (NaClBrowser::GetDelegate()->DialogsAreSuppressed())
443 cmd_line->AppendSwitch(switches::kNoErrorDialogs); 445 cmd_line->AppendSwitch(switches::kNoErrorDialogs);
444 446
445 if (!nacl_loader_prefix.empty()) 447 if (!nacl_loader_prefix.empty())
446 cmd_line->PrependWrapper(nacl_loader_prefix); 448 cmd_line->PrependWrapper(nacl_loader_prefix);
447 449
448 // On Windows we might need to start the broker process to launch a new loader 450 // On Windows we might need to start the broker process to launch a new loader
449 #if defined(OS_WIN) 451 #if defined(OS_WIN)
450 if (RunningOnWOW64()) { 452 if (RunningOnWOW64()) {
451 if (!NaClBrokerService::GetInstance()->LaunchLoader( 453 if (!NaClBrokerService::GetInstance()->LaunchLoader(
452 weak_factory_.GetWeakPtr(), channel_id)) { 454 weak_factory_.GetWeakPtr(), channel_id)) {
453 LOG(ERROR) << "NaCl process launch failed: broker service did not launch " 455 SendErrorToRenderer("broker service did not launch process");
454 "process";
455 return false; 456 return false;
456 } 457 }
457 } else { 458 } else {
458 process_->Launch(new NaClSandboxedProcessLauncherDelegate, 459 process_->Launch(new NaClSandboxedProcessLauncherDelegate,
459 cmd_line.release()); 460 cmd_line.release());
460 } 461 }
461 #elif defined(OS_POSIX) 462 #elif defined(OS_POSIX)
462 process_->Launch(nacl_loader_prefix.empty(), // use_zygote 463 process_->Launch(nacl_loader_prefix.empty(), // use_zygote
463 base::EnvironmentVector(), 464 base::EnvironmentVector(),
464 cmd_line.release()); 465 cmd_line.release());
(...skipping 24 matching lines...) Expand all
489 490
490 void NaClProcessHost::OnProcessLaunched() { 491 void NaClProcessHost::OnProcessLaunched() {
491 if (!StartWithLaunchedProcess()) 492 if (!StartWithLaunchedProcess())
492 delete this; 493 delete this;
493 } 494 }
494 495
495 // Called when the NaClBrowser singleton has been fully initialized. 496 // Called when the NaClBrowser singleton has been fully initialized.
496 void NaClProcessHost::OnResourcesReady() { 497 void NaClProcessHost::OnResourcesReady() {
497 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 498 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
498 if (!nacl_browser->IsReady()) { 499 if (!nacl_browser->IsReady()) {
499 LOG(ERROR) << "NaCl process launch failed: could not acquire shared " 500 SendErrorToRenderer("could not acquire shared resources needed by NaCl");
500 "resources needed by NaCl";
501 delete this; 501 delete this;
502 } else if (!SendStart()) { 502 } else if (!SendStart()) {
503 delete this; 503 delete this;
504 } 504 }
505 } 505 }
506 506
507 bool NaClProcessHost::ReplyToRenderer( 507 bool NaClProcessHost::ReplyToRenderer(
508 const IPC::ChannelHandle& channel_handle) { 508 const IPC::ChannelHandle& channel_handle) {
509 #if defined(OS_WIN) 509 #if defined(OS_WIN)
510 // If we are on 64-bit Windows, the NaCl process's sandbox is 510 // 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 511 // managed by a different process from the renderer's sandbox. We
512 // need to inform the renderer's sandbox about the NaCl process so 512 // need to inform the renderer's sandbox about the NaCl process so
513 // that the renderer can send handles to the NaCl process using 513 // that the renderer can send handles to the NaCl process using
514 // BrokerDuplicateHandle(). 514 // BrokerDuplicateHandle().
515 if (RunningOnWOW64()) { 515 if (RunningOnWOW64()) {
516 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) { 516 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) {
517 LOG(ERROR) << "Failed to add NaCl process PID"; 517 SendErrorToRenderer("failed to register NaCl process in sandbox system");
Mark Seaborn 2013/07/17 18:21:49 How about "BrokerAddTargetPeer() failed"?
halyavin 2013/07/18 09:32:22 Done.
518 return false; 518 return false;
519 } 519 }
520 } 520 }
521 #endif 521 #endif
522 522
523 nacl::FileDescriptor handle_for_renderer; 523 nacl::FileDescriptor handle_for_renderer;
524 #if defined(OS_WIN) 524 #if defined(OS_WIN)
525 // Copy the handle into the renderer process. 525 // Copy the handle into the renderer process.
526 HANDLE handle_in_renderer; 526 HANDLE handle_in_renderer;
527 if (!DuplicateHandle(base::GetCurrentProcessHandle(), 527 if (!DuplicateHandle(base::GetCurrentProcessHandle(),
528 reinterpret_cast<HANDLE>( 528 reinterpret_cast<HANDLE>(
529 internal_->socket_for_renderer), 529 internal_->socket_for_renderer),
530 nacl_host_message_filter_->PeerHandle(), 530 nacl_host_message_filter_->PeerHandle(),
531 &handle_in_renderer, 531 &handle_in_renderer,
532 0, // Unused given DUPLICATE_SAME_ACCESS. 532 0, // Unused given DUPLICATE_SAME_ACCESS.
533 FALSE, 533 FALSE,
534 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { 534 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
535 LOG(ERROR) << "DuplicateHandle() failed"; 535 SendErrorToRenderer("DuplicateHandle() failed");
536 return false; 536 return false;
537 } 537 }
538 handle_for_renderer = reinterpret_cast<nacl::FileDescriptor>( 538 handle_for_renderer = reinterpret_cast<nacl::FileDescriptor>(
539 handle_in_renderer); 539 handle_in_renderer);
540 #else 540 #else
541 // No need to dup the imc_handle - we don't pass it anywhere else so 541 // No need to dup the imc_handle - we don't pass it anywhere else so
542 // it cannot be closed. 542 // it cannot be closed.
543 nacl::FileDescriptor imc_handle; 543 nacl::FileDescriptor imc_handle;
544 imc_handle.fd = internal_->socket_for_renderer; 544 imc_handle.fd = internal_->socket_for_renderer;
545 imc_handle.auto_close = true; 545 imc_handle.auto_close = true;
546 handle_for_renderer = imc_handle; 546 handle_for_renderer = imc_handle;
547 #endif 547 #endif
548 548
549 const ChildProcessData& data = process_->GetData(); 549 const ChildProcessData& data = process_->GetData();
550 NaClHostMsg_LaunchNaCl::WriteReplyParams( 550 SendMessageToRenderer(
551 reply_msg_, handle_for_renderer, 551 nacl::NaClLaunchResult(handle_for_renderer,
552 channel_handle, base::GetProcId(data.handle), data.id); 552 channel_handle,
553 nacl_host_message_filter_->Send(reply_msg_); 553 base::GetProcId(data.handle),
554 nacl_host_message_filter_ = NULL; 554 data.id),
555 reply_msg_ = NULL; 555 std::string() /* error_message */);
556 internal_->socket_for_renderer = NACL_INVALID_HANDLE; 556 internal_->socket_for_renderer = NACL_INVALID_HANDLE;
557 return true; 557 return true;
558 } 558 }
559 559
560 void NaClProcessHost::SendErrorToRenderer(const std::string& error_message) {
561 LOG(ERROR) << "NaCl process launch failed: " << error_message;
562 SendMessageToRenderer(nacl::NaClLaunchResult(), error_message);
563 }
564
565 void NaClProcessHost::SendMessageToRenderer(
566 const nacl::NaClLaunchResult& result,
567 const std::string& error_message) {
568 DCHECK(nacl_host_message_filter_);
569 DCHECK(reply_msg_);
570 if (nacl_host_message_filter_ != NULL && reply_msg_ != NULL) {
571 NaClHostMsg_LaunchNaCl::WriteReplyParams(
572 reply_msg_, result, error_message);
573 nacl_host_message_filter_->Send(reply_msg_);
574 nacl_host_message_filter_ = NULL;
575 reply_msg_ = NULL;
576 }
577 }
578
560 // TCP port we chose for NaCl debug stub. It can be any other number. 579 // TCP port we chose for NaCl debug stub. It can be any other number.
561 static const int kDebugStubPort = 4014; 580 static const int kDebugStubPort = 4014;
562 581
563 #if defined(OS_POSIX) 582 #if defined(OS_POSIX)
564 SocketDescriptor NaClProcessHost::GetDebugStubSocketHandle() { 583 SocketDescriptor NaClProcessHost::GetDebugStubSocketHandle() {
565 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 584 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
566 SocketDescriptor s; 585 SocketDescriptor s;
567 // We allocate currently unused TCP port for debug stub tests. The port 586 // We allocate currently unused TCP port for debug stub tests. The port
568 // number is passed to the test via debug stub port listener. 587 // number is passed to the test via debug stub port listener.
569 if (nacl_browser->HasGdbDebugStubPortListener()) { 588 if (nacl_browser->HasGdbDebugStubPortListener()) {
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 767 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
749 768
750 if (nacl_browser->IsReady()) { 769 if (nacl_browser->IsReady()) {
751 return SendStart(); 770 return SendStart();
752 } else if (nacl_browser->IsOk()) { 771 } else if (nacl_browser->IsOk()) {
753 nacl_browser->WaitForResources( 772 nacl_browser->WaitForResources(
754 base::Bind(&NaClProcessHost::OnResourcesReady, 773 base::Bind(&NaClProcessHost::OnResourcesReady,
755 weak_factory_.GetWeakPtr())); 774 weak_factory_.GetWeakPtr()));
756 return true; 775 return true;
757 } else { 776 } else {
758 LOG(ERROR) << "NaCl process failed to launch: previously failed to acquire " 777 SendErrorToRenderer("previously failed to acquire shared resources");
759 "shared resources";
760 return false; 778 return false;
761 } 779 }
762 } 780 }
763 781
764 void NaClProcessHost::OnQueryKnownToValidate(const std::string& signature, 782 void NaClProcessHost::OnQueryKnownToValidate(const std::string& signature,
765 bool* result) { 783 bool* result) {
766 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 784 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
767 *result = nacl_browser->QueryKnownToValidate(signature, off_the_record_); 785 *result = nacl_browser->QueryKnownToValidate(signature, off_the_record_);
768 } 786 }
769 787
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 } else { 930 } else {
913 NaClStartDebugExceptionHandlerThread( 931 NaClStartDebugExceptionHandlerThread(
914 process_handle.Take(), info, 932 process_handle.Take(), info,
915 base::MessageLoopProxy::current(), 933 base::MessageLoopProxy::current(),
916 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, 934 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker,
917 weak_factory_.GetWeakPtr())); 935 weak_factory_.GetWeakPtr()));
918 return true; 936 return true;
919 } 937 }
920 } 938 }
921 #endif 939 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698