| 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 "components/nacl/browser/nacl_process_host.h" | 5 #include "components/nacl/browser/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 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 weak_factory_(this) { | 266 weak_factory_(this) { |
| 267 process_.reset(content::BrowserChildProcessHost::Create( | 267 process_.reset(content::BrowserChildProcessHost::Create( |
| 268 PROCESS_TYPE_NACL_LOADER, this)); | 268 PROCESS_TYPE_NACL_LOADER, this)); |
| 269 | 269 |
| 270 // Set the display name so the user knows what plugin the process is running. | 270 // Set the display name so the user knows what plugin the process is running. |
| 271 // We aren't on the UI thread so getting the pref locale for language | 271 // We aren't on the UI thread so getting the pref locale for language |
| 272 // formatting isn't possible, so IDN will be lost, but this is probably OK | 272 // formatting isn't possible, so IDN will be lost, but this is probably OK |
| 273 // for this use case. | 273 // for this use case. |
| 274 process_->SetName(net::FormatUrl(manifest_url_, std::string())); | 274 process_->SetName(net::FormatUrl(manifest_url_, std::string())); |
| 275 | 275 |
| 276 enable_debug_stub_ = CommandLine::ForCurrentProcess()->HasSwitch( | 276 enable_debug_stub_ = base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 277 switches::kEnableNaClDebug); | 277 switches::kEnableNaClDebug); |
| 278 DCHECK(process_type_ != kUnknownNaClProcessType); | 278 DCHECK(process_type_ != kUnknownNaClProcessType); |
| 279 enable_crash_throttling_ = process_type_ != kNativeNaClProcessType; | 279 enable_crash_throttling_ = process_type_ != kNativeNaClProcessType; |
| 280 } | 280 } |
| 281 | 281 |
| 282 NaClProcessHost::~NaClProcessHost() { | 282 NaClProcessHost::~NaClProcessHost() { |
| 283 // Report exit status only if the process was successfully started. | 283 // Report exit status only if the process was successfully started. |
| 284 if (process_->GetData().handle != base::kNullProcessHandle) { | 284 if (process_->GetData().handle != base::kNullProcessHandle) { |
| 285 int exit_code = 0; | 285 int exit_code = 0; |
| 286 process_->GetTerminationStatus(false /* known_dead */, &exit_code); | 286 process_->GetTerminationStatus(false /* known_dead */, &exit_code); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 303 } | 303 } |
| 304 #if defined(OS_WIN) | 304 #if defined(OS_WIN) |
| 305 if (process_launched_by_broker_) { | 305 if (process_launched_by_broker_) { |
| 306 NaClBrokerService::GetInstance()->OnLoaderDied(); | 306 NaClBrokerService::GetInstance()->OnLoaderDied(); |
| 307 } | 307 } |
| 308 #endif | 308 #endif |
| 309 } | 309 } |
| 310 | 310 |
| 311 void NaClProcessHost::OnProcessCrashed(int exit_status) { | 311 void NaClProcessHost::OnProcessCrashed(int exit_status) { |
| 312 if (enable_crash_throttling_ && | 312 if (enable_crash_throttling_ && |
| 313 !CommandLine::ForCurrentProcess()->HasSwitch( | 313 !base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 314 switches::kDisablePnaclCrashThrottling)) { | 314 switches::kDisablePnaclCrashThrottling)) { |
| 315 NaClBrowser::GetInstance()->OnProcessCrashed(); | 315 NaClBrowser::GetInstance()->OnProcessCrashed(); |
| 316 } | 316 } |
| 317 } | 317 } |
| 318 | 318 |
| 319 // This is called at browser startup. | 319 // This is called at browser startup. |
| 320 // static | 320 // static |
| 321 void NaClProcessHost::EarlyStartup() { | 321 void NaClProcessHost::EarlyStartup() { |
| 322 NaClBrowser::GetInstance()->EarlyStartup(); | 322 NaClBrowser::GetInstance()->EarlyStartup(); |
| 323 // Inform NaClBrowser that we exist and will have a debug port at some point. | 323 // Inform NaClBrowser that we exist and will have a debug port at some point. |
| 324 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) | 324 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| 325 // Open the IRT file early to make sure that it isn't replaced out from | 325 // Open the IRT file early to make sure that it isn't replaced out from |
| 326 // under us by autoupdate. | 326 // under us by autoupdate. |
| 327 NaClBrowser::GetInstance()->EnsureIrtAvailable(); | 327 NaClBrowser::GetInstance()->EnsureIrtAvailable(); |
| 328 #endif | 328 #endif |
| 329 CommandLine* cmd = CommandLine::ForCurrentProcess(); | 329 base::CommandLine* cmd = base::CommandLine::ForCurrentProcess(); |
| 330 UMA_HISTOGRAM_BOOLEAN( | 330 UMA_HISTOGRAM_BOOLEAN( |
| 331 "NaCl.nacl-gdb", | 331 "NaCl.nacl-gdb", |
| 332 !cmd->GetSwitchValuePath(switches::kNaClGdb).empty()); | 332 !cmd->GetSwitchValuePath(switches::kNaClGdb).empty()); |
| 333 UMA_HISTOGRAM_BOOLEAN( | 333 UMA_HISTOGRAM_BOOLEAN( |
| 334 "NaCl.nacl-gdb-script", | 334 "NaCl.nacl-gdb-script", |
| 335 !cmd->GetSwitchValuePath(switches::kNaClGdbScript).empty()); | 335 !cmd->GetSwitchValuePath(switches::kNaClGdbScript).empty()); |
| 336 UMA_HISTOGRAM_BOOLEAN( | 336 UMA_HISTOGRAM_BOOLEAN( |
| 337 "NaCl.enable-nacl-debug", | 337 "NaCl.enable-nacl-debug", |
| 338 cmd->HasSwitch(switches::kEnableNaClDebug)); | 338 cmd->HasSwitch(switches::kEnableNaClDebug)); |
| 339 std::string nacl_debug_mask = | 339 std::string nacl_debug_mask = |
| (...skipping 17 matching lines...) Expand all Loading... |
| 357 NaClHostMessageFilter* nacl_host_message_filter, | 357 NaClHostMessageFilter* nacl_host_message_filter, |
| 358 IPC::Message* reply_msg, | 358 IPC::Message* reply_msg, |
| 359 const base::FilePath& manifest_path) { | 359 const base::FilePath& manifest_path) { |
| 360 nacl_host_message_filter_ = nacl_host_message_filter; | 360 nacl_host_message_filter_ = nacl_host_message_filter; |
| 361 reply_msg_ = reply_msg; | 361 reply_msg_ = reply_msg; |
| 362 manifest_path_ = manifest_path; | 362 manifest_path_ = manifest_path; |
| 363 | 363 |
| 364 // Do not launch the requested NaCl module if NaCl is marked "unstable" due | 364 // Do not launch the requested NaCl module if NaCl is marked "unstable" due |
| 365 // to too many crashes within a given time period. | 365 // to too many crashes within a given time period. |
| 366 if (enable_crash_throttling_ && | 366 if (enable_crash_throttling_ && |
| 367 !CommandLine::ForCurrentProcess()->HasSwitch( | 367 !base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 368 switches::kDisablePnaclCrashThrottling) && | 368 switches::kDisablePnaclCrashThrottling) && |
| 369 NaClBrowser::GetInstance()->IsThrottled()) { | 369 NaClBrowser::GetInstance()->IsThrottled()) { |
| 370 SendErrorToRenderer("Process creation was throttled due to excessive" | 370 SendErrorToRenderer("Process creation was throttled due to excessive" |
| 371 " crashes"); | 371 " crashes"); |
| 372 delete this; | 372 delete this; |
| 373 return; | 373 return; |
| 374 } | 374 } |
| 375 | 375 |
| 376 const CommandLine* cmd = CommandLine::ForCurrentProcess(); | 376 const base::CommandLine* cmd = base::CommandLine::ForCurrentProcess(); |
| 377 #if defined(OS_WIN) | 377 #if defined(OS_WIN) |
| 378 if (cmd->HasSwitch(switches::kEnableNaClDebug) && | 378 if (cmd->HasSwitch(switches::kEnableNaClDebug) && |
| 379 !cmd->HasSwitch(switches::kNoSandbox)) { | 379 !cmd->HasSwitch(switches::kNoSandbox)) { |
| 380 // We don't switch off sandbox automatically for security reasons. | 380 // We don't switch off sandbox automatically for security reasons. |
| 381 SendErrorToRenderer("NaCl's GDB debug stub requires --no-sandbox flag" | 381 SendErrorToRenderer("NaCl's GDB debug stub requires --no-sandbox flag" |
| 382 " on Windows. See crbug.com/265624."); | 382 " on Windows. See crbug.com/265624."); |
| 383 delete this; | 383 delete this; |
| 384 return; | 384 return; |
| 385 } | 385 } |
| 386 #endif | 386 #endif |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 // reporting crash information. | 448 // reporting crash information. |
| 449 crash_info_shmem_.CreateAnonymous(kNaClCrashInfoShmemSize); | 449 crash_info_shmem_.CreateAnonymous(kNaClCrashInfoShmemSize); |
| 450 | 450 |
| 451 // Launch the process | 451 // Launch the process |
| 452 if (!LaunchSelLdr()) { | 452 if (!LaunchSelLdr()) { |
| 453 delete this; | 453 delete this; |
| 454 } | 454 } |
| 455 } | 455 } |
| 456 | 456 |
| 457 void NaClProcessHost::OnChannelConnected(int32 peer_pid) { | 457 void NaClProcessHost::OnChannelConnected(int32 peer_pid) { |
| 458 if (!CommandLine::ForCurrentProcess()->GetSwitchValuePath( | 458 if (!base::CommandLine::ForCurrentProcess()->GetSwitchValuePath( |
| 459 switches::kNaClGdb).empty()) { | 459 switches::kNaClGdb).empty()) { |
| 460 LaunchNaClGdb(); | 460 LaunchNaClGdb(); |
| 461 } | 461 } |
| 462 } | 462 } |
| 463 | 463 |
| 464 #if defined(OS_WIN) | 464 #if defined(OS_WIN) |
| 465 void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) { | 465 void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) { |
| 466 process_launched_by_broker_ = true; | 466 process_launched_by_broker_ = true; |
| 467 process_->SetHandle(handle); | 467 process_->SetHandle(handle); |
| 468 SetDebugStubPort(nacl::kGdbDebugStubPortUnknown); | 468 SetDebugStubPort(nacl::kGdbDebugStubPortUnknown); |
| 469 if (!StartWithLaunchedProcess()) | 469 if (!StartWithLaunchedProcess()) |
| 470 delete this; | 470 delete this; |
| 471 } | 471 } |
| 472 | 472 |
| 473 void NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker(bool success) { | 473 void NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker(bool success) { |
| 474 IPC::Message* reply = attach_debug_exception_handler_reply_msg_.release(); | 474 IPC::Message* reply = attach_debug_exception_handler_reply_msg_.release(); |
| 475 NaClProcessMsg_AttachDebugExceptionHandler::WriteReplyParams(reply, success); | 475 NaClProcessMsg_AttachDebugExceptionHandler::WriteReplyParams(reply, success); |
| 476 Send(reply); | 476 Send(reply); |
| 477 } | 477 } |
| 478 #endif | 478 #endif |
| 479 | 479 |
| 480 // Needed to handle sync messages in OnMessageReceived. | 480 // Needed to handle sync messages in OnMessageReceived. |
| 481 bool NaClProcessHost::Send(IPC::Message* msg) { | 481 bool NaClProcessHost::Send(IPC::Message* msg) { |
| 482 return process_->Send(msg); | 482 return process_->Send(msg); |
| 483 } | 483 } |
| 484 | 484 |
| 485 bool NaClProcessHost::LaunchNaClGdb() { | 485 bool NaClProcessHost::LaunchNaClGdb() { |
| 486 const base::CommandLine& command_line = |
| 487 *base::CommandLine::ForCurrentProcess(); |
| 486 #if defined(OS_WIN) | 488 #if defined(OS_WIN) |
| 487 base::FilePath nacl_gdb = | 489 base::FilePath nacl_gdb = |
| 488 CommandLine::ForCurrentProcess()->GetSwitchValuePath(switches::kNaClGdb); | 490 command_line.GetSwitchValuePath(switches::kNaClGdb); |
| 489 CommandLine cmd_line(nacl_gdb); | 491 base::CommandLine cmd_line(nacl_gdb); |
| 490 #else | 492 #else |
| 491 CommandLine::StringType nacl_gdb = | 493 base::CommandLine::StringType nacl_gdb = |
| 492 CommandLine::ForCurrentProcess()->GetSwitchValueNative( | 494 command_line.GetSwitchValueNative(switches::kNaClGdb); |
| 493 switches::kNaClGdb); | 495 base::CommandLine::StringVector argv; |
| 494 CommandLine::StringVector argv; | |
| 495 // We don't support spaces inside arguments in --nacl-gdb switch. | 496 // We don't support spaces inside arguments in --nacl-gdb switch. |
| 496 base::SplitString(nacl_gdb, static_cast<CommandLine::CharType>(' '), &argv); | 497 base::SplitString(nacl_gdb, static_cast<base::CommandLine::CharType>(' '), |
| 497 CommandLine cmd_line(argv); | 498 &argv); |
| 499 base::CommandLine cmd_line(argv); |
| 498 #endif | 500 #endif |
| 499 cmd_line.AppendArg("--eval-command"); | 501 cmd_line.AppendArg("--eval-command"); |
| 500 base::FilePath::StringType irt_path( | 502 base::FilePath::StringType irt_path( |
| 501 NaClBrowser::GetInstance()->GetIrtFilePath().value()); | 503 NaClBrowser::GetInstance()->GetIrtFilePath().value()); |
| 502 // Avoid back slashes because nacl-gdb uses posix escaping rules on Windows. | 504 // Avoid back slashes because nacl-gdb uses posix escaping rules on Windows. |
| 503 // See issue https://code.google.com/p/nativeclient/issues/detail?id=3482. | 505 // See issue https://code.google.com/p/nativeclient/issues/detail?id=3482. |
| 504 std::replace(irt_path.begin(), irt_path.end(), '\\', '/'); | 506 std::replace(irt_path.begin(), irt_path.end(), '\\', '/'); |
| 505 cmd_line.AppendArgNative(FILE_PATH_LITERAL("nacl-irt \"") + irt_path + | 507 cmd_line.AppendArgNative(FILE_PATH_LITERAL("nacl-irt \"") + irt_path + |
| 506 FILE_PATH_LITERAL("\"")); | 508 FILE_PATH_LITERAL("\"")); |
| 507 if (!manifest_path_.empty()) { | 509 if (!manifest_path_.empty()) { |
| 508 cmd_line.AppendArg("--eval-command"); | 510 cmd_line.AppendArg("--eval-command"); |
| 509 base::FilePath::StringType manifest_path_value(manifest_path_.value()); | 511 base::FilePath::StringType manifest_path_value(manifest_path_.value()); |
| 510 std::replace(manifest_path_value.begin(), manifest_path_value.end(), | 512 std::replace(manifest_path_value.begin(), manifest_path_value.end(), |
| 511 '\\', '/'); | 513 '\\', '/'); |
| 512 cmd_line.AppendArgNative(FILE_PATH_LITERAL("nacl-manifest \"") + | 514 cmd_line.AppendArgNative(FILE_PATH_LITERAL("nacl-manifest \"") + |
| 513 manifest_path_value + FILE_PATH_LITERAL("\"")); | 515 manifest_path_value + FILE_PATH_LITERAL("\"")); |
| 514 } | 516 } |
| 515 cmd_line.AppendArg("--eval-command"); | 517 cmd_line.AppendArg("--eval-command"); |
| 516 cmd_line.AppendArg("target remote :4014"); | 518 cmd_line.AppendArg("target remote :4014"); |
| 517 base::FilePath script = CommandLine::ForCurrentProcess()->GetSwitchValuePath( | 519 base::FilePath script = |
| 518 switches::kNaClGdbScript); | 520 command_line.GetSwitchValuePath(switches::kNaClGdbScript); |
| 519 if (!script.empty()) { | 521 if (!script.empty()) { |
| 520 cmd_line.AppendArg("--command"); | 522 cmd_line.AppendArg("--command"); |
| 521 cmd_line.AppendArgNative(script.value()); | 523 cmd_line.AppendArgNative(script.value()); |
| 522 } | 524 } |
| 523 return base::LaunchProcess(cmd_line, base::LaunchOptions(), NULL); | 525 return base::LaunchProcess(cmd_line, base::LaunchOptions(), NULL); |
| 524 } | 526 } |
| 525 | 527 |
| 526 bool NaClProcessHost::LaunchSelLdr() { | 528 bool NaClProcessHost::LaunchSelLdr() { |
| 527 std::string channel_id = process_->GetHost()->CreateChannel(); | 529 std::string channel_id = process_->GetHost()->CreateChannel(); |
| 528 if (channel_id.empty()) { | 530 if (channel_id.empty()) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 } else if (!IsInPath(old_path, x64_crt_path)) { | 582 } else if (!IsInPath(old_path, x64_crt_path)) { |
| 581 std::string new_path(old_path); | 583 std::string new_path(old_path); |
| 582 new_path.append(";"); | 584 new_path.append(";"); |
| 583 new_path.append(x64_crt_path); | 585 new_path.append(x64_crt_path); |
| 584 env->SetVar(kPath, new_path); | 586 env->SetVar(kPath, new_path); |
| 585 } | 587 } |
| 586 #endif // _DLL | 588 #endif // _DLL |
| 587 } | 589 } |
| 588 #endif | 590 #endif |
| 589 | 591 |
| 590 scoped_ptr<CommandLine> cmd_line(new CommandLine(exe_path)); | 592 scoped_ptr<base::CommandLine> cmd_line(new base::CommandLine(exe_path)); |
| 591 CopyNaClCommandLineArguments(cmd_line.get()); | 593 CopyNaClCommandLineArguments(cmd_line.get()); |
| 592 | 594 |
| 593 cmd_line->AppendSwitchASCII(switches::kProcessType, | 595 cmd_line->AppendSwitchASCII(switches::kProcessType, |
| 594 (uses_nonsfi_mode_ ? | 596 (uses_nonsfi_mode_ ? |
| 595 switches::kNaClLoaderNonSfiProcess : | 597 switches::kNaClLoaderNonSfiProcess : |
| 596 switches::kNaClLoaderProcess)); | 598 switches::kNaClLoaderProcess)); |
| 597 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); | 599 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); |
| 598 if (NaClBrowser::GetDelegate()->DialogsAreSuppressed()) | 600 if (NaClBrowser::GetDelegate()->DialogsAreSuppressed()) |
| 599 cmd_line->AppendSwitch(switches::kNoErrorDialogs); | 601 cmd_line->AppendSwitch(switches::kNoErrorDialogs); |
| 600 | 602 |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 960 render_view_id_, | 962 render_view_id_, |
| 961 profile_directory_)); | 963 profile_directory_)); |
| 962 ppapi_host_->SetOnKeepaliveCallback( | 964 ppapi_host_->SetOnKeepaliveCallback( |
| 963 NaClBrowser::GetDelegate()->GetOnKeepaliveCallback()); | 965 NaClBrowser::GetDelegate()->GetOnKeepaliveCallback()); |
| 964 | 966 |
| 965 ppapi::PpapiNaClPluginArgs args; | 967 ppapi::PpapiNaClPluginArgs args; |
| 966 args.off_the_record = nacl_host_message_filter_->off_the_record(); | 968 args.off_the_record = nacl_host_message_filter_->off_the_record(); |
| 967 args.permissions = permissions_; | 969 args.permissions = permissions_; |
| 968 args.keepalive_throttle_interval_milliseconds = | 970 args.keepalive_throttle_interval_milliseconds = |
| 969 keepalive_throttle_interval_milliseconds_; | 971 keepalive_throttle_interval_milliseconds_; |
| 970 CommandLine* cmdline = CommandLine::ForCurrentProcess(); | 972 base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); |
| 971 DCHECK(cmdline); | 973 DCHECK(cmdline); |
| 972 std::string flag_whitelist[] = { | 974 std::string flag_whitelist[] = { |
| 973 switches::kV, | 975 switches::kV, |
| 974 switches::kVModule, | 976 switches::kVModule, |
| 975 }; | 977 }; |
| 976 for (size_t i = 0; i < arraysize(flag_whitelist); ++i) { | 978 for (size_t i = 0; i < arraysize(flag_whitelist); ++i) { |
| 977 std::string value = cmdline->GetSwitchValueASCII(flag_whitelist[i]); | 979 std::string value = cmdline->GetSwitchValueASCII(flag_whitelist[i]); |
| 978 if (!value.empty()) { | 980 if (!value.empty()) { |
| 979 args.switch_names.push_back(flag_whitelist[i]); | 981 args.switch_names.push_back(flag_whitelist[i]); |
| 980 args.switch_values.push_back(value); | 982 args.switch_values.push_back(value); |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1173 process_handle.Take(), info, | 1175 process_handle.Take(), info, |
| 1174 base::MessageLoopProxy::current(), | 1176 base::MessageLoopProxy::current(), |
| 1175 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, | 1177 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, |
| 1176 weak_factory_.GetWeakPtr())); | 1178 weak_factory_.GetWeakPtr())); |
| 1177 return true; | 1179 return true; |
| 1178 } | 1180 } |
| 1179 } | 1181 } |
| 1180 #endif | 1182 #endif |
| 1181 | 1183 |
| 1182 } // namespace nacl | 1184 } // namespace nacl |
| OLD | NEW |