1 //===-- TargetList.cpp ------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // C Includes 11 // C++ Includes 12 // Other libraries and framework includes 13 // Project includes 14 #include "lldb/Core/Broadcaster.h" 15 #include "lldb/Core/Event.h" 16 #include "lldb/Core/State.h" 17 #include "lldb/Core/Timer.h" 18 #include "lldb/Host/Host.h" 19 #include "lldb/Target/Process.h" 20 #include "lldb/Target/TargetList.h" 21 22 using namespace lldb; 23 using namespace lldb_private; 24 25 26 //---------------------------------------------------------------------- 27 // TargetList constructor 28 //---------------------------------------------------------------------- 29 TargetList::TargetList() : 30 Broadcaster("TargetList"), 31 m_target_list(), 32 m_target_list_mutex (Mutex::eMutexTypeRecursive), 33 m_current_target_idx (0) 34 { 35 } 36 37 //---------------------------------------------------------------------- 38 // Destructor 39 //---------------------------------------------------------------------- 40 TargetList::~TargetList() 41 { 42 Mutex::Locker locker(m_target_list_mutex); 43 m_target_list.clear(); 44 } 45 46 Error 47 TargetList::CreateTarget 48 ( 49 Debugger &debugger, 50 const FileSpec& file, 51 const ArchSpec& arch, 52 const UUID *uuid_ptr, 53 bool get_dependent_files, 54 TargetSP &target_sp 55 ) 56 { 57 Timer scoped_timer (__PRETTY_FUNCTION__, 58 "TargetList::CreateTarget (file = '%s/%s', arch = '%s', uuid = %p)", 59 file.GetDirectory().AsCString(), 60 file.GetFilename().AsCString(), 61 arch.AsCString(), 62 uuid_ptr); 63 ModuleSP exe_module_sp; 64 FileSpec resolved_file(file); 65 if (!Host::ResolveExecutableInBundle (&resolved_file)) 66 resolved_file = file; 67 68 Error error = ModuleList::GetSharedModule(resolved_file, 69 arch, 70 uuid_ptr, 71 NULL, 72 0, 73 exe_module_sp, 74 NULL, 75 NULL); 76 if (exe_module_sp) 77 { 78 target_sp.reset(new Target(debugger)); 79 target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); 80 81 if (target_sp.get()) 82 { 83 Mutex::Locker locker(m_target_list_mutex); 84 m_current_target_idx = m_target_list.size(); 85 m_target_list.push_back(target_sp); 86 } 87 88 // target_sp.reset(new Target); 89 // // Let the target resolve any funky bundle paths before we try and get 90 // // the object file... 91 // target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); 92 // if (exe_module_sp->GetObjectFile() == NULL) 93 // { 94 // error.SetErrorStringWithFormat("%s%s%s: doesn't contain architecture %s", 95 // file.GetDirectory().AsCString(), 96 // file.GetDirectory() ? "/" : "", 97 // file.GetFilename().AsCString(), 98 // arch.AsCString()); 99 // } 100 // else 101 // { 102 // if (target_sp.get()) 103 // { 104 // error.Clear(); 105 // Mutex::Locker locker(m_target_list_mutex); 106 // m_current_target_idx = m_target_list.size(); 107 // m_target_list.push_back(target_sp); 108 // } 109 // } 110 } 111 else 112 { 113 target_sp.reset(); 114 } 115 116 return error; 117 } 118 119 bool 120 TargetList::DeleteTarget (TargetSP &target_sp) 121 { 122 Mutex::Locker locker(m_target_list_mutex); 123 collection::iterator pos, end = m_target_list.end(); 124 125 for (pos = m_target_list.begin(); pos != end; ++pos) 126 { 127 if (pos->get() == target_sp.get()) 128 { 129 m_target_list.erase(pos); 130 return true; 131 } 132 } 133 return false; 134 } 135 136 137 TargetSP 138 TargetList::FindTargetWithExecutableAndArchitecture 139 ( 140 const FileSpec &exe_file_spec, 141 const ArchSpec *exe_arch_ptr 142 ) const 143 { 144 Mutex::Locker locker (m_target_list_mutex); 145 TargetSP target_sp; 146 bool full_match = exe_file_spec.GetDirectory(); 147 148 collection::const_iterator pos, end = m_target_list.end(); 149 for (pos = m_target_list.begin(); pos != end; ++pos) 150 { 151 ModuleSP module_sp ((*pos)->GetExecutableModule()); 152 153 if (module_sp) 154 { 155 if (FileSpec::Equal (exe_file_spec, module_sp->GetFileSpec(), full_match)) 156 { 157 if (exe_arch_ptr) 158 { 159 if (*exe_arch_ptr != module_sp->GetArchitecture()) 160 continue; 161 } 162 target_sp = *pos; 163 break; 164 } 165 } 166 } 167 return target_sp; 168 } 169 170 TargetSP 171 TargetList::FindTargetWithProcessID (lldb::pid_t pid) const 172 { 173 Mutex::Locker locker(m_target_list_mutex); 174 TargetSP target_sp; 175 collection::const_iterator pos, end = m_target_list.end(); 176 for (pos = m_target_list.begin(); pos != end; ++pos) 177 { 178 Process* process = (*pos)->GetProcessSP().get(); 179 if (process && process->GetID() == pid) 180 { 181 target_sp = *pos; 182 break; 183 } 184 } 185 return target_sp; 186 } 187 188 189 TargetSP 190 TargetList::FindTargetWithProcess (Process *process) const 191 { 192 TargetSP target_sp; 193 if (process) 194 { 195 Mutex::Locker locker(m_target_list_mutex); 196 collection::const_iterator pos, end = m_target_list.end(); 197 for (pos = m_target_list.begin(); pos != end; ++pos) 198 { 199 if (process == (*pos)->GetProcessSP().get()) 200 { 201 target_sp = *pos; 202 break; 203 } 204 } 205 } 206 return target_sp; 207 } 208 209 TargetSP 210 TargetList::GetTargetSP (Target *target) const 211 { 212 TargetSP target_sp; 213 if (target) 214 { 215 Mutex::Locker locker(m_target_list_mutex); 216 collection::const_iterator pos, end = m_target_list.end(); 217 for (pos = m_target_list.begin(); pos != end; ++pos) 218 { 219 if (target == (*pos).get()) 220 { 221 target_sp = *pos; 222 break; 223 } 224 } 225 } 226 return target_sp; 227 } 228 229 uint32_t 230 TargetList::SendAsyncInterrupt (lldb::pid_t pid) 231 { 232 uint32_t num_async_interrupts_sent = 0; 233 234 if (pid != LLDB_INVALID_PROCESS_ID) 235 { 236 TargetSP target_sp(FindTargetWithProcessID (pid)); 237 if (target_sp.get()) 238 { 239 Process* process = target_sp->GetProcessSP().get(); 240 if (process) 241 { 242 process->BroadcastEvent (Process::eBroadcastBitInterrupt, NULL); 243 ++num_async_interrupts_sent; 244 } 245 } 246 } 247 else 248 { 249 // We don't have a valid pid to broadcast to, so broadcast to the target 250 // list's async broadcaster... 251 BroadcastEvent (Process::eBroadcastBitInterrupt, NULL); 252 } 253 254 return num_async_interrupts_sent; 255 } 256 257 uint32_t 258 TargetList::SignalIfRunning (lldb::pid_t pid, int signo) 259 { 260 uint32_t num_signals_sent = 0; 261 Process *process = NULL; 262 if (pid == LLDB_INVALID_PROCESS_ID) 263 { 264 // Signal all processes with signal 265 Mutex::Locker locker(m_target_list_mutex); 266 collection::iterator pos, end = m_target_list.end(); 267 for (pos = m_target_list.begin(); pos != end; ++pos) 268 { 269 process = (*pos)->GetProcessSP().get(); 270 if (process) 271 { 272 if (process->IsAlive()) 273 { 274 ++num_signals_sent; 275 process->Signal (signo); 276 } 277 } 278 } 279 } 280 else 281 { 282 // Signal a specific process with signal 283 TargetSP target_sp(FindTargetWithProcessID (pid)); 284 if (target_sp.get()) 285 { 286 process = target_sp->GetProcessSP().get(); 287 if (process) 288 { 289 if (process->IsAlive()) 290 { 291 ++num_signals_sent; 292 process->Signal (signo); 293 } 294 } 295 } 296 } 297 return num_signals_sent; 298 } 299 300 int 301 TargetList::GetNumTargets () const 302 { 303 Mutex::Locker locker (m_target_list_mutex); 304 return m_target_list.size(); 305 } 306 307 lldb::TargetSP 308 TargetList::GetTargetAtIndex (uint32_t idx) const 309 { 310 TargetSP target_sp; 311 Mutex::Locker locker (m_target_list_mutex); 312 if (idx < m_target_list.size()) 313 target_sp = m_target_list[idx]; 314 return target_sp; 315 } 316 317 uint32_t 318 TargetList::SetCurrentTarget (Target* target) 319 { 320 Mutex::Locker locker (m_target_list_mutex); 321 collection::const_iterator pos, 322 begin = m_target_list.begin(), 323 end = m_target_list.end(); 324 for (pos = begin; pos != end; ++pos) 325 { 326 if (pos->get() == target) 327 { 328 m_current_target_idx = std::distance (begin, pos); 329 return m_current_target_idx; 330 } 331 } 332 m_current_target_idx = 0; 333 return m_current_target_idx; 334 } 335 336 lldb::TargetSP 337 TargetList::GetCurrentTarget () 338 { 339 Mutex::Locker locker (m_target_list_mutex); 340 if (m_current_target_idx >= m_target_list.size()) 341 m_current_target_idx = 0; 342 return GetTargetAtIndex (m_current_target_idx); 343 } 344