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/Core/State.h" 17 #include "lldb/Target/Process.h" 18 #include "lldb/Target/RegisterContext.h" 19 #include "lldb/Target/StopInfo.h" 20 #include "lldb/Target/Target.h" 21 #include "lldb/Target/Unwind.h" 22 #include "lldb/Breakpoint/WatchpointLocation.h" 23 24 #include "ProcessGDBRemote.h" 25 #include "ProcessGDBRemoteLog.h" 26 #include "Plugins/Process/Utility/UnwindLLDB.h" 27 #include "Utility/StringExtractorGDBRemote.h" 28 29 #if defined(__APPLE__) 30 #include "UnwindMacOSXFrameBackchain.h" 31 #endif 32 33 using namespace lldb; 34 using namespace lldb_private; 35 36 //---------------------------------------------------------------------- 37 // Thread Registers 38 //---------------------------------------------------------------------- 39 40 ThreadGDBRemote::ThreadGDBRemote (ProcessGDBRemote &process, lldb::tid_t tid) : 41 Thread(process, tid), 42 m_thread_name (), 43 m_dispatch_queue_name (), 44 m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS) 45 { 46 // ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD | GDBR_LOG_VERBOSE, "ThreadGDBRemote::ThreadGDBRemote ( pid = %i, tid = 0x%4.4x, )", m_process.GetID(), GetID()); 47 ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID()); 48 } 49 50 ThreadGDBRemote::~ThreadGDBRemote () 51 { 52 ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::~ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID()); 53 DestroyThread(); 54 } 55 56 57 const char * 58 ThreadGDBRemote::GetInfo () 59 { 60 return NULL; 61 } 62 63 64 const char * 65 ThreadGDBRemote::GetName () 66 { 67 if (m_thread_name.empty()) 68 return NULL; 69 return m_thread_name.c_str(); 70 } 71 72 73 const char * 74 ThreadGDBRemote::GetQueueName () 75 { 76 // Always re-fetch the dispatch queue name since it can change 77 if (m_thread_dispatch_qaddr != 0 || m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) 78 return GetGDBProcess().GetDispatchQueueNameForThread (m_thread_dispatch_qaddr, m_dispatch_queue_name); 79 return NULL; 80 } 81 82 bool 83 ThreadGDBRemote::WillResume (StateType resume_state) 84 { 85 ClearStackFrames(); 86 // Call the Thread::WillResume first. If we stop at a signal, the stop info 87 // class for signal will set the resume signal that we need below. The signal 88 // stuff obeys the Process::UnixSignal defaults. 89 Thread::WillResume(resume_state); 90 91 int signo = GetResumeSignal(); 92 lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); 93 if (log) 94 log->Printf ("Resuming thread: %4.4x with state: %s.", GetID(), StateAsCString(resume_state)); 95 96 ProcessGDBRemote &process = GetGDBProcess(); 97 switch (resume_state) 98 { 99 case eStateSuspended: 100 case eStateStopped: 101 // Don't append anything for threads that should stay stopped. 102 break; 103 104 case eStateRunning: 105 if (m_process.GetUnixSignals().SignalIsValid (signo)) 106 process.m_continue_C_tids.push_back(std::make_pair(GetID(), signo)); 107 else 108 process.m_continue_c_tids.push_back(GetID()); 109 break; 110 111 case eStateStepping: 112 if (m_process.GetUnixSignals().SignalIsValid (signo)) 113 process.m_continue_S_tids.push_back(std::make_pair(GetID(), signo)); 114 else 115 process.m_continue_s_tids.push_back(GetID()); 116 break; 117 118 default: 119 break; 120 } 121 return true; 122 } 123 124 void 125 ThreadGDBRemote::RefreshStateAfterStop() 126 { 127 // Invalidate all registers in our register context. We don't set "force" to 128 // true because the stop reply packet might have had some register values 129 // that were expedited and these will already be copied into the register 130 // context by the time this function gets called. The GDBRemoteRegisterContext 131 // class has been made smart enough to detect when it needs to invalidate 132 // which registers are valid by putting hooks in the register read and 133 // register supply functions where they check the process stop ID and do 134 // the right thing. 135 const bool force = false; 136 GetRegisterContext()->InvalidateIfNeeded (force); 137 } 138 139 Unwind * 140 ThreadGDBRemote::GetUnwinder () 141 { 142 if (m_unwinder_ap.get() == NULL) 143 { 144 const ArchSpec target_arch (GetProcess().GetTarget().GetArchitecture ()); 145 const llvm::Triple::ArchType machine = target_arch.GetMachine(); 146 if (machine == llvm::Triple::x86_64 || machine == llvm::Triple::x86) 147 { 148 m_unwinder_ap.reset (new UnwindLLDB (*this)); 149 } 150 #if defined(__APPLE__) 151 else 152 { 153 m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this)); 154 } 155 #endif 156 } 157 return m_unwinder_ap.get(); 158 } 159 160 void 161 ThreadGDBRemote::ClearStackFrames () 162 { 163 Unwind *unwinder = GetUnwinder (); 164 if (unwinder) 165 unwinder->Clear(); 166 Thread::ClearStackFrames(); 167 } 168 169 170 bool 171 ThreadGDBRemote::ThreadIDIsValid (lldb::tid_t thread) 172 { 173 return thread != 0; 174 } 175 176 void 177 ThreadGDBRemote::Dump(Log *log, uint32_t index) 178 { 179 } 180 181 182 bool 183 ThreadGDBRemote::ShouldStop (bool &step_more) 184 { 185 return true; 186 } 187 lldb::RegisterContextSP 188 ThreadGDBRemote::GetRegisterContext () 189 { 190 if (m_reg_context_sp.get() == NULL) 191 m_reg_context_sp = CreateRegisterContextForFrame (NULL); 192 return m_reg_context_sp; 193 } 194 195 lldb::RegisterContextSP 196 ThreadGDBRemote::CreateRegisterContextForFrame (StackFrame *frame) 197 { 198 lldb::RegisterContextSP reg_ctx_sp; 199 const bool read_all_registers_at_once = false; 200 uint32_t concrete_frame_idx = 0; 201 202 if (frame) 203 concrete_frame_idx = frame->GetConcreteFrameIndex (); 204 205 if (concrete_frame_idx == 0) 206 reg_ctx_sp.reset (new GDBRemoteRegisterContext (*this, concrete_frame_idx, GetGDBProcess().m_register_info, read_all_registers_at_once)); 207 else if (m_unwinder_ap.get()) 208 reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame); 209 return reg_ctx_sp; 210 } 211 212 bool 213 ThreadGDBRemote::PrivateSetRegisterValue (uint32_t reg, StringExtractor &response) 214 { 215 GDBRemoteRegisterContext *gdb_reg_ctx = static_cast<GDBRemoteRegisterContext *>(GetRegisterContext ().get()); 216 assert (gdb_reg_ctx); 217 return gdb_reg_ctx->PrivateSetRegisterValue (reg, response); 218 } 219 220 bool 221 ThreadGDBRemote::SaveFrameZeroState (RegisterCheckpoint &checkpoint) 222 { 223 lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0)); 224 if (frame_sp) 225 { 226 checkpoint.SetStackID(frame_sp->GetStackID()); 227 return frame_sp->GetRegisterContext()->ReadAllRegisterValues (checkpoint.GetData()); 228 } 229 return false; 230 } 231 232 bool 233 ThreadGDBRemote::RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint) 234 { 235 lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0)); 236 if (frame_sp) 237 { 238 bool ret = frame_sp->GetRegisterContext()->WriteAllRegisterValues (checkpoint.GetData()); 239 frame_sp->GetRegisterContext()->InvalidateIfNeeded(true); 240 ClearStackFrames(); 241 return ret; 242 } 243 return false; 244 } 245 246 lldb::StopInfoSP 247 ThreadGDBRemote::GetPrivateStopReason () 248 { 249 const uint32_t process_stop_id = GetProcess().GetStopID(); 250 if (m_thread_stop_reason_stop_id != process_stop_id || 251 (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid())) 252 { 253 // If GetGDBProcess().SetThreadStopInfo() doesn't find a stop reason 254 // for this thread, then m_actual_stop_info_sp will not ever contain 255 // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false" 256 // check will never be able to tell us if we have the correct stop info 257 // for this thread and we will continually send qThreadStopInfo packets 258 // down to the remote GDB server, so we need to keep our own notion 259 // of the stop ID that m_actual_stop_info_sp is valid for (even if it 260 // contains nothing). We use m_thread_stop_reason_stop_id for this below. 261 m_thread_stop_reason_stop_id = process_stop_id; 262 m_actual_stop_info_sp.reset(); 263 264 StringExtractorGDBRemote stop_packet; 265 ProcessGDBRemote &gdb_process = GetGDBProcess(); 266 if (gdb_process.GetGDBRemote().GetThreadStopInfo(GetID(), stop_packet)) 267 gdb_process.SetThreadStopInfo (stop_packet); 268 } 269 return m_actual_stop_info_sp; 270 } 271 272 273