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

Side by Side Diff: content/browser/child_process_launcher.cc

Issue 2585963002: Clarifying the parameters ownership of BrowserChildProcessHost::Launch() (Closed)
Patch Set: Fixed crasher on Windows. Created 3 years, 12 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
« no previous file with comments | « content/browser/child_process_launcher.h ('k') | content/browser/gpu/gpu_process_host.cc » ('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 2012 The Chromium Authors. All rights reserved. 1 // Copyright 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 "content/browser/child_process_launcher.h" 5 #include "content/browser/child_process_launcher.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 base::Passed(base::Process(handle)), launch_result)); 108 base::Passed(base::Process(handle)), launch_result));
109 if (BrowserThread::CurrentlyOn(client_thread_id)) { 109 if (BrowserThread::CurrentlyOn(client_thread_id)) {
110 callback_on_client_thread.Run(); 110 callback_on_client_thread.Run();
111 } else { 111 } else {
112 BrowserThread::PostTask( 112 BrowserThread::PostTask(
113 client_thread_id, FROM_HERE, callback_on_client_thread); 113 client_thread_id, FROM_HERE, callback_on_client_thread);
114 } 114 }
115 } 115 }
116 #endif 116 #endif
117 117
118 void LaunchOnLauncherThread(const NotifyCallback& callback, 118 void LaunchOnLauncherThread(
119 BrowserThread::ID client_thread_id, 119 const NotifyCallback& callback,
120 int child_process_id, 120 BrowserThread::ID client_thread_id,
121 SandboxedProcessLauncherDelegate* delegate, 121 int child_process_id,
122 mojo::edk::ScopedPlatformHandle client_handle, 122 std::unique_ptr<SandboxedProcessLauncherDelegate> delegate,
123 base::CommandLine* cmd_line) { 123 mojo::edk::ScopedPlatformHandle client_handle,
124 std::unique_ptr<base::CommandLine> cmd_line) {
124 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); 125 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
125 std::unique_ptr<SandboxedProcessLauncherDelegate> delegate_deleter(delegate);
126 #if !defined(OS_ANDROID) 126 #if !defined(OS_ANDROID)
127 ZygoteHandle zygote = nullptr; 127 ZygoteHandle zygote = nullptr;
128 int launch_result = LAUNCH_RESULT_FAILURE; 128 int launch_result = LAUNCH_RESULT_FAILURE;
129 #endif 129 #endif
130 #if defined(OS_WIN) 130 #if defined(OS_WIN)
131 bool launch_elevated = delegate->ShouldLaunchElevated(); 131 bool launch_elevated = delegate->ShouldLaunchElevated();
132 #elif defined(OS_MACOSX) 132 #elif defined(OS_MACOSX)
133 base::EnvironmentMap env = delegate->GetEnvironment(); 133 base::EnvironmentMap env = delegate->GetEnvironment();
134 #elif defined(OS_POSIX) && !defined(OS_ANDROID) 134 #elif defined(OS_POSIX) && !defined(OS_ANDROID)
135 base::EnvironmentMap env = delegate->GetEnvironment(); 135 base::EnvironmentMap env = delegate->GetEnvironment();
136 #endif 136 #endif
137 std::unique_ptr<base::CommandLine> cmd_line_deleter(cmd_line);
138 base::TimeTicks begin_launch_time = base::TimeTicks::Now(); 137 base::TimeTicks begin_launch_time = base::TimeTicks::Now();
139 138
140 base::Process process; 139 base::Process process;
141 #if defined(OS_WIN) 140 #if defined(OS_WIN)
142 if (launch_elevated) { 141 if (launch_elevated) {
143 // When establishing a Mojo connection, the pipe path has already been added 142 // When establishing a Mojo connection, the pipe path has already been added
144 // to the command line. 143 // to the command line.
145 base::LaunchOptions options; 144 base::LaunchOptions options;
146 options.start_hidden = true; 145 options.start_hidden = true;
147 process = base::LaunchElevatedProcess(*cmd_line, options); 146 process = base::LaunchElevatedProcess(*cmd_line, options);
148 } else { 147 } else {
149 base::HandlesToInheritVector handles; 148 base::HandlesToInheritVector handles;
150 handles.push_back(client_handle.get().handle); 149 handles.push_back(client_handle.get().handle);
151 base::FieldTrialList::AppendFieldTrialHandleIfNeeded(&handles); 150 base::FieldTrialList::AppendFieldTrialHandleIfNeeded(&handles);
152 cmd_line->AppendSwitchASCII( 151 cmd_line->AppendSwitchASCII(
153 mojo::edk::PlatformChannelPair::kMojoPlatformChannelHandleSwitch, 152 mojo::edk::PlatformChannelPair::kMojoPlatformChannelHandleSwitch,
154 base::UintToString(base::win::HandleToUint32(handles[0]))); 153 base::UintToString(base::win::HandleToUint32(handles[0])));
155 launch_result = 154 launch_result = StartSandboxedProcess(
156 StartSandboxedProcess(delegate, cmd_line, handles, &process); 155 delegate.get(), cmd_line.get(), handles, &process);
157 } 156 }
158 #elif defined(OS_POSIX) 157 #elif defined(OS_POSIX)
159 std::string process_type = 158 std::string process_type =
160 cmd_line->GetSwitchValueASCII(switches::kProcessType); 159 cmd_line->GetSwitchValueASCII(switches::kProcessType);
161 std::unique_ptr<FileDescriptorInfo> files_to_register( 160 std::unique_ptr<FileDescriptorInfo> files_to_register(
162 FileDescriptorInfoImpl::Create()); 161 FileDescriptorInfoImpl::Create());
163 162
164 base::ScopedFD mojo_fd(client_handle.release().handle); 163 base::ScopedFD mojo_fd(client_handle.release().handle);
165 DCHECK(mojo_fd.is_valid()); 164 DCHECK(mojo_fd.is_valid());
166 165
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 if (process.IsValid()) { 325 if (process.IsValid()) {
327 broker->AddPlaceholderForPid(process.Pid(), child_process_id); 326 broker->AddPlaceholderForPid(process.Pid(), child_process_id);
328 } else { 327 } else {
329 if (pre_exec_delegate) { 328 if (pre_exec_delegate) {
330 BootstrapSandboxManager::GetInstance()->sandbox()->RevokeToken( 329 BootstrapSandboxManager::GetInstance()->sandbox()->RevokeToken(
331 pre_exec_delegate->sandbox_token()); 330 pre_exec_delegate->sandbox_token());
332 } 331 }
333 } 332 }
334 333
335 // After updating the broker, release the lock and let the child's 334 // After updating the broker, release the lock and let the child's
336 // messasge be processed on the broker's thread. 335 // message be processed on the broker's thread.
337 broker->GetLock().Release(); 336 broker->GetLock().Release();
338 #endif // defined(OS_MACOSX) 337 #endif // defined(OS_MACOSX)
339 } 338 }
340 #endif // else defined(OS_POSIX) 339 #endif // else defined(OS_POSIX)
341 #if !defined(OS_ANDROID) 340 #if !defined(OS_ANDROID)
342 if (process.IsValid()) { 341 if (process.IsValid()) {
343 launch_result = LAUNCH_RESULT_SUCCESS; 342 launch_result = LAUNCH_RESULT_SUCCESS;
344 RecordHistogramsOnLauncherThread(base::TimeTicks::Now() - 343 RecordHistogramsOnLauncherThread(base::TimeTicks::Now() -
345 begin_launch_time); 344 begin_launch_time);
346 } 345 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 #endif // defined(OS_MACOSX) 384 #endif // defined(OS_MACOSX)
386 } 385 }
387 #if defined(OS_ANDROID) 386 #if defined(OS_ANDROID)
388 SetChildProcessInForeground(process.Handle(), !background); 387 SetChildProcessInForeground(process.Handle(), !background);
389 #endif 388 #endif
390 } 389 }
391 390
392 } // namespace 391 } // namespace
393 392
394 ChildProcessLauncher::ChildProcessLauncher( 393 ChildProcessLauncher::ChildProcessLauncher(
395 SandboxedProcessLauncherDelegate* delegate, 394 std::unique_ptr<SandboxedProcessLauncherDelegate> delegate,
396 base::CommandLine* cmd_line, 395 std::unique_ptr<base::CommandLine> cmd_line,
397 int child_process_id, 396 int child_process_id,
398 Client* client, 397 Client* client,
399 const std::string& mojo_child_token, 398 const std::string& mojo_child_token,
400 const mojo::edk::ProcessErrorCallback& process_error_callback, 399 const mojo::edk::ProcessErrorCallback& process_error_callback,
401 bool terminate_on_shutdown) 400 bool terminate_on_shutdown)
402 : client_(client), 401 : client_(client),
403 termination_status_(base::TERMINATION_STATUS_NORMAL_TERMINATION), 402 termination_status_(base::TERMINATION_STATUS_NORMAL_TERMINATION),
404 exit_code_(RESULT_CODE_NORMAL_EXIT), 403 exit_code_(RESULT_CODE_NORMAL_EXIT),
405 zygote_(nullptr), 404 zygote_(nullptr),
406 starting_(true), 405 starting_(true),
407 process_error_callback_(process_error_callback), 406 process_error_callback_(process_error_callback),
408 #if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \ 407 #if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \
409 defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \ 408 defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \
410 defined(UNDEFINED_SANITIZER) 409 defined(UNDEFINED_SANITIZER)
411 terminate_child_on_shutdown_(false), 410 terminate_child_on_shutdown_(false),
412 #else 411 #else
413 terminate_child_on_shutdown_(terminate_on_shutdown), 412 terminate_child_on_shutdown_(terminate_on_shutdown),
414 #endif 413 #endif
415 mojo_child_token_(mojo_child_token), 414 mojo_child_token_(mojo_child_token),
416 weak_factory_(this) { 415 weak_factory_(this) {
417 DCHECK(CalledOnValidThread()); 416 DCHECK(CalledOnValidThread());
418 CHECK(BrowserThread::GetCurrentThreadIdentifier(&client_thread_id_)); 417 CHECK(BrowserThread::GetCurrentThreadIdentifier(&client_thread_id_));
419 Launch(delegate, cmd_line, child_process_id); 418 Launch(std::move(delegate), std::move(cmd_line), child_process_id);
420 } 419 }
421 420
422 ChildProcessLauncher::~ChildProcessLauncher() { 421 ChildProcessLauncher::~ChildProcessLauncher() {
423 DCHECK(CalledOnValidThread()); 422 DCHECK(CalledOnValidThread());
424 if (process_.IsValid() && terminate_child_on_shutdown_) { 423 if (process_.IsValid() && terminate_child_on_shutdown_) {
425 // On Posix, EnsureProcessTerminated can lead to 2 seconds of sleep! So 424 // On Posix, EnsureProcessTerminated can lead to 2 seconds of sleep! So
426 // don't this on the UI/IO threads. 425 // don't this on the UI/IO threads.
427 BrowserThread::PostTask(BrowserThread::PROCESS_LAUNCHER, FROM_HERE, 426 BrowserThread::PostTask(BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
428 base::Bind(&TerminateOnLauncherThread, zygote_, 427 base::Bind(&TerminateOnLauncherThread, zygote_,
429 base::Passed(&process_))); 428 base::Passed(&process_)));
430 } 429 }
431 } 430 }
432 431
433 void ChildProcessLauncher::Launch(SandboxedProcessLauncherDelegate* delegate, 432 void ChildProcessLauncher::Launch(
434 base::CommandLine* cmd_line, 433 std::unique_ptr<SandboxedProcessLauncherDelegate> delegate,
435 int child_process_id) { 434 std::unique_ptr<base::CommandLine> cmd_line,
435 int child_process_id) {
436 DCHECK(CalledOnValidThread()); 436 DCHECK(CalledOnValidThread());
437 437
438 #if defined(OS_ANDROID) 438 #if defined(OS_ANDROID)
439 // Android only supports renderer, sandboxed utility and gpu. 439 // Android only supports renderer, sandboxed utility and gpu.
440 std::string process_type = 440 std::string process_type =
441 cmd_line->GetSwitchValueASCII(switches::kProcessType); 441 cmd_line->GetSwitchValueASCII(switches::kProcessType);
442 CHECK(process_type == switches::kGpuProcess || 442 CHECK(process_type == switches::kGpuProcess ||
443 process_type == switches::kRendererProcess || 443 process_type == switches::kRendererProcess ||
444 #if BUILDFLAG(ENABLE_PLUGINS) 444 #if BUILDFLAG(ENABLE_PLUGINS)
445 process_type == switches::kPpapiPluginProcess || 445 process_type == switches::kPpapiPluginProcess ||
446 #endif 446 #endif
447 process_type == switches::kUtilityProcess) 447 process_type == switches::kUtilityProcess)
448 << "Unsupported process type: " << process_type; 448 << "Unsupported process type: " << process_type;
449 449
450 // Non-sandboxed utility or renderer process are currently not supported. 450 // Non-sandboxed utility or renderer process are currently not supported.
451 DCHECK(process_type == switches::kGpuProcess || 451 DCHECK(process_type == switches::kGpuProcess ||
452 !cmd_line->HasSwitch(switches::kNoSandbox)); 452 !cmd_line->HasSwitch(switches::kNoSandbox));
453 453
454 #endif 454 #endif
455 mojo::edk::ScopedPlatformHandle server_handle; 455 mojo::edk::ScopedPlatformHandle server_handle;
456 mojo::edk::ScopedPlatformHandle client_handle; 456 mojo::edk::ScopedPlatformHandle client_handle;
457 #if defined(OS_WIN) 457 #if defined(OS_WIN)
458 if (delegate->ShouldLaunchElevated()) { 458 if (delegate->ShouldLaunchElevated()) {
459 mojo::edk::NamedPlatformChannelPair named_pair; 459 mojo::edk::NamedPlatformChannelPair named_pair;
460 server_handle = named_pair.PassServerHandle(); 460 server_handle = named_pair.PassServerHandle();
461 named_pair.PrepareToPassClientHandleToChildProcess(cmd_line); 461 named_pair.PrepareToPassClientHandleToChildProcess(cmd_line.get());
462 } else 462 } else
463 #endif 463 #endif
464 { 464 {
465 mojo::edk::PlatformChannelPair channel_pair; 465 mojo::edk::PlatformChannelPair channel_pair;
466 server_handle = channel_pair.PassServerHandle(); 466 server_handle = channel_pair.PassServerHandle();
467 client_handle = channel_pair.PassClientHandle(); 467 client_handle = channel_pair.PassClientHandle();
468 } 468 }
469 NotifyCallback reply_callback(base::Bind(&ChildProcessLauncher::DidLaunch, 469 NotifyCallback reply_callback(base::Bind(&ChildProcessLauncher::DidLaunch,
470 weak_factory_.GetWeakPtr(), 470 weak_factory_.GetWeakPtr(),
471 terminate_child_on_shutdown_, 471 terminate_child_on_shutdown_,
472 base::Passed(&server_handle))); 472 base::Passed(&server_handle)));
473 BrowserThread::PostTask( 473 BrowserThread::PostTask(
474 BrowserThread::PROCESS_LAUNCHER, FROM_HERE, 474 BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
475 base::Bind(&LaunchOnLauncherThread, reply_callback, client_thread_id_, 475 base::Bind(&LaunchOnLauncherThread, reply_callback, client_thread_id_,
476 child_process_id, delegate, 476 child_process_id, base::Passed(&delegate),
477 base::Passed(&client_handle), cmd_line)); 477 base::Passed(&client_handle), base::Passed(&cmd_line)));
478 } 478 }
479 479
480 void ChildProcessLauncher::UpdateTerminationStatus(bool known_dead) { 480 void ChildProcessLauncher::UpdateTerminationStatus(bool known_dead) {
481 DCHECK(CalledOnValidThread()); 481 DCHECK(CalledOnValidThread());
482 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 482 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
483 if (zygote_) { 483 if (zygote_) {
484 termination_status_ = zygote_->GetTerminationStatus( 484 termination_status_ = zygote_->GetTerminationStatus(
485 process_.Handle(), known_dead, &exit_code_); 485 process_.Handle(), known_dead, &exit_code_);
486 } else if (known_dead) { 486 } else if (known_dead) {
487 termination_status_ = 487 termination_status_ =
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 } 605 }
606 606
607 ChildProcessLauncher::Client* ChildProcessLauncher::ReplaceClientForTest( 607 ChildProcessLauncher::Client* ChildProcessLauncher::ReplaceClientForTest(
608 Client* client) { 608 Client* client) {
609 Client* ret = client_; 609 Client* ret = client_;
610 client_ = client; 610 client_ = client;
611 return ret; 611 return ret;
612 } 612 }
613 613
614 } // namespace content 614 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/child_process_launcher.h ('k') | content/browser/gpu/gpu_process_host.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698