1 //===-- NativeProcessProtocol.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 #include "NativeProcessProtocol.h" 11 12 #include "lldb/lldb-enumerations.h" 13 #include "lldb/Core/ArchSpec.h" 14 #include "lldb/Core/Log.h" 15 #include "lldb/Core/State.h" 16 #include "lldb/Target/NativeRegisterContext.h" 17 18 #include "NativeThreadProtocol.h" 19 #include "SoftwareBreakpoint.h" 20 21 using namespace lldb; 22 using namespace lldb_private; 23 24 // ----------------------------------------------------------------------------- 25 // NativeProcessProtocol Members 26 // ----------------------------------------------------------------------------- 27 28 NativeProcessProtocol::NativeProcessProtocol (lldb::pid_t pid) : 29 m_pid (pid), 30 m_threads (), 31 m_current_thread_id (LLDB_INVALID_THREAD_ID), 32 m_threads_mutex (Mutex::eMutexTypeRecursive), 33 m_state (lldb::eStateInvalid), 34 m_state_mutex (Mutex::eMutexTypeRecursive), 35 m_exit_type (eExitTypeInvalid), 36 m_exit_status (0), 37 m_exit_description (), 38 m_delegates_mutex (Mutex::eMutexTypeRecursive), 39 m_delegates (), 40 m_breakpoint_list (), 41 m_terminal_fd (-1), 42 m_stop_id (0) 43 { 44 } 45 46 lldb_private::Error 47 NativeProcessProtocol::GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInfo &range_info) 48 { 49 // Default: not implemented. 50 return Error ("not implemented"); 51 } 52 53 bool 54 NativeProcessProtocol::GetExitStatus (ExitType *exit_type, int *status, std::string &exit_description) 55 { 56 if (m_state == lldb::eStateExited) 57 { 58 *exit_type = m_exit_type; 59 *status = m_exit_status; 60 exit_description = m_exit_description; 61 return true; 62 } 63 64 *status = 0; 65 return false; 66 } 67 68 bool 69 NativeProcessProtocol::SetExitStatus (ExitType exit_type, int status, const char *exit_description, bool bNotifyStateChange) 70 { 71 Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 72 if (log) 73 log->Printf ("NativeProcessProtocol::%s(%d, %d, %s, %s) called", 74 __FUNCTION__, 75 exit_type, 76 status, 77 exit_description ? exit_description : "nullptr", 78 bNotifyStateChange ? "true" : "false"); 79 80 // Exit status already set 81 if (m_state == lldb::eStateExited) 82 { 83 if (log) 84 log->Printf ("NativeProcessProtocol::%s exit status already set to %d, ignoring new set to %d", __FUNCTION__, m_exit_status, status); 85 return false; 86 } 87 88 m_state = lldb::eStateExited; 89 90 m_exit_type = exit_type; 91 m_exit_status = status; 92 if (exit_description && exit_description[0]) 93 m_exit_description = exit_description; 94 else 95 m_exit_description.clear(); 96 97 if (bNotifyStateChange) 98 SynchronouslyNotifyProcessStateChanged (lldb::eStateExited); 99 100 return true; 101 } 102 103 NativeThreadProtocolSP 104 NativeProcessProtocol::GetThreadAtIndex (uint32_t idx) 105 { 106 Mutex::Locker locker (m_threads_mutex); 107 if (idx < m_threads.size ()) 108 return m_threads[idx]; 109 return NativeThreadProtocolSP (); 110 } 111 112 NativeThreadProtocolSP 113 NativeProcessProtocol::GetThreadByID (lldb::tid_t tid) 114 { 115 Mutex::Locker locker (m_threads_mutex); 116 for (auto thread_sp : m_threads) 117 { 118 if (thread_sp->GetID() == tid) 119 return thread_sp; 120 } 121 return NativeThreadProtocolSP (); 122 } 123 124 bool 125 NativeProcessProtocol::IsAlive () const 126 { 127 return m_state != eStateDetached 128 && m_state != eStateExited 129 && m_state != eStateInvalid 130 && m_state != eStateUnloaded; 131 } 132 133 bool 134 NativeProcessProtocol::GetByteOrder (lldb::ByteOrder &byte_order) const 135 { 136 ArchSpec process_arch; 137 if (!GetArchitecture (process_arch)) 138 return false; 139 byte_order = process_arch.GetByteOrder (); 140 return true; 141 } 142 143 uint32_t 144 NativeProcessProtocol::GetMaxWatchpoints () const 145 { 146 // This default implementation will return the number of 147 // *hardware* breakpoints available. MacOSX and other OS 148 // implementations that support software breakpoints will want to 149 // override this correctly for their implementation. 150 Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 151 152 // get any thread 153 NativeThreadProtocolSP thread_sp (const_cast<NativeProcessProtocol*> (this)->GetThreadAtIndex (0)); 154 if (!thread_sp) 155 { 156 if (log) 157 log->Warning ("NativeProcessProtocol::%s (): failed to find a thread to grab a NativeRegisterContext!", __FUNCTION__); 158 return 0; 159 } 160 161 NativeRegisterContextSP reg_ctx_sp (thread_sp->GetRegisterContext ()); 162 if (!reg_ctx_sp) 163 { 164 if (log) 165 log->Warning ("NativeProcessProtocol::%s (): failed to get a RegisterContextNativeProcess from the first thread!", __FUNCTION__); 166 return 0; 167 } 168 169 return reg_ctx_sp->NumSupportedHardwareWatchpoints (); 170 } 171 172 Error 173 NativeProcessProtocol::SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) 174 { 175 // This default implementation assumes setting the watchpoint for 176 // the process will require setting the watchpoint for each of the 177 // threads. Furthermore, it will track watchpoints set for the 178 // process and will add them to each thread that is attached to 179 // via the (FIXME implement) OnThreadAttached () method. 180 181 Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 182 183 // FIXME save the watchpoint on the set of process watchpoint vars 184 // so we can add them to a thread each time a new thread is registered. 185 186 // Update the thread list 187 UpdateThreads (); 188 189 // Keep track of the threads we successfully set the watchpoint 190 // for. If one of the thread watchpoint setting operations fails, 191 // back off and remove the watchpoint for all the threads that 192 // were successfully set so we get back to a consistent state. 193 std::vector<NativeThreadProtocolSP> watchpoint_established_threads; 194 195 // Tell each thread to set a watchpoint. In the event that 196 // hardware watchpoints are requested but the SetWatchpoint fails, 197 // try to set a software watchpoint as a fallback. It's 198 // conceivable that if there are more threads than hardware 199 // watchpoints available, some of the threads will fail to set 200 // hardware watchpoints while software ones may be available. 201 Mutex::Locker locker (m_threads_mutex); 202 for (auto thread_sp : m_threads) 203 { 204 assert (thread_sp && "thread list should not have a NULL thread!"); 205 if (!thread_sp) 206 continue; 207 208 Error thread_error = thread_sp->SetWatchpoint (addr, size, watch_flags, hardware); 209 if (thread_error.Fail () && hardware) 210 { 211 // Try software watchpoints since we failed on hardware watchpoint setting 212 // and we may have just run out of hardware watchpoints. 213 thread_error = thread_sp->SetWatchpoint (addr, size, watch_flags, false); 214 if (thread_error.Success ()) 215 { 216 if (log) 217 log->Warning ("hardware watchpoint requested but software watchpoint set"); 218 } 219 } 220 221 if (thread_error.Success ()) 222 { 223 // Remember that we set this watchpoint successfully in 224 // case we need to clear it later. 225 watchpoint_established_threads.push_back (thread_sp); 226 } 227 else 228 { 229 // Unset the watchpoint for each thread we successfully 230 // set so that we get back to a consistent state of "not 231 // set" for the watchpoint. 232 for (auto unwatch_thread_sp : watchpoint_established_threads) 233 { 234 Error remove_error = unwatch_thread_sp->RemoveWatchpoint (addr); 235 if (remove_error.Fail () && log) 236 { 237 log->Warning ("NativeProcessProtocol::%s (): RemoveWatchpoint failed for pid=%" PRIu64 ", tid=%" PRIu64 ": %s", 238 __FUNCTION__, GetID (), unwatch_thread_sp->GetID (), remove_error.AsCString ()); 239 } 240 } 241 242 return thread_error; 243 } 244 } 245 return Error (); 246 } 247 248 Error 249 NativeProcessProtocol::RemoveWatchpoint (lldb::addr_t addr) 250 { 251 // FIXME remove the watchpoint on the set of process watchpoint vars 252 // so we can add them to a thread each time a new thread is registered. 253 254 // Update the thread list 255 UpdateThreads (); 256 257 Error overall_error; 258 259 Mutex::Locker locker (m_threads_mutex); 260 for (auto thread_sp : m_threads) 261 { 262 assert (thread_sp && "thread list should not have a NULL thread!"); 263 if (!thread_sp) 264 continue; 265 266 const Error thread_error = thread_sp->RemoveWatchpoint (addr); 267 if (thread_error.Fail ()) 268 { 269 // Keep track of the first thread error if any threads 270 // fail. We want to try to remove the watchpoint from 271 // every thread, though, even if one or more have errors. 272 if (!overall_error.Fail ()) 273 overall_error = thread_error; 274 } 275 } 276 return overall_error; 277 } 278 279 bool 280 NativeProcessProtocol::RegisterNativeDelegate (NativeDelegate &native_delegate) 281 { 282 Mutex::Locker locker (m_delegates_mutex); 283 if (std::find (m_delegates.begin (), m_delegates.end (), &native_delegate) != m_delegates.end ()) 284 return false; 285 286 m_delegates.push_back (&native_delegate); 287 native_delegate.InitializeDelegate (this); 288 return true; 289 } 290 291 bool 292 NativeProcessProtocol::UnregisterNativeDelegate (NativeDelegate &native_delegate) 293 { 294 Mutex::Locker locker (m_delegates_mutex); 295 296 const auto initial_size = m_delegates.size (); 297 m_delegates.erase (remove (m_delegates.begin (), m_delegates.end (), &native_delegate), m_delegates.end ()); 298 299 // We removed the delegate if the count of delegates shrank after 300 // removing all copies of the given native_delegate from the vector. 301 return m_delegates.size () < initial_size; 302 } 303 304 void 305 NativeProcessProtocol::SynchronouslyNotifyProcessStateChanged (lldb::StateType state) 306 { 307 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 308 309 Mutex::Locker locker (m_delegates_mutex); 310 for (auto native_delegate: m_delegates) 311 native_delegate->ProcessStateChanged (this, state); 312 313 if (log) 314 { 315 if (!m_delegates.empty ()) 316 { 317 log->Printf ("NativeProcessProtocol::%s: sent state notification [%s] from process %" PRIu64, 318 __FUNCTION__, lldb_private::StateAsCString (state), GetID ()); 319 } 320 else 321 { 322 log->Printf ("NativeProcessProtocol::%s: would send state notification [%s] from process %" PRIu64 ", but no delegates", 323 __FUNCTION__, lldb_private::StateAsCString (state), GetID ()); 324 } 325 } 326 } 327 328 void 329 NativeProcessProtocol::NotifyDidExec () 330 { 331 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 332 if (log) 333 log->Printf ("NativeProcessProtocol::%s - preparing to call delegates", __FUNCTION__); 334 335 { 336 Mutex::Locker locker (m_delegates_mutex); 337 for (auto native_delegate: m_delegates) 338 native_delegate->DidExec (this); 339 } 340 } 341 342 343 Error 344 NativeProcessProtocol::SetSoftwareBreakpoint (lldb::addr_t addr, uint32_t size_hint) 345 { 346 Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); 347 if (log) 348 log->Printf ("NativeProcessProtocol::%s addr = 0x%" PRIx64, __FUNCTION__, addr); 349 350 return m_breakpoint_list.AddRef (addr, size_hint, false, 351 [this] (lldb::addr_t addr, size_t size_hint, bool /* hardware */, NativeBreakpointSP &breakpoint_sp)->Error 352 { return SoftwareBreakpoint::CreateSoftwareBreakpoint (*this, addr, size_hint, breakpoint_sp); }); 353 } 354 355 Error 356 NativeProcessProtocol::RemoveBreakpoint (lldb::addr_t addr) 357 { 358 return m_breakpoint_list.DecRef (addr); 359 } 360 361 Error 362 NativeProcessProtocol::EnableBreakpoint (lldb::addr_t addr) 363 { 364 return m_breakpoint_list.EnableBreakpoint (addr); 365 } 366 367 Error 368 NativeProcessProtocol::DisableBreakpoint (lldb::addr_t addr) 369 { 370 return m_breakpoint_list.DisableBreakpoint (addr); 371 } 372 373 lldb::StateType 374 NativeProcessProtocol::GetState () const 375 { 376 Mutex::Locker locker (m_state_mutex); 377 return m_state; 378 } 379 380 void 381 NativeProcessProtocol::SetState (lldb::StateType state, bool notify_delegates) 382 { 383 Mutex::Locker locker (m_state_mutex); 384 m_state = state; 385 386 if (StateIsStoppedState (state, false)) 387 { 388 ++m_stop_id; 389 390 // Give process a chance to do any stop id bump processing, such as 391 // clearing cached data that is invalidated each time the process runs. 392 // Note if/when we support some threads running, we'll end up needing 393 // to manage this per thread and per process. 394 DoStopIDBumped (m_stop_id); 395 } 396 397 // Optionally notify delegates of the state change. 398 if (notify_delegates) 399 SynchronouslyNotifyProcessStateChanged (state); 400 } 401 402 uint32_t NativeProcessProtocol::GetStopID () const 403 { 404 Mutex::Locker locker (m_state_mutex); 405 return m_stop_id; 406 } 407 408 void 409 NativeProcessProtocol::DoStopIDBumped (uint32_t /* newBumpId */) 410 { 411 // Default implementation does nothing. 412 } 413