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

Side by Side Diff: base/process_util_win.cc

Issue 8674003: Move the ProcessWatcher methods out of content/common/process_watcher into base/process_util, alo... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 9 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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_util.h" 5 #include "base/process_util.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <io.h> 8 #include <io.h>
9 #include <windows.h> 9 #include <windows.h>
10 #include <userenv.h> 10 #include <userenv.h>
11 #include <psapi.h> 11 #include <psapi.h>
12 12
13 #include <ios> 13 #include <ios>
14 14
15 #include "base/command_line.h" 15 #include "base/command_line.h"
16 #include "base/debug/stack_trace.h" 16 #include "base/debug/stack_trace.h"
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/memory/scoped_ptr.h" 18 #include "base/memory/scoped_ptr.h"
19 #include "base/message_loop.h"
19 #include "base/metrics/histogram.h" 20 #include "base/metrics/histogram.h"
20 #include "base/sys_info.h" 21 #include "base/sys_info.h"
22 #include "base/win/object_watcher.h"
21 #include "base/win/scoped_handle.h" 23 #include "base/win/scoped_handle.h"
22 #include "base/win/windows_version.h" 24 #include "base/win/windows_version.h"
23 25
24 // userenv.dll is required for CreateEnvironmentBlock(). 26 // userenv.dll is required for CreateEnvironmentBlock().
25 #pragma comment(lib, "userenv.lib") 27 #pragma comment(lib, "userenv.lib")
26 28
27 namespace base { 29 namespace base {
28 30
29 namespace { 31 namespace {
30 32
31 // System pagesize. This value remains constant on x86/64 architectures. 33 // System pagesize. This value remains constant on x86/64 architectures.
32 const int PAGESIZE_KB = 4; 34 const int PAGESIZE_KB = 4;
33 35
34 // Exit codes with special meanings on Windows. 36 // Exit codes with special meanings on Windows.
35 const DWORD kNormalTerminationExitCode = 0; 37 const DWORD kNormalTerminationExitCode = 0;
36 const DWORD kDebuggerInactiveExitCode = 0xC0000354; 38 const DWORD kDebuggerInactiveExitCode = 0xC0000354;
37 const DWORD kKeyboardInterruptExitCode = 0xC000013A; 39 const DWORD kKeyboardInterruptExitCode = 0xC000013A;
38 const DWORD kDebuggerTerminatedExitCode = 0x40010004; 40 const DWORD kDebuggerTerminatedExitCode = 0x40010004;
39 41
42 // Maximum amount of time (in milliseconds) to wait for the process to exit.
43 static const int kWaitInterval = 2000;
44
40 // This exit code is used by the Windows task manager when it kills a 45 // This exit code is used by the Windows task manager when it kills a
41 // process. It's value is obviously not that unique, and it's 46 // process. It's value is obviously not that unique, and it's
42 // surprising to me that the task manager uses this value, but it 47 // surprising to me that the task manager uses this value, but it
43 // seems to be common practice on Windows to test for it as an 48 // seems to be common practice on Windows to test for it as an
44 // indication that the task manager has killed something if the 49 // indication that the task manager has killed something if the
45 // process goes away. 50 // process goes away.
46 const DWORD kProcessKilledExitCode = 1; 51 const DWORD kProcessKilledExitCode = 1;
47 52
48 // HeapSetInformation function pointer. 53 // HeapSetInformation function pointer.
49 typedef BOOL (WINAPI* HeapSetFn)(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T); 54 typedef BOOL (WINAPI* HeapSetFn)(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 101
97 void OnNoMemory() { 102 void OnNoMemory() {
98 // Kill the process. This is important for security, since WebKit doesn't 103 // Kill the process. This is important for security, since WebKit doesn't
99 // NULL-check many memory allocations. If a malloc fails, returns NULL, and 104 // NULL-check many memory allocations. If a malloc fails, returns NULL, and
100 // the buffer is then used, it provides a handy mapping of memory starting at 105 // the buffer is then used, it provides a handy mapping of memory starting at
101 // address 0 for an attacker to utilize. 106 // address 0 for an attacker to utilize.
102 __debugbreak(); 107 __debugbreak();
103 _exit(1); 108 _exit(1);
104 } 109 }
105 110
111 class TimerExpiredTask : public Task,
112 public win::ObjectWatcher::Delegate {
113 public:
114 explicit TimerExpiredTask(ProcessHandle process) : process_(process) {
115 watcher_.StartWatching(process_, this);
116 }
117
118 virtual ~TimerExpiredTask() {
119 if (process_) {
120 KillProcess();
121 DCHECK(!process_) << "Make sure to close the handle.";
122 }
123 }
124
125 // Task ---------------------------------------------------------------------
126
127 virtual void Run() {
128 if (process_)
129 KillProcess();
130 }
131
132 // MessageLoop::Watcher -----------------------------------------------------
133
134 virtual void OnObjectSignaled(HANDLE object) {
135 // When we're called from KillProcess, the ObjectWatcher may still be
136 // watching. the process handle, so make sure it has stopped.
137 watcher_.StopWatching();
138
139 CloseHandle(process_);
cpu_(ooo_6.6-7.5) 2011/11/24 00:22:07 I see a problem, here we close the handle, but we
140 process_ = NULL;
141 }
142
143 private:
144 void KillProcess() {
145 // OK, time to get frisky. We don't actually care when the process
146 // terminates. We just care that it eventually terminates, and that's what
147 // TerminateProcess should do for us. Don't check for the result code since
148 // it fails quite often. This should be investigated eventually.
149 base::KillProcess(process_, kProcessKilledExitCode, false);
150
151 // Now, just cleanup as if the process exited normally.
152 OnObjectSignaled(process_);
153 }
154
155 // The process that we are watching.
156 ProcessHandle process_;
157
158 win::ObjectWatcher watcher_;
159
160 DISALLOW_COPY_AND_ASSIGN(TimerExpiredTask);
161 };
162
106 } // namespace 163 } // namespace
107 164
108 ProcessId GetCurrentProcId() { 165 ProcessId GetCurrentProcId() {
109 return ::GetCurrentProcessId(); 166 return ::GetCurrentProcessId();
110 } 167 }
111 168
112 ProcessHandle GetCurrentProcessHandle() { 169 ProcessHandle GetCurrentProcessHandle() {
113 return ::GetCurrentProcess(); 170 return ::GetCurrentProcess();
114 } 171 }
115 172
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 int exit_code, 601 int exit_code,
545 const ProcessFilter* filter) { 602 const ProcessFilter* filter) {
546 bool exited_cleanly = WaitForProcessesToExit(executable_name, 603 bool exited_cleanly = WaitForProcessesToExit(executable_name,
547 wait_milliseconds, 604 wait_milliseconds,
548 filter); 605 filter);
549 if (!exited_cleanly) 606 if (!exited_cleanly)
550 KillProcesses(executable_name, exit_code, filter); 607 KillProcesses(executable_name, exit_code, filter);
551 return exited_cleanly; 608 return exited_cleanly;
552 } 609 }
553 610
611 void EnsureProcessTerminated(ProcessHandle process) {
612 DCHECK(process != GetCurrentProcess());
613
614 // If already signaled, then we are done!
615 if (WaitForSingleObject(process, 0) == WAIT_OBJECT_0) {
616 CloseHandle(process);
617 return;
618 }
619
620 MessageLoop::current()->PostDelayedTask(FROM_HERE,
621 new TimerExpiredTask(process),
622 kWaitInterval);
623 }
624
554 /////////////////////////////////////////////////////////////////////////////// 625 ///////////////////////////////////////////////////////////////////////////////
555 // ProcesMetrics 626 // ProcesMetrics
556 627
557 ProcessMetrics::ProcessMetrics(ProcessHandle process) 628 ProcessMetrics::ProcessMetrics(ProcessHandle process)
558 : process_(process), 629 : process_(process),
559 processor_count_(base::SysInfo::NumberOfProcessors()), 630 processor_count_(base::SysInfo::NumberOfProcessors()),
560 last_time_(0), 631 last_time_(0),
561 last_system_time_(0) { 632 last_system_time_(0) {
562 } 633 }
563 634
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 973
903 PERFORMANCE_INFORMATION info; 974 PERFORMANCE_INFORMATION info;
904 if (!InternalGetPerformanceInfo(&info, sizeof(info))) { 975 if (!InternalGetPerformanceInfo(&info, sizeof(info))) {
905 DLOG(ERROR) << "Failed to fetch internal performance info."; 976 DLOG(ERROR) << "Failed to fetch internal performance info.";
906 return 0; 977 return 0;
907 } 978 }
908 return (info.CommitTotal * system_info.dwPageSize) / 1024; 979 return (info.CommitTotal * system_info.dwPageSize) / 1024;
909 } 980 }
910 981
911 } // namespace base 982 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698