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

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("could not create a socket pair");
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("could not create channel");
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 resolve module");
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 nacl::FileDescriptor handle_for_renderer; 508 nacl::FileDescriptor handle_for_renderer;
510 #if defined(OS_WIN) 509 #if defined(OS_WIN)
511 // Copy the handle into the renderer process. 510 // Copy the handle into the renderer process.
512 HANDLE handle_in_renderer; 511 HANDLE handle_in_renderer;
513 if (!DuplicateHandle(base::GetCurrentProcessHandle(), 512 if (!DuplicateHandle(base::GetCurrentProcessHandle(),
514 reinterpret_cast<HANDLE>( 513 reinterpret_cast<HANDLE>(
515 internal_->socket_for_renderer), 514 internal_->socket_for_renderer),
516 nacl_host_message_filter_->peer_handle(), 515 nacl_host_message_filter_->peer_handle(),
517 &handle_in_renderer, 516 &handle_in_renderer,
518 0, // Unused given DUPLICATE_SAME_ACCESS. 517 0, // Unused given DUPLICATE_SAME_ACCESS.
519 FALSE, 518 FALSE,
520 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { 519 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
521 LOG(ERROR) << "DuplicateHandle() failed"; 520 SendErrorToRenderer("DuplicateHandle() failed");
522 return false; 521 return false;
523 } 522 }
524 handle_for_renderer = reinterpret_cast<nacl::FileDescriptor>( 523 handle_for_renderer = reinterpret_cast<nacl::FileDescriptor>(
525 handle_in_renderer); 524 handle_in_renderer);
526 #else 525 #else
527 // No need to dup the imc_handle - we don't pass it anywhere else so 526 // No need to dup the imc_handle - we don't pass it anywhere else so
528 // it cannot be closed. 527 // it cannot be closed.
529 nacl::FileDescriptor imc_handle; 528 nacl::FileDescriptor imc_handle;
530 imc_handle.fd = internal_->socket_for_renderer; 529 imc_handle.fd = internal_->socket_for_renderer;
531 imc_handle.auto_close = true; 530 imc_handle.auto_close = true;
532 handle_for_renderer = imc_handle; 531 handle_for_renderer = imc_handle;
533 #endif 532 #endif
534 533
535 #if defined(OS_WIN) 534 #if defined(OS_WIN)
536 // If we are on 64-bit Windows, the NaCl process's sandbox is 535 // If we are on 64-bit Windows, the NaCl process's sandbox is
537 // managed by a different process from the renderer's sandbox. We 536 // managed by a different process from the renderer's sandbox. We
538 // need to inform the renderer's sandbox about the NaCl process so 537 // need to inform the renderer's sandbox about the NaCl process so
539 // that the renderer can send handles to the NaCl process using 538 // that the renderer can send handles to the NaCl process using
540 // BrokerDuplicateHandle(). 539 // BrokerDuplicateHandle().
541 if (RunningOnWOW64()) { 540 if (RunningOnWOW64()) {
542 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) { 541 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) {
543 LOG(ERROR) << "Failed to add NaCl process PID"; 542 SendErrorToRenderer("Failed to add NaCl process PID");
dmichael (off chromium) 2013/07/10 17:07:20 nit: let's make the capitalization consistent. Her
halyavin 2013/07/11 09:03:36 Done.
544 return false; 543 return false;
545 } 544 }
546 } 545 }
547 #endif 546 #endif
548 547
549 const ChildProcessData& data = process_->GetData(); 548 const ChildProcessData& data = process_->GetData();
550 NaClHostMsg_LaunchNaCl::WriteReplyParams( 549 NaClHostMsg_LaunchNaCl::WriteReplyParams(
dmichael (off chromium) 2013/07/10 17:07:20 For the sake of making the code more self-document
halyavin 2013/07/11 09:03:36 We are passing actual data here instead of empty n
dmichael (off chromium) 2013/07/11 16:12:59 I know, I'm suggesting you add an argument to Send
551 reply_msg_, handle_for_renderer, 550 reply_msg_,
552 channel_handle, base::GetProcId(data.handle), data.id); 551 nacl::NaClLaunchResult(handle_for_renderer,
552 channel_handle,
553 base::GetProcId(data.handle),
554 data.id),
555 std::string());
dmichael (off chromium) 2013/07/10 17:07:20 an inline comment might be nice "std::string() /*
halyavin 2013/07/11 09:03:36 Done.
553 nacl_host_message_filter_->Send(reply_msg_); 556 nacl_host_message_filter_->Send(reply_msg_);
554 nacl_host_message_filter_ = NULL; 557 nacl_host_message_filter_ = NULL;
555 reply_msg_ = NULL; 558 reply_msg_ = NULL;
556 internal_->socket_for_renderer = NACL_INVALID_HANDLE; 559 internal_->socket_for_renderer = NACL_INVALID_HANDLE;
dmichael (off chromium) 2013/07/10 17:07:20 ^^^ You're currently not doing this for the error
halyavin 2013/07/11 09:03:36 Yes, this is done on purpose. The handle is set to
halyavin 2013/07/11 12:49:44 The handle leak fix is here: https://codereview.ch
dmichael (off chromium) 2013/07/11 16:12:59 If we're sending a message to the other process on
557 return true; 560 return true;
558 } 561 }
559 562
563 void NaClProcessHost::SendErrorToRenderer(const std::string& error_message) {
564 LOG(ERROR) << "NaCl process launch failed: " << error_message;
565 if (nacl_host_message_filter_ != NULL && reply_msg_ != NULL) {
566 NaClHostMsg_LaunchNaCl::WriteReplyParams(
567 reply_msg_, nacl::NaClLaunchResult(), error_message);
568 nacl_host_message_filter_->Send(reply_msg_);
569 nacl_host_message_filter_ = NULL;
570 reply_msg_ = NULL;
571 }
572 }
573
560 // TCP port we chose for NaCl debug stub. It can be any other number. 574 // TCP port we chose for NaCl debug stub. It can be any other number.
561 static const int kDebugStubPort = 4014; 575 static const int kDebugStubPort = 4014;
562 576
563 #if defined(OS_POSIX) 577 #if defined(OS_POSIX)
564 SocketDescriptor NaClProcessHost::GetDebugStubSocketHandle() { 578 SocketDescriptor NaClProcessHost::GetDebugStubSocketHandle() {
565 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 579 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
566 SocketDescriptor s; 580 SocketDescriptor s;
567 // We allocate currently unused TCP port for debug stub tests. The port 581 // We allocate currently unused TCP port for debug stub tests. The port
568 // number is passed to the test via debug stub port listener. 582 // number is passed to the test via debug stub port listener.
569 if (nacl_browser->HasGdbDebugStubPortListener()) { 583 if (nacl_browser->HasGdbDebugStubPortListener()) {
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 762 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
749 763
750 if (nacl_browser->IsReady()) { 764 if (nacl_browser->IsReady()) {
751 return SendStart(); 765 return SendStart();
752 } else if (nacl_browser->IsOk()) { 766 } else if (nacl_browser->IsOk()) {
753 nacl_browser->WaitForResources( 767 nacl_browser->WaitForResources(
754 base::Bind(&NaClProcessHost::OnResourcesReady, 768 base::Bind(&NaClProcessHost::OnResourcesReady,
755 weak_factory_.GetWeakPtr())); 769 weak_factory_.GetWeakPtr()));
756 return true; 770 return true;
757 } else { 771 } else {
758 LOG(ERROR) << "NaCl process failed to launch: previously failed to acquire " 772 SendErrorToRenderer("previously failed to acquire shared resources");
759 "shared resources";
760 return false; 773 return false;
761 } 774 }
762 } 775 }
763 776
764 void NaClProcessHost::OnQueryKnownToValidate(const std::string& signature, 777 void NaClProcessHost::OnQueryKnownToValidate(const std::string& signature,
765 bool* result) { 778 bool* result) {
766 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 779 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
767 *result = nacl_browser->QueryKnownToValidate(signature, off_the_record_); 780 *result = nacl_browser->QueryKnownToValidate(signature, off_the_record_);
768 } 781 }
769 782
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 } else { 925 } else {
913 NaClStartDebugExceptionHandlerThread( 926 NaClStartDebugExceptionHandlerThread(
914 process_handle.Take(), info, 927 process_handle.Take(), info,
915 base::MessageLoopProxy::current(), 928 base::MessageLoopProxy::current(),
916 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, 929 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker,
917 weak_factory_.GetWeakPtr())); 930 weak_factory_.GetWeakPtr()));
918 return true; 931 return true;
919 } 932 }
920 } 933 }
921 #endif 934 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698