1 //===-- ThreadGDBRemote.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 11 #include "ThreadGDBRemote.h" 12 13 #include "lldb/Core/ArchSpec.h" 14 #include "lldb/Core/DataExtractor.h" 15 #include "lldb/Core/StreamString.h" 16 #include "lldb/Target/Process.h" 17 #include "lldb/Target/RegisterContext.h" 18 #include "lldb/Target/StopInfo.h" 19 #include "lldb/Target/Target.h" 20 #include "lldb/Target/Unwind.h" 21 #include "lldb/Breakpoint/WatchpointLocation.h" 22 23 #include "LibUnwindRegisterContext.h" 24 #include "ProcessGDBRemote.h" 25 #include "ProcessGDBRemoteLog.h" 26 #include "Utility/StringExtractorGDBRemote.h" 27 #include "UnwindLibUnwind.h" 28 #include "UnwindMacOSXFrameBackchain.h" 29 30 using namespace lldb; 31 using namespace lldb_private; 32 33 //---------------------------------------------------------------------- 34 // Thread Registers 35 //---------------------------------------------------------------------- 36 37 ThreadGDBRemote::ThreadGDBRemote (ProcessGDBRemote &process, lldb::tid_t tid) : 38 Thread(process, tid), 39 m_thread_name (), 40 m_dispatch_queue_name (), 41 m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS) 42 { 43 // ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD | GDBR_LOG_VERBOSE, "ThreadGDBRemote::ThreadGDBRemote ( pid = %i, tid = 0x%4.4x, )", m_process.GetID(), GetID()); 44 ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID()); 45 } 46 47 ThreadGDBRemote::~ThreadGDBRemote () 48 { 49 ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::~ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID()); 50 } 51 52 53 const char * 54 ThreadGDBRemote::GetInfo () 55 { 56 return NULL; 57 } 58 59 60 const char * 61 ThreadGDBRemote::GetName () 62 { 63 if (m_thread_name.empty()) 64 return NULL; 65 return m_thread_name.c_str(); 66 } 67 68 69 const char * 70 ThreadGDBRemote::GetQueueName () 71 { 72 // Always re-fetch the dispatch queue name since it can change 73 if (m_thread_dispatch_qaddr != 0 || m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) 74 return GetGDBProcess().GetDispatchQueueNameForThread (m_thread_dispatch_qaddr, m_dispatch_queue_name); 75 return NULL; 76 } 77 78 bool 79 ThreadGDBRemote::WillResume (StateType resume_state) 80 { 81 ClearStackFrames(); 82 // Call the Thread::WillResume first. If we stop at a signal, the stop info 83 // class for signal will set the resume signal that we need below. The signal 84 // stuff obeys the Process::UnixSignal defaults. 85 Thread::WillResume(resume_state); 86 87 int signo = GetResumeSignal(); 88 89 switch (resume_state) 90 { 91 case eStateSuspended: 92 case eStateStopped: 93 // Don't append anything for threads that should stay stopped. 94 break; 95 96 case eStateRunning: 97 if (m_process.GetUnixSignals().SignalIsValid (signo)) 98 GetGDBProcess().m_continue_packet.Printf(";C%2.2x:%4.4x", signo, GetID()); 99 else 100 GetGDBProcess().m_continue_packet.Printf(";c:%4.4x", GetID()); 101 break; 102 103 case eStateStepping: 104 if (m_process.GetUnixSignals().SignalIsValid (signo)) 105 GetGDBProcess().m_continue_packet.Printf(";S%2.2x:%4.4x", signo, GetID()); 106 else 107 GetGDBProcess().m_continue_packet.Printf(";s:%4.4x", GetID()); 108 break; 109 110 default: 111 break; 112 } 113 return true; 114 } 115 116 void 117 ThreadGDBRemote::RefreshStateAfterStop() 118 { 119 // Invalidate all registers in our register context 120 GetRegisterContext()->Invalidate(); 121 } 122 123 Unwind * 124 ThreadGDBRemote::GetUnwinder () 125 { 126 if (m_unwinder_ap.get() == NULL) 127 { 128 const ArchSpec target_arch (GetProcess().GetTarget().GetArchitecture ()); 129 if (target_arch == ArchSpec("x86_64") || target_arch == ArchSpec("i386")) 130 { 131 m_unwinder_ap.reset (new UnwindLibUnwind (*this, GetGDBProcess().GetLibUnwindAddressSpace())); 132 } 133 else 134 { 135 m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this)); 136 } 137 } 138 return m_unwinder_ap.get(); 139 } 140 141 void 142 ThreadGDBRemote::ClearStackFrames () 143 { 144 Unwind *unwinder = GetUnwinder (); 145 if (unwinder) 146 unwinder->Clear(); 147 Thread::ClearStackFrames(); 148 } 149 150 151 bool 152 ThreadGDBRemote::ThreadIDIsValid (lldb::tid_t thread) 153 { 154 return thread != 0; 155 } 156 157 void 158 ThreadGDBRemote::Dump(Log *log, uint32_t index) 159 { 160 } 161 162 163 bool 164 ThreadGDBRemote::ShouldStop (bool &step_more) 165 { 166 return true; 167 } 168 RegisterContext * 169 ThreadGDBRemote::GetRegisterContext () 170 { 171 if (m_reg_context_sp.get() == NULL) 172 m_reg_context_sp.reset (CreateRegisterContextForFrame (NULL)); 173 return m_reg_context_sp.get(); 174 } 175 176 RegisterContext * 177 ThreadGDBRemote::CreateRegisterContextForFrame (StackFrame *frame) 178 { 179 const bool read_all_registers_at_once = false; 180 uint32_t frame_idx = 0; 181 182 if (frame) 183 frame_idx = frame->GetFrameIndex (); 184 185 if (frame_idx == 0) 186 return new GDBRemoteRegisterContext (*this, frame, GetGDBProcess().m_register_info, read_all_registers_at_once); 187 else if (m_unwinder_ap.get()) 188 return m_unwinder_ap->CreateRegisterContextForFrame (frame); 189 return NULL; 190 } 191 192 bool 193 ThreadGDBRemote::SaveFrameZeroState (RegisterCheckpoint &checkpoint) 194 { 195 lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0)); 196 if (frame_sp) 197 { 198 checkpoint.SetStackID(frame_sp->GetStackID()); 199 return frame_sp->GetRegisterContext()->ReadAllRegisterValues (checkpoint.GetData()); 200 } 201 return false; 202 } 203 204 bool 205 ThreadGDBRemote::RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint) 206 { 207 lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0)); 208 if (frame_sp) 209 { 210 bool ret = frame_sp->GetRegisterContext()->WriteAllRegisterValues (checkpoint.GetData()); 211 frame_sp->GetRegisterContext()->Invalidate(); 212 ClearStackFrames(); 213 return ret; 214 } 215 return false; 216 } 217 218 lldb::StopInfoSP 219 ThreadGDBRemote::GetPrivateStopReason () 220 { 221 if (m_actual_stop_info_sp.get() == NULL || m_actual_stop_info_sp->IsValid() == false) 222 { 223 m_actual_stop_info_sp.reset(); 224 225 char packet[256]; 226 ::snprintf(packet, sizeof(packet), "qThreadStopInfo%x", GetID()); 227 StringExtractorGDBRemote stop_packet; 228 if (GetGDBProcess().GetGDBRemote().SendPacketAndWaitForResponse(packet, stop_packet, 1, false)) 229 { 230 std::string copy(stop_packet.GetStringRef()); 231 GetGDBProcess().SetThreadStopInfo (stop_packet); 232 } 233 } 234 return m_actual_stop_info_sp; 235 } 236 237 238