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

Side by Side Diff: base/process/launch_win.cc

Issue 2680123003: Multi-Process Tracking Support (Closed)
Patch Set: added defined process-phase recording and process-exit callback support Created 3 years, 10 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
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 "base/process/launch.h" 5 #include "base/process/launch.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <io.h> 8 #include <io.h>
9 #include <shellapi.h> 9 #include <shellapi.h>
10 #include <windows.h> 10 #include <windows.h>
11 #include <userenv.h> 11 #include <userenv.h>
12 #include <psapi.h> 12 #include <psapi.h>
13 13
14 #include <ios> 14 #include <ios>
15 #include <limits> 15 #include <limits>
16 16
17 #include "base/bind.h" 17 #include "base/bind.h"
18 #include "base/bind_helpers.h" 18 #include "base/bind_helpers.h"
19 #include "base/command_line.h" 19 #include "base/command_line.h"
20 #include "base/debug/activity_tracker.h"
20 #include "base/debug/stack_trace.h" 21 #include "base/debug/stack_trace.h"
21 #include "base/logging.h" 22 #include "base/logging.h"
22 #include "base/message_loop/message_loop.h" 23 #include "base/message_loop/message_loop.h"
23 #include "base/metrics/histogram.h" 24 #include "base/metrics/histogram.h"
24 #include "base/process/kill.h" 25 #include "base/process/kill.h"
25 #include "base/strings/utf_string_conversions.h" 26 #include "base/strings/utf_string_conversions.h"
26 #include "base/sys_info.h" 27 #include "base/sys_info.h"
27 #include "base/win/scoped_handle.h" 28 #include "base/win/scoped_handle.h"
28 #include "base/win/scoped_process_information.h" 29 #include "base/win/scoped_process_information.h"
29 #include "base/win/startup_information.h" 30 #include "base/win/startup_information.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 // Create the child process. 89 // Create the child process.
89 PROCESS_INFORMATION temp_process_info = {}; 90 PROCESS_INFORMATION temp_process_info = {};
90 if (!CreateProcess(nullptr, &writable_command_line_string[0], nullptr, 91 if (!CreateProcess(nullptr, &writable_command_line_string[0], nullptr,
91 nullptr, 92 nullptr,
92 TRUE, // Handles are inherited. 93 TRUE, // Handles are inherited.
93 0, nullptr, nullptr, &start_info, &temp_process_info)) { 94 0, nullptr, nullptr, &start_info, &temp_process_info)) {
94 NOTREACHED() << "Failed to start process"; 95 NOTREACHED() << "Failed to start process";
95 return false; 96 return false;
96 } 97 }
97 base::win::ScopedProcessInformation proc_info(temp_process_info); 98 base::win::ScopedProcessInformation proc_info(temp_process_info);
99 base::debug::GlobalActivityTracker::RecordProcessLaunchIfEnabled(
100 proc_info.process_id());
98 101
99 // Close our writing end of pipe now. Otherwise later read would not be able 102 // Close our writing end of pipe now. Otherwise later read would not be able
100 // to detect end of child's output. 103 // to detect end of child's output.
101 scoped_out_write.Close(); 104 scoped_out_write.Close();
102 105
103 // Read output from the child process's pipe for STDOUT 106 // Read output from the child process's pipe for STDOUT
104 const int kBufferSize = 1024; 107 const int kBufferSize = 1024;
105 char buffer[kBufferSize]; 108 char buffer[kBufferSize];
106 109
107 for (;;) { 110 for (;;) {
108 DWORD bytes_read = 0; 111 DWORD bytes_read = 0;
109 BOOL success = 112 BOOL success =
110 ReadFile(out_read, buffer, kBufferSize, &bytes_read, nullptr); 113 ReadFile(out_read, buffer, kBufferSize, &bytes_read, nullptr);
111 if (!success || bytes_read == 0) 114 if (!success || bytes_read == 0)
112 break; 115 break;
113 output->append(buffer, bytes_read); 116 output->append(buffer, bytes_read);
114 } 117 }
115 118
116 // Let's wait for the process to finish. 119 // Let's wait for the process to finish.
117 WaitForSingleObject(proc_info.process_handle(), INFINITE); 120 WaitForSingleObject(proc_info.process_handle(), INFINITE);
118 121
119 int exit_code; 122 int exit_code;
120 base::TerminationStatus status = GetTerminationStatus( 123 base::TerminationStatus status = GetTerminationStatus(
121 proc_info.process_handle(), &exit_code); 124 proc_info.process_handle(), &exit_code);
125 base::debug::GlobalActivityTracker::RecordProcessExitIfEnabled(
126 proc_info.process_id(), exit_code);
122 return status != base::TERMINATION_STATUS_PROCESS_CRASHED && 127 return status != base::TERMINATION_STATUS_PROCESS_CRASHED &&
123 status != base::TERMINATION_STATUS_ABNORMAL_TERMINATION; 128 status != base::TERMINATION_STATUS_ABNORMAL_TERMINATION;
124 } 129 }
125 130
126 } // namespace 131 } // namespace
127 132
128 void RouteStdioToConsole(bool create_console_if_not_found) { 133 void RouteStdioToConsole(bool create_console_if_not_found) {
129 // Don't change anything if stdout or stderr already point to a 134 // Don't change anything if stdout or stderr already point to a
130 // valid stream. 135 // valid stream.
131 // 136 //
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 scoped_process.Terminate(kProcessKilledExitCode, true); 315 scoped_process.Terminate(kProcessKilledExitCode, true);
311 return Process(); 316 return Process();
312 } 317 }
313 318
314 ResumeThread(process_info.thread_handle()); 319 ResumeThread(process_info.thread_handle());
315 } 320 }
316 321
317 if (options.wait) 322 if (options.wait)
318 WaitForSingleObject(process_info.process_handle(), INFINITE); 323 WaitForSingleObject(process_info.process_handle(), INFINITE);
319 324
325 base::debug::GlobalActivityTracker::RecordProcessLaunchIfEnabled(
326 process_info.process_id());
320 return Process(process_info.TakeProcessHandle()); 327 return Process(process_info.TakeProcessHandle());
321 } 328 }
322 329
323 Process LaunchElevatedProcess(const CommandLine& cmdline, 330 Process LaunchElevatedProcess(const CommandLine& cmdline,
324 const LaunchOptions& options) { 331 const LaunchOptions& options) {
325 const string16 file = cmdline.GetProgram().value(); 332 const string16 file = cmdline.GetProgram().value();
326 const string16 arguments = cmdline.GetArgumentsString(); 333 const string16 arguments = cmdline.GetArgumentsString();
327 334
328 SHELLEXECUTEINFO shex_info = {}; 335 SHELLEXECUTEINFO shex_info = {};
329 shex_info.cbSize = sizeof(shex_info); 336 shex_info.cbSize = sizeof(shex_info);
330 shex_info.fMask = SEE_MASK_NOCLOSEPROCESS; 337 shex_info.fMask = SEE_MASK_NOCLOSEPROCESS;
331 shex_info.hwnd = GetActiveWindow(); 338 shex_info.hwnd = GetActiveWindow();
332 shex_info.lpVerb = L"runas"; 339 shex_info.lpVerb = L"runas";
333 shex_info.lpFile = file.c_str(); 340 shex_info.lpFile = file.c_str();
334 shex_info.lpParameters = arguments.c_str(); 341 shex_info.lpParameters = arguments.c_str();
335 shex_info.lpDirectory = nullptr; 342 shex_info.lpDirectory = nullptr;
336 shex_info.nShow = options.start_hidden ? SW_HIDE : SW_SHOW; 343 shex_info.nShow = options.start_hidden ? SW_HIDE : SW_SHOW;
337 shex_info.hInstApp = nullptr; 344 shex_info.hInstApp = nullptr;
338 345
339 if (!ShellExecuteEx(&shex_info)) { 346 if (!ShellExecuteEx(&shex_info)) {
340 DPLOG(ERROR); 347 DPLOG(ERROR);
341 return Process(); 348 return Process();
342 } 349 }
343 350
344 if (options.wait) 351 if (options.wait)
345 WaitForSingleObject(shex_info.hProcess, INFINITE); 352 WaitForSingleObject(shex_info.hProcess, INFINITE);
346 353
354 base::debug::GlobalActivityTracker::RecordProcessLaunchIfEnabled(
355 GetProcessId(shex_info.hProcess));
347 return Process(shex_info.hProcess); 356 return Process(shex_info.hProcess);
348 } 357 }
349 358
350 bool SetJobObjectLimitFlags(HANDLE job_object, DWORD limit_flags) { 359 bool SetJobObjectLimitFlags(HANDLE job_object, DWORD limit_flags) {
351 JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info = {}; 360 JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info = {};
352 limit_info.BasicLimitInformation.LimitFlags = limit_flags; 361 limit_info.BasicLimitInformation.LimitFlags = limit_flags;
353 return 0 != SetInformationJobObject( 362 return 0 != SetInformationJobObject(
354 job_object, 363 job_object,
355 JobObjectExtendedLimitInformation, 364 JobObjectExtendedLimitInformation,
356 &limit_info, 365 &limit_info,
(...skipping 10 matching lines...) Expand all
367 376
368 bool GetAppOutput(const StringPiece16& cl, std::string* output) { 377 bool GetAppOutput(const StringPiece16& cl, std::string* output) {
369 return GetAppOutputInternal(cl, false, output); 378 return GetAppOutputInternal(cl, false, output);
370 } 379 }
371 380
372 void RaiseProcessToHighPriority() { 381 void RaiseProcessToHighPriority() {
373 SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); 382 SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
374 } 383 }
375 384
376 } // namespace base 385 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698