Debug.h revision 263367
1//===-- Debug.h -------------------------------------------------*- 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#ifndef liblldb_Debug_h_ 11#define liblldb_Debug_h_ 12 13#include "lldb/lldb-private.h" 14#include "lldb/Core/Error.h" 15#include "lldb/Core/StreamString.h" 16#include "lldb/Host/Mutex.h" 17#include <vector> 18 19namespace lldb_private { 20 21 //------------------------------------------------------------------ 22 // Tells a thread what it needs to do when the process is resumed. 23 //------------------------------------------------------------------ 24 struct ResumeAction 25 { 26 lldb::tid_t tid; // The thread ID that this action applies to, LLDB_INVALID_THREAD_ID for the default thread action 27 lldb::StateType state; // Valid values are eStateStopped/eStateSuspended, eStateRunning, and eStateStepping. 28 int signal; // When resuming this thread, resume it with this signal if this value is > 0 29 }; 30 31 //------------------------------------------------------------------ 32 // A class that contains instructions for all threads for 33 // NativeProcessProtocol::Resume(). Each thread can either run, stay 34 // suspended, or step when the process is resumed. We optionally 35 // have the ability to also send a signal to the thread when the 36 // action is run or step. 37 //------------------------------------------------------------------ 38 class ResumeActionList 39 { 40 public: 41 ResumeActionList () : 42 m_actions (), 43 m_signal_handled () 44 { 45 } 46 47 ResumeActionList (lldb::StateType default_action, int signal) : 48 m_actions(), 49 m_signal_handled () 50 { 51 SetDefaultThreadActionIfNeeded (default_action, signal); 52 } 53 54 55 ResumeActionList (const ResumeAction *actions, size_t num_actions) : 56 m_actions (), 57 m_signal_handled () 58 { 59 if (actions && num_actions) 60 { 61 m_actions.assign (actions, actions + num_actions); 62 m_signal_handled.assign (num_actions, false); 63 } 64 } 65 66 ~ResumeActionList() 67 { 68 } 69 70 bool 71 IsEmpty() const 72 { 73 return m_actions.empty(); 74 } 75 76 void 77 Append (const ResumeAction &action) 78 { 79 m_actions.push_back (action); 80 m_signal_handled.push_back (false); 81 } 82 83 void 84 AppendAction (lldb::tid_t tid, 85 lldb::StateType state, 86 int signal = 0) 87 { 88 ResumeAction action = { tid, state, signal }; 89 Append (action); 90 } 91 92 void 93 AppendResumeAll () 94 { 95 AppendAction (LLDB_INVALID_THREAD_ID, lldb::eStateRunning); 96 } 97 98 void 99 AppendSuspendAll () 100 { 101 AppendAction (LLDB_INVALID_THREAD_ID, lldb::eStateStopped); 102 } 103 104 void 105 AppendStepAll () 106 { 107 AppendAction (LLDB_INVALID_THREAD_ID, lldb::eStateStepping); 108 } 109 110 const ResumeAction * 111 GetActionForThread (lldb::tid_t tid, bool default_ok) const 112 { 113 const size_t num_actions = m_actions.size(); 114 for (size_t i=0; i<num_actions; ++i) 115 { 116 if (m_actions[i].tid == tid) 117 return &m_actions[i]; 118 } 119 if (default_ok && tid != LLDB_INVALID_THREAD_ID) 120 return GetActionForThread (LLDB_INVALID_THREAD_ID, false); 121 return NULL; 122 } 123 124 size_t 125 NumActionsWithState (lldb::StateType state) const 126 { 127 size_t count = 0; 128 const size_t num_actions = m_actions.size(); 129 for (size_t i=0; i<num_actions; ++i) 130 { 131 if (m_actions[i].state == state) 132 ++count; 133 } 134 return count; 135 } 136 137 bool 138 SetDefaultThreadActionIfNeeded (lldb::StateType action, int signal) 139 { 140 if (GetActionForThread (LLDB_INVALID_THREAD_ID, true) == NULL) 141 { 142 // There isn't a default action so we do need to set it. 143 ResumeAction default_action = {LLDB_INVALID_THREAD_ID, action, signal }; 144 m_actions.push_back (default_action); 145 m_signal_handled.push_back (false); 146 return true; // Return true as we did add the default action 147 } 148 return false; 149 } 150 151 void 152 SetSignalHandledForThread (lldb::tid_t tid) const 153 { 154 if (tid != LLDB_INVALID_THREAD_ID) 155 { 156 const size_t num_actions = m_actions.size(); 157 for (size_t i=0; i<num_actions; ++i) 158 { 159 if (m_actions[i].tid == tid) 160 m_signal_handled[i] = true; 161 } 162 } 163 } 164 165 const ResumeAction * 166 GetFirst() const 167 { 168 return m_actions.data(); 169 } 170 171 size_t 172 GetSize () const 173 { 174 return m_actions.size(); 175 } 176 177 void 178 Clear() 179 { 180 m_actions.clear(); 181 m_signal_handled.clear(); 182 } 183 184 protected: 185 std::vector<ResumeAction> m_actions; 186 mutable std::vector<bool> m_signal_handled; 187 }; 188 189 struct ThreadStopInfo 190 { 191 lldb::StopReason reason; 192 union 193 { 194 // eStopTypeSignal 195 struct 196 { 197 uint32_t signo; 198 } signal; 199 200 // eStopTypeException 201 struct 202 { 203 uint64_t type; 204 uint32_t data_count; 205 lldb::addr_t data[2]; 206 } exception; 207 } details; 208 }; 209 210 //------------------------------------------------------------------ 211 // NativeThreadProtocol 212 //------------------------------------------------------------------ 213 class NativeThreadProtocol { 214 215 public: 216 NativeThreadProtocol (NativeProcessProtocol *process, lldb::tid_t tid) : 217 m_process (process), 218 m_tid (tid) 219 { 220 } 221 222 virtual ~NativeThreadProtocol() 223 { 224 } 225 virtual const char *GetName() = 0; 226 virtual lldb::StateType GetState () = 0; 227 virtual Error ReadRegister (uint32_t reg, RegisterValue ®_value) = 0; 228 virtual Error WriteRegister (uint32_t reg, const RegisterValue ®_value) = 0; 229 virtual Error SaveAllRegisters (lldb::DataBufferSP &data_sp) = 0; 230 virtual Error RestoreAllRegisters (lldb::DataBufferSP &data_sp) = 0; 231 virtual bool GetStopReason (ThreadStopInfo &stop_info) = 0; 232 233 lldb::tid_t 234 GetID() const 235 { 236 return m_tid; 237 } 238 protected: 239 NativeProcessProtocol *m_process; 240 lldb::tid_t m_tid; 241 }; 242 243 244 //------------------------------------------------------------------ 245 // NativeProcessProtocol 246 //------------------------------------------------------------------ 247 class NativeProcessProtocol { 248 public: 249 250 static NativeProcessProtocol * 251 CreateInstance (lldb::pid_t pid); 252 253 // lldb_private::Host calls should be used to launch a process for debugging, and 254 // then the process should be attached to. When attaching to a process 255 // lldb_private::Host calls should be used to locate the process to attach to, 256 // and then this function should be called. 257 NativeProcessProtocol (lldb::pid_t pid) : 258 m_pid (pid), 259 m_threads(), 260 m_threads_mutex (Mutex::eMutexTypeRecursive), 261 m_state (lldb::eStateInvalid), 262 m_exit_status(0), 263 m_exit_description() 264 { 265 } 266 267 public: 268 virtual ~NativeProcessProtocol () 269 { 270 } 271 272 virtual Error Resume (const ResumeActionList &resume_actions) = 0; 273 virtual Error Halt () = 0; 274 virtual Error Detach () = 0; 275 virtual Error Signal (int signo) = 0; 276 virtual Error Kill () = 0; 277 278 virtual Error ReadMemory (lldb::addr_t addr, void *buf, lldb::addr_t size, lldb::addr_t &bytes_read) = 0; 279 virtual Error WriteMemory (lldb::addr_t addr, const void *buf, lldb::addr_t size, lldb::addr_t &bytes_written) = 0; 280 virtual Error AllocateMemory (lldb::addr_t size, uint32_t permissions, lldb::addr_t &addr) = 0; 281 virtual Error DeallocateMemory (lldb::addr_t addr) = 0; 282 283 virtual lldb::addr_t GetSharedLibraryInfoAddress () = 0; 284 285 virtual bool IsAlive () = 0; 286 virtual size_t UpdateThreads () = 0; 287 virtual bool GetArchitecture (ArchSpec &arch) = 0; 288 289 //---------------------------------------------------------------------- 290 // Breakpoint functions 291 //---------------------------------------------------------------------- 292 virtual Error SetBreakpoint (lldb::addr_t addr, size_t size, bool hardware) = 0; 293 virtual Error RemoveBreakpoint (lldb::addr_t addr, size_t size) = 0; 294 295 //---------------------------------------------------------------------- 296 // Watchpoint functions 297 //---------------------------------------------------------------------- 298 virtual uint32_t GetMaxWatchpoints () = 0; 299 virtual Error SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) = 0; 300 virtual Error RemoveWatchpoint (lldb::addr_t addr) = 0; 301 302 303 //---------------------------------------------------------------------- 304 // Accessors 305 //---------------------------------------------------------------------- 306 lldb::pid_t 307 GetID() const 308 { 309 return m_pid; 310 } 311 312 lldb::StateType 313 GetState () const 314 { 315 return m_state; 316 } 317 318 bool 319 IsRunning () const 320 { 321 return m_state == lldb::eStateRunning || IsStepping(); 322 } 323 324 bool 325 IsStepping () const 326 { 327 return m_state == lldb::eStateStepping; 328 } 329 330 bool 331 CanResume () const 332 { 333 return m_state == lldb::eStateStopped; 334 } 335 336 337 void 338 SetState (lldb::StateType state) 339 { 340 m_state = state; 341 } 342 343 //---------------------------------------------------------------------- 344 // Exit Status 345 //---------------------------------------------------------------------- 346 virtual bool 347 GetExitStatus (int *status) 348 { 349 if (m_state == lldb::eStateExited) 350 { 351 *status = m_exit_status; 352 return true; 353 } 354 *status = 0; 355 return false; 356 } 357 virtual bool 358 SetExitStatus (int status, const char *exit_description) 359 { 360 // Exit status already set 361 if (m_state == lldb::eStateExited) 362 return false; 363 m_state = lldb::eStateExited; 364 m_exit_status = status; 365 if (exit_description && exit_description[0]) 366 m_exit_description = exit_description; 367 else 368 m_exit_description.clear(); 369 return true; 370 } 371 372 //---------------------------------------------------------------------- 373 // Access to threads 374 //---------------------------------------------------------------------- 375 lldb::NativeThreadProtocolSP 376 GetThreadAtIndex (uint32_t idx) 377 { 378 Mutex::Locker locker(m_threads_mutex); 379 if (idx < m_threads.size()) 380 return m_threads[idx]; 381 return lldb::NativeThreadProtocolSP(); 382 } 383 384 lldb::NativeThreadProtocolSP 385 GetThreadByID (lldb::tid_t tid) 386 { 387 Mutex::Locker locker(m_threads_mutex); 388 for (auto thread_sp : m_threads) 389 { 390 if (thread_sp->GetID() == tid) 391 return thread_sp; 392 } 393 return lldb::NativeThreadProtocolSP(); 394 } 395 396 protected: 397 lldb::pid_t m_pid; 398 std::vector<lldb::NativeThreadProtocolSP> m_threads; 399 mutable Mutex m_threads_mutex; 400 lldb::StateType m_state; 401 int m_exit_status; 402 std::string m_exit_description; 403 }; 404 405} 406#endif // #ifndef liblldb_Debug_h_ 407