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

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

Issue 2680123003: Multi-Process Tracking Support (Closed)
Patch Set: record command-line when a process is started 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 88
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 }
98
97 base::win::ScopedProcessInformation proc_info(temp_process_info); 99 base::win::ScopedProcessInformation proc_info(temp_process_info);
100 base::debug::GlobalActivityTracker* tracker =
manzagop (departed) 2017/02/24 15:56:35 Use your *IfEnabled counterpart?
bcwhite 2017/03/06 16:33:52 Some of the parameters can be expensive to generat
manzagop (departed) 2017/03/07 22:08:57 Probably worth a comment.
bcwhite 2017/03/09 14:07:54 Done. (in the activity_tracker.h file)
101 base::debug::GlobalActivityTracker::Get();
102 if (tracker)
103 tracker->RecordProcessLaunch(proc_info.process_id(), cl.as_string());
98 104
99 // Close our writing end of pipe now. Otherwise later read would not be able 105 // Close our writing end of pipe now. Otherwise later read would not be able
100 // to detect end of child's output. 106 // to detect end of child's output.
101 scoped_out_write.Close(); 107 scoped_out_write.Close();
102 108
103 // Read output from the child process's pipe for STDOUT 109 // Read output from the child process's pipe for STDOUT
104 const int kBufferSize = 1024; 110 const int kBufferSize = 1024;
105 char buffer[kBufferSize]; 111 char buffer[kBufferSize];
106 112
107 for (;;) { 113 for (;;) {
108 DWORD bytes_read = 0; 114 DWORD bytes_read = 0;
109 BOOL success = 115 BOOL success =
110 ReadFile(out_read, buffer, kBufferSize, &bytes_read, nullptr); 116 ReadFile(out_read, buffer, kBufferSize, &bytes_read, nullptr);
111 if (!success || bytes_read == 0) 117 if (!success || bytes_read == 0)
112 break; 118 break;
113 output->append(buffer, bytes_read); 119 output->append(buffer, bytes_read);
114 } 120 }
115 121
116 // Let's wait for the process to finish. 122 // Let's wait for the process to finish.
117 WaitForSingleObject(proc_info.process_handle(), INFINITE); 123 WaitForSingleObject(proc_info.process_handle(), INFINITE);
118 124
119 int exit_code; 125 int exit_code;
120 base::TerminationStatus status = GetTerminationStatus( 126 base::TerminationStatus status = GetTerminationStatus(
121 proc_info.process_handle(), &exit_code); 127 proc_info.process_handle(), &exit_code);
128 base::debug::GlobalActivityTracker::RecordProcessExitIfEnabled(
129 proc_info.process_id(), exit_code);
122 return status != base::TERMINATION_STATUS_PROCESS_CRASHED && 130 return status != base::TERMINATION_STATUS_PROCESS_CRASHED &&
123 status != base::TERMINATION_STATUS_ABNORMAL_TERMINATION; 131 status != base::TERMINATION_STATUS_ABNORMAL_TERMINATION;
124 } 132 }
125 133
126 } // namespace 134 } // namespace
127 135
128 void RouteStdioToConsole(bool create_console_if_not_found) { 136 void RouteStdioToConsole(bool create_console_if_not_found) {
129 // Don't change anything if stdout or stderr already point to a 137 // Don't change anything if stdout or stderr already point to a
130 // valid stream. 138 // valid stream.
131 // 139 //
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 scoped_process.Terminate(kProcessKilledExitCode, true); 318 scoped_process.Terminate(kProcessKilledExitCode, true);
311 return Process(); 319 return Process();
312 } 320 }
313 321
314 ResumeThread(process_info.thread_handle()); 322 ResumeThread(process_info.thread_handle());
315 } 323 }
316 324
317 if (options.wait) 325 if (options.wait)
318 WaitForSingleObject(process_info.process_handle(), INFINITE); 326 WaitForSingleObject(process_info.process_handle(), INFINITE);
319 327
328 base::debug::GlobalActivityTracker::RecordProcessLaunchIfEnabled(
329 process_info.process_id(), cmdline);
320 return Process(process_info.TakeProcessHandle()); 330 return Process(process_info.TakeProcessHandle());
321 } 331 }
322 332
323 Process LaunchElevatedProcess(const CommandLine& cmdline, 333 Process LaunchElevatedProcess(const CommandLine& cmdline,
324 const LaunchOptions& options) { 334 const LaunchOptions& options) {
325 const string16 file = cmdline.GetProgram().value(); 335 const string16 file = cmdline.GetProgram().value();
326 const string16 arguments = cmdline.GetArgumentsString(); 336 const string16 arguments = cmdline.GetArgumentsString();
327 337
328 SHELLEXECUTEINFO shex_info = {}; 338 SHELLEXECUTEINFO shex_info = {};
329 shex_info.cbSize = sizeof(shex_info); 339 shex_info.cbSize = sizeof(shex_info);
330 shex_info.fMask = SEE_MASK_NOCLOSEPROCESS; 340 shex_info.fMask = SEE_MASK_NOCLOSEPROCESS;
331 shex_info.hwnd = GetActiveWindow(); 341 shex_info.hwnd = GetActiveWindow();
332 shex_info.lpVerb = L"runas"; 342 shex_info.lpVerb = L"runas";
333 shex_info.lpFile = file.c_str(); 343 shex_info.lpFile = file.c_str();
334 shex_info.lpParameters = arguments.c_str(); 344 shex_info.lpParameters = arguments.c_str();
335 shex_info.lpDirectory = nullptr; 345 shex_info.lpDirectory = nullptr;
336 shex_info.nShow = options.start_hidden ? SW_HIDE : SW_SHOW; 346 shex_info.nShow = options.start_hidden ? SW_HIDE : SW_SHOW;
337 shex_info.hInstApp = nullptr; 347 shex_info.hInstApp = nullptr;
338 348
339 if (!ShellExecuteEx(&shex_info)) { 349 if (!ShellExecuteEx(&shex_info)) {
340 DPLOG(ERROR); 350 DPLOG(ERROR);
341 return Process(); 351 return Process();
342 } 352 }
343 353
344 if (options.wait) 354 if (options.wait)
345 WaitForSingleObject(shex_info.hProcess, INFINITE); 355 WaitForSingleObject(shex_info.hProcess, INFINITE);
346 356
357 base::debug::GlobalActivityTracker::RecordProcessLaunchIfEnabled(
358 GetProcessId(shex_info.hProcess), file, arguments);
347 return Process(shex_info.hProcess); 359 return Process(shex_info.hProcess);
348 } 360 }
349 361
350 bool SetJobObjectLimitFlags(HANDLE job_object, DWORD limit_flags) { 362 bool SetJobObjectLimitFlags(HANDLE job_object, DWORD limit_flags) {
351 JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info = {}; 363 JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info = {};
352 limit_info.BasicLimitInformation.LimitFlags = limit_flags; 364 limit_info.BasicLimitInformation.LimitFlags = limit_flags;
353 return 0 != SetInformationJobObject( 365 return 0 != SetInformationJobObject(
354 job_object, 366 job_object,
355 JobObjectExtendedLimitInformation, 367 JobObjectExtendedLimitInformation,
356 &limit_info, 368 &limit_info,
(...skipping 10 matching lines...) Expand all
367 379
368 bool GetAppOutput(const StringPiece16& cl, std::string* output) { 380 bool GetAppOutput(const StringPiece16& cl, std::string* output) {
369 return GetAppOutputInternal(cl, false, output); 381 return GetAppOutputInternal(cl, false, output);
370 } 382 }
371 383
372 void RaiseProcessToHighPriority() { 384 void RaiseProcessToHighPriority() {
373 SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); 385 SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
374 } 386 }
375 387
376 } // namespace base 388 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698