1258882Semaste//===-- Debug.h -------------------------------------------------*- C++ -*-===// 2258882Semaste// 3258882Semaste// The LLVM Compiler Infrastructure 4258882Semaste// 5258882Semaste// This file is distributed under the University of Illinois Open Source 6258882Semaste// License. See LICENSE.TXT for details. 7258882Semaste// 8258882Semaste//===----------------------------------------------------------------------===// 9258882Semaste 10258882Semaste#ifndef liblldb_Debug_h_ 11258882Semaste#define liblldb_Debug_h_ 12258882Semaste 13258882Semaste#include "lldb/lldb-private.h" 14258882Semaste#include "lldb/Core/Error.h" 15258882Semaste#include "lldb/Core/StreamString.h" 16258882Semaste#include "lldb/Host/Mutex.h" 17258882Semaste#include <vector> 18258882Semaste 19258882Semastenamespace lldb_private { 20258882Semaste 21258882Semaste //------------------------------------------------------------------ 22258882Semaste // Tells a thread what it needs to do when the process is resumed. 23258882Semaste //------------------------------------------------------------------ 24258882Semaste struct ResumeAction 25258882Semaste { 26258882Semaste lldb::tid_t tid; // The thread ID that this action applies to, LLDB_INVALID_THREAD_ID for the default thread action 27258882Semaste lldb::StateType state; // Valid values are eStateStopped/eStateSuspended, eStateRunning, and eStateStepping. 28258882Semaste int signal; // When resuming this thread, resume it with this signal if this value is > 0 29258882Semaste }; 30258882Semaste 31258882Semaste //------------------------------------------------------------------ 32258882Semaste // A class that contains instructions for all threads for 33258882Semaste // NativeProcessProtocol::Resume(). Each thread can either run, stay 34258882Semaste // suspended, or step when the process is resumed. We optionally 35258882Semaste // have the ability to also send a signal to the thread when the 36258882Semaste // action is run or step. 37258882Semaste //------------------------------------------------------------------ 38258882Semaste class ResumeActionList 39258882Semaste { 40258882Semaste public: 41258882Semaste ResumeActionList () : 42258882Semaste m_actions (), 43258882Semaste m_signal_handled () 44258882Semaste { 45258882Semaste } 46258882Semaste 47258882Semaste ResumeActionList (lldb::StateType default_action, int signal) : 48258882Semaste m_actions(), 49258882Semaste m_signal_handled () 50258882Semaste { 51258882Semaste SetDefaultThreadActionIfNeeded (default_action, signal); 52258882Semaste } 53258882Semaste 54258882Semaste 55258882Semaste ResumeActionList (const ResumeAction *actions, size_t num_actions) : 56258882Semaste m_actions (), 57258882Semaste m_signal_handled () 58258882Semaste { 59258882Semaste if (actions && num_actions) 60258882Semaste { 61258882Semaste m_actions.assign (actions, actions + num_actions); 62258882Semaste m_signal_handled.assign (num_actions, false); 63258882Semaste } 64258882Semaste } 65258882Semaste 66258882Semaste ~ResumeActionList() 67258882Semaste { 68258882Semaste } 69258882Semaste 70258882Semaste bool 71258882Semaste IsEmpty() const 72258882Semaste { 73258882Semaste return m_actions.empty(); 74258882Semaste } 75258882Semaste 76258882Semaste void 77258882Semaste Append (const ResumeAction &action) 78258882Semaste { 79258882Semaste m_actions.push_back (action); 80258882Semaste m_signal_handled.push_back (false); 81258882Semaste } 82258882Semaste 83258882Semaste void 84258882Semaste AppendAction (lldb::tid_t tid, 85258882Semaste lldb::StateType state, 86258882Semaste int signal = 0) 87258882Semaste { 88258882Semaste ResumeAction action = { tid, state, signal }; 89258882Semaste Append (action); 90258882Semaste } 91258882Semaste 92258882Semaste void 93258882Semaste AppendResumeAll () 94258882Semaste { 95258882Semaste AppendAction (LLDB_INVALID_THREAD_ID, lldb::eStateRunning); 96258882Semaste } 97258882Semaste 98258882Semaste void 99258882Semaste AppendSuspendAll () 100258882Semaste { 101258882Semaste AppendAction (LLDB_INVALID_THREAD_ID, lldb::eStateStopped); 102258882Semaste } 103258882Semaste 104258882Semaste void 105258882Semaste AppendStepAll () 106258882Semaste { 107258882Semaste AppendAction (LLDB_INVALID_THREAD_ID, lldb::eStateStepping); 108258882Semaste } 109258882Semaste 110258882Semaste const ResumeAction * 111258882Semaste GetActionForThread (lldb::tid_t tid, bool default_ok) const 112258882Semaste { 113258882Semaste const size_t num_actions = m_actions.size(); 114258882Semaste for (size_t i=0; i<num_actions; ++i) 115258882Semaste { 116258882Semaste if (m_actions[i].tid == tid) 117258882Semaste return &m_actions[i]; 118258882Semaste } 119258882Semaste if (default_ok && tid != LLDB_INVALID_THREAD_ID) 120258882Semaste return GetActionForThread (LLDB_INVALID_THREAD_ID, false); 121258882Semaste return NULL; 122258882Semaste } 123258882Semaste 124258882Semaste size_t 125258882Semaste NumActionsWithState (lldb::StateType state) const 126258882Semaste { 127258882Semaste size_t count = 0; 128258882Semaste const size_t num_actions = m_actions.size(); 129258882Semaste for (size_t i=0; i<num_actions; ++i) 130258882Semaste { 131258882Semaste if (m_actions[i].state == state) 132258882Semaste ++count; 133258882Semaste } 134258882Semaste return count; 135258882Semaste } 136258882Semaste 137258882Semaste bool 138258882Semaste SetDefaultThreadActionIfNeeded (lldb::StateType action, int signal) 139258882Semaste { 140258882Semaste if (GetActionForThread (LLDB_INVALID_THREAD_ID, true) == NULL) 141258882Semaste { 142258882Semaste // There isn't a default action so we do need to set it. 143258882Semaste ResumeAction default_action = {LLDB_INVALID_THREAD_ID, action, signal }; 144258882Semaste m_actions.push_back (default_action); 145258882Semaste m_signal_handled.push_back (false); 146258882Semaste return true; // Return true as we did add the default action 147258882Semaste } 148258882Semaste return false; 149258882Semaste } 150258882Semaste 151258882Semaste void 152258882Semaste SetSignalHandledForThread (lldb::tid_t tid) const 153258882Semaste { 154258882Semaste if (tid != LLDB_INVALID_THREAD_ID) 155258882Semaste { 156258882Semaste const size_t num_actions = m_actions.size(); 157258882Semaste for (size_t i=0; i<num_actions; ++i) 158258882Semaste { 159258882Semaste if (m_actions[i].tid == tid) 160258882Semaste m_signal_handled[i] = true; 161258882Semaste } 162258882Semaste } 163258882Semaste } 164258882Semaste 165258882Semaste const ResumeAction * 166258882Semaste GetFirst() const 167258882Semaste { 168258882Semaste return m_actions.data(); 169258882Semaste } 170258882Semaste 171258882Semaste size_t 172258882Semaste GetSize () const 173258882Semaste { 174258882Semaste return m_actions.size(); 175258882Semaste } 176258882Semaste 177258882Semaste void 178258882Semaste Clear() 179258882Semaste { 180258882Semaste m_actions.clear(); 181258882Semaste m_signal_handled.clear(); 182258882Semaste } 183258882Semaste 184258882Semaste protected: 185258882Semaste std::vector<ResumeAction> m_actions; 186258882Semaste mutable std::vector<bool> m_signal_handled; 187258882Semaste }; 188258882Semaste 189258882Semaste struct ThreadStopInfo 190258882Semaste { 191258882Semaste lldb::StopReason reason; 192258882Semaste union 193258882Semaste { 194258882Semaste // eStopTypeSignal 195258882Semaste struct 196258882Semaste { 197258882Semaste uint32_t signo; 198258882Semaste } signal; 199258882Semaste 200258882Semaste // eStopTypeException 201258882Semaste struct 202258882Semaste { 203258882Semaste uint64_t type; 204258882Semaste uint32_t data_count; 205258882Semaste lldb::addr_t data[2]; 206258882Semaste } exception; 207258882Semaste } details; 208258882Semaste }; 209258882Semaste 210258882Semaste //------------------------------------------------------------------ 211258882Semaste // NativeThreadProtocol 212258882Semaste //------------------------------------------------------------------ 213258882Semaste class NativeThreadProtocol { 214258882Semaste 215258882Semaste public: 216258882Semaste NativeThreadProtocol (NativeProcessProtocol *process, lldb::tid_t tid) : 217258882Semaste m_process (process), 218258882Semaste m_tid (tid) 219258882Semaste { 220258882Semaste } 221258882Semaste 222258882Semaste virtual ~NativeThreadProtocol() 223258882Semaste { 224258882Semaste } 225258882Semaste virtual const char *GetName() = 0; 226258882Semaste virtual lldb::StateType GetState () = 0; 227258882Semaste virtual Error ReadRegister (uint32_t reg, RegisterValue ®_value) = 0; 228258882Semaste virtual Error WriteRegister (uint32_t reg, const RegisterValue ®_value) = 0; 229258882Semaste virtual Error SaveAllRegisters (lldb::DataBufferSP &data_sp) = 0; 230258882Semaste virtual Error RestoreAllRegisters (lldb::DataBufferSP &data_sp) = 0; 231258882Semaste virtual bool GetStopReason (ThreadStopInfo &stop_info) = 0; 232258882Semaste 233258882Semaste lldb::tid_t 234258882Semaste GetID() const 235258882Semaste { 236258882Semaste return m_tid; 237258882Semaste } 238258882Semaste protected: 239258882Semaste NativeProcessProtocol *m_process; 240258882Semaste lldb::tid_t m_tid; 241258882Semaste }; 242258882Semaste 243258882Semaste 244258882Semaste //------------------------------------------------------------------ 245258882Semaste // NativeProcessProtocol 246258882Semaste //------------------------------------------------------------------ 247258882Semaste class NativeProcessProtocol { 248258882Semaste public: 249258882Semaste 250258882Semaste static NativeProcessProtocol * 251258882Semaste CreateInstance (lldb::pid_t pid); 252258882Semaste 253258882Semaste // lldb_private::Host calls should be used to launch a process for debugging, and 254258882Semaste // then the process should be attached to. When attaching to a process 255258882Semaste // lldb_private::Host calls should be used to locate the process to attach to, 256258882Semaste // and then this function should be called. 257258882Semaste NativeProcessProtocol (lldb::pid_t pid) : 258258882Semaste m_pid (pid), 259258882Semaste m_threads(), 260258882Semaste m_threads_mutex (Mutex::eMutexTypeRecursive), 261258882Semaste m_state (lldb::eStateInvalid), 262258882Semaste m_exit_status(0), 263258882Semaste m_exit_description() 264258882Semaste { 265258882Semaste } 266258882Semaste 267258882Semaste public: 268258882Semaste virtual ~NativeProcessProtocol () 269258882Semaste { 270258882Semaste } 271258882Semaste 272258882Semaste virtual Error Resume (const ResumeActionList &resume_actions) = 0; 273258882Semaste virtual Error Halt () = 0; 274258882Semaste virtual Error Detach () = 0; 275258882Semaste virtual Error Signal (int signo) = 0; 276258882Semaste virtual Error Kill () = 0; 277258882Semaste 278258882Semaste virtual Error ReadMemory (lldb::addr_t addr, void *buf, lldb::addr_t size, lldb::addr_t &bytes_read) = 0; 279258882Semaste virtual Error WriteMemory (lldb::addr_t addr, const void *buf, lldb::addr_t size, lldb::addr_t &bytes_written) = 0; 280258882Semaste virtual Error AllocateMemory (lldb::addr_t size, uint32_t permissions, lldb::addr_t &addr) = 0; 281258882Semaste virtual Error DeallocateMemory (lldb::addr_t addr) = 0; 282258882Semaste 283258882Semaste virtual lldb::addr_t GetSharedLibraryInfoAddress () = 0; 284258882Semaste 285258882Semaste virtual bool IsAlive () = 0; 286258882Semaste virtual size_t UpdateThreads () = 0; 287258882Semaste virtual bool GetArchitecture (ArchSpec &arch) = 0; 288258882Semaste 289258882Semaste //---------------------------------------------------------------------- 290258882Semaste // Breakpoint functions 291258882Semaste //---------------------------------------------------------------------- 292258882Semaste virtual Error SetBreakpoint (lldb::addr_t addr, size_t size, bool hardware) = 0; 293258882Semaste virtual Error RemoveBreakpoint (lldb::addr_t addr, size_t size) = 0; 294258882Semaste 295258882Semaste //---------------------------------------------------------------------- 296258882Semaste // Watchpoint functions 297258882Semaste //---------------------------------------------------------------------- 298258882Semaste virtual uint32_t GetMaxWatchpoints () = 0; 299258882Semaste virtual Error SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) = 0; 300258882Semaste virtual Error RemoveWatchpoint (lldb::addr_t addr) = 0; 301258882Semaste 302258882Semaste 303258882Semaste //---------------------------------------------------------------------- 304258882Semaste // Accessors 305258882Semaste //---------------------------------------------------------------------- 306258882Semaste lldb::pid_t 307258882Semaste GetID() const 308258882Semaste { 309258882Semaste return m_pid; 310258882Semaste } 311258882Semaste 312258882Semaste lldb::StateType 313258882Semaste GetState () const 314258882Semaste { 315258882Semaste return m_state; 316258882Semaste } 317258882Semaste 318258882Semaste bool 319258882Semaste IsRunning () const 320258882Semaste { 321258882Semaste return m_state == lldb::eStateRunning || IsStepping(); 322258882Semaste } 323258882Semaste 324258882Semaste bool 325258882Semaste IsStepping () const 326258882Semaste { 327258882Semaste return m_state == lldb::eStateStepping; 328258882Semaste } 329258882Semaste 330258882Semaste bool 331258882Semaste CanResume () const 332258882Semaste { 333258882Semaste return m_state == lldb::eStateStopped; 334258882Semaste } 335258882Semaste 336258882Semaste 337258882Semaste void 338258882Semaste SetState (lldb::StateType state) 339258882Semaste { 340258882Semaste m_state = state; 341258882Semaste } 342258882Semaste 343258882Semaste //---------------------------------------------------------------------- 344258882Semaste // Exit Status 345258882Semaste //---------------------------------------------------------------------- 346258882Semaste virtual bool 347258882Semaste GetExitStatus (int *status) 348258882Semaste { 349258882Semaste if (m_state == lldb::eStateExited) 350258882Semaste { 351258882Semaste *status = m_exit_status; 352258882Semaste return true; 353258882Semaste } 354258882Semaste *status = 0; 355258882Semaste return false; 356258882Semaste } 357258882Semaste virtual bool 358258882Semaste SetExitStatus (int status, const char *exit_description) 359258882Semaste { 360258882Semaste // Exit status already set 361258882Semaste if (m_state == lldb::eStateExited) 362258882Semaste return false; 363258882Semaste m_state = lldb::eStateExited; 364258882Semaste m_exit_status = status; 365258882Semaste if (exit_description && exit_description[0]) 366258882Semaste m_exit_description = exit_description; 367258882Semaste else 368258882Semaste m_exit_description.clear(); 369258882Semaste return true; 370258882Semaste } 371258882Semaste 372258882Semaste //---------------------------------------------------------------------- 373258882Semaste // Access to threads 374258882Semaste //---------------------------------------------------------------------- 375258882Semaste lldb::NativeThreadProtocolSP 376258882Semaste GetThreadAtIndex (uint32_t idx) 377258882Semaste { 378258882Semaste Mutex::Locker locker(m_threads_mutex); 379258882Semaste if (idx < m_threads.size()) 380258882Semaste return m_threads[idx]; 381258882Semaste return lldb::NativeThreadProtocolSP(); 382258882Semaste } 383258882Semaste 384258882Semaste lldb::NativeThreadProtocolSP 385258882Semaste GetThreadByID (lldb::tid_t tid) 386258882Semaste { 387258882Semaste Mutex::Locker locker(m_threads_mutex); 388258882Semaste for (auto thread_sp : m_threads) 389258882Semaste { 390258882Semaste if (thread_sp->GetID() == tid) 391258882Semaste return thread_sp; 392258882Semaste } 393258882Semaste return lldb::NativeThreadProtocolSP(); 394258882Semaste } 395258882Semaste 396258882Semaste protected: 397258882Semaste lldb::pid_t m_pid; 398258882Semaste std::vector<lldb::NativeThreadProtocolSP> m_threads; 399258882Semaste mutable Mutex m_threads_mutex; 400258882Semaste lldb::StateType m_state; 401258882Semaste int m_exit_status; 402258882Semaste std::string m_exit_description; 403258882Semaste }; 404258882Semaste 405258882Semaste} 406258882Semaste#endif // #ifndef liblldb_Debug_h_ 407