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 |