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

Side by Side Diff: experimental/windows_debugger/debugger/core/debug_execution_engine.cc

Issue 10928195: First round of dead file removal (Closed) Base URL: https://github.com/samclegg/nativeclient-sdk.git@master
Patch Set: Created 8 years, 3 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
(Empty)
1 // Copyright (c) 2011 The Native Client Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 #include "debugger/core/debug_api.h"
5 #include <algorithm>
6 #include "debugger/core/debug_execution_engine.h"
7 #include "debugger/core/debug_logger.h"
8 #include "debugger/core/debuggee_process.h"
9
10 namespace {
11 /// Timeout for exiting processes. If nothing happens for
12 /// kWaitOnExitMs milliseconds, ExecutionEngine quits waiting
13 /// for debug events.
14 int kWaitOnExitMs = 300;
15
16 bool not_dead_proc(debug::IDebuggeeProcess* proc) {
17 return debug::IDebuggeeProcess::kDead != proc->state();
18 }
19 void delete_proc(debug::IDebuggeeProcess* proc) { delete proc; }
20 void detach_proc(debug::IDebuggeeProcess* proc) {
21 proc->Detach();
22 }
23 void kill_proc(debug::IDebuggeeProcess* proc) {
24 proc->Kill();
25 }
26 } // namespace
27
28 namespace debug {
29
30 ExecutionEngine::ExecutionEngine(DebugAPI* debug_api)
31 : debug_api_(*debug_api) {
32 }
33
34 ExecutionEngine::~ExecutionEngine() {
35 Stop(kWaitOnExitMs);
36 std::for_each(processes_.begin(), processes_.end(), delete_proc);
37 processes_.clear();
38 }
39
40 IDebuggeeProcess* ExecutionEngine::CreateDebuggeeProcess(int pid,
41 HANDLE handle,
42 HANDLE file_handle) {
43 return new DebuggeeProcess(pid, handle, file_handle, &debug_api_);
44 }
45
46 bool ExecutionEngine::StartProcess(const char* cmd, const char* work_dir) {
47 STARTUPINFO si;
48 memset(&si, 0, sizeof(si));
49 si.cb = sizeof(si);
50 PROCESS_INFORMATION pi;
51 memset(&pi, 0, sizeof(pi));
52
53 char* cmd_dup = _strdup(cmd);
54 if (NULL == cmd_dup) {
55 DBG_LOG("TR01.00", "Memory allocation error.");
56 return false;
57 }
58 BOOL res = debug_api_.CreateProcess(NULL,
59 cmd_dup,
60 NULL,
61 NULL,
62 FALSE,
63 DEBUG_PROCESS | CREATE_NEW_CONSOLE,
64 NULL,
65 work_dir,
66 &si,
67 &pi);
68 free(cmd_dup);
69 if (!res)
70 return false;
71
72 debug_api_.CloseHandle(pi.hThread);
73 debug_api_.CloseHandle(pi.hProcess);
74 return true;
75 }
76
77 bool ExecutionEngine::AttachToProcess(int pid) {
78 return (TRUE == debug_api_.DebugActiveProcess(pid)) ? true : false;
79 }
80
81 void ExecutionEngine::DetachAll() {
82 std::for_each(processes_.begin(), processes_.end(), detach_proc);
83 std::for_each(processes_.begin(), processes_.end(), delete_proc);
84 processes_.clear();
85 }
86
87 IDebuggeeProcess* ExecutionEngine::GetProcess(int pid) {
88 ProcessConstIter it = processes_.begin();
89 while (it != processes_.end()) {
90 IDebuggeeProcess* proc = *it;
91 ++it;
92 if (pid == proc->id())
93 return proc;
94 }
95 return NULL;
96 }
97
98 void ExecutionEngine::GetProcessIds(std::deque<int>* processes) const {
99 processes->clear();
100 ProcessConstIter it = processes_.begin();
101 while (it != processes_.end()) {
102 processes->push_back((*it)->id());
103 ++it;
104 }
105 }
106
107 void ExecutionEngine::RemoveDeadProcesses() {
108 ProcessIter it = std::partition(processes_.begin(),
109 processes_.end(),
110 not_dead_proc);
111 std::for_each(it, processes_.end(), delete_proc);
112 processes_.erase(it, processes_.end());
113 }
114
115 bool ExecutionEngine::WaitForDebugEventAndDispatchIt(int wait_ms,
116 int* halted_pid) {
117 RemoveDeadProcesses();
118 DEBUG_EVENT de;
119 if (debug_api_.WaitForDebugEvent(&de, wait_ms)) {
120 int pid = OnDebugEvent(de);
121 if (NULL != halted_pid)
122 *halted_pid = pid;
123 return true;
124 }
125 return false;
126 }
127
128 int ExecutionEngine::OnDebugEvent(const DEBUG_EVENT& debug_event) {
129 debug_event_.set_windows_debug_event(debug_event);
130 debug_event_.set_nacl_debug_event_code(DebugEvent::kNotNaClDebugEvent);
131
132 IDebuggeeProcess* process = GetProcess(debug_event.dwProcessId);
133
134 if (CREATE_PROCESS_DEBUG_EVENT == debug_event.dwDebugEventCode) {
135 process = CreateDebuggeeProcess(debug_event.dwProcessId,
136 debug_event.u.CreateProcessInfo.hProcess,
137 debug_event.u.CreateProcessInfo.hFile);
138 if (NULL != process)
139 processes_.push_back(process);
140 }
141
142 char tmp[1000];
143 debug_event_.ToString(tmp, sizeof(tmp));
144 DBG_LOG("TR01.01", "msg='ExecutionEngine::OnDebugEvent' event='%s'", tmp);
145
146 if (NULL != process) {
147 process->OnDebugEvent(&debug_event_);
148 if (process->IsHalted())
149 return process->id();
150 }
151 return 0;
152 }
153
154 void ExecutionEngine::Stop(int wait_ms) {
155 std::for_each(processes_.begin(), processes_.end(), kill_proc);
156 while (processes_.size() > 0) {
157 int halted_pid = 0;
158 WaitForDebugEventAndDispatchIt(wait_ms, &halted_pid);
159 if (0 != halted_pid) {
160 IDebuggeeProcess* proc = GetProcess(halted_pid);
161 proc->ContinueAndPassExceptionToDebuggee();
162 } else {
163 break; // Timed-out, stop waiting for processes to shut down.
164 }
165 }
166 }
167 } // namespace debug
168
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698