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