LinuxThread.cpp revision 3bf3a9df7a920591092ef13c735cb65854a29a35
1//===-- LinuxThread.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// C Includes 11#include <errno.h> 12 13// C++ Includes 14// Other libraries and framework includes 15// Project includes 16#include "lldb/Core/Debugger.h" 17#include "lldb/Host/Host.h" 18#include "lldb/Target/Process.h" 19#include "lldb/Target/StopInfo.h" 20#include "lldb/Target/Target.h" 21#include "LinuxStopInfo.h" 22#include "LinuxThread.h" 23#include "ProcessLinux.h" 24#include "ProcessLinuxLog.h" 25#include "ProcessMonitor.h" 26#include "RegisterContextLinux_i386.h" 27#include "RegisterContextLinux_x86_64.h" 28#include "UnwindLLDB.h" 29 30using namespace lldb_private; 31 32 33LinuxThread::LinuxThread(Process &process, lldb::tid_t tid) 34 : Thread(process, tid), 35 m_frame_ap(0) 36{ 37 LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD)); 38 if (log && log->GetMask().Test(LINUX_LOG_VERBOSE)) 39 log->Printf ("LinuxThread::%s (tid = %i)", __FUNCTION__, tid); 40} 41 42LinuxThread::~LinuxThread() 43{ 44 DestroyThread(); 45} 46 47ProcessMonitor & 48LinuxThread::GetMonitor() 49{ 50 ProcessLinux &process = static_cast<ProcessLinux&>(GetProcess()); 51 return process.GetMonitor(); 52} 53 54void 55LinuxThread::RefreshStateAfterStop() 56{ 57 LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD)); 58 if (log && log->GetMask().Test(LINUX_LOG_VERBOSE)) 59 log->Printf ("LinuxThread::%s ()", __FUNCTION__); 60 61 // Let all threads recover from stopping and do any clean up based 62 // on the previous thread state (if any). 63 ProcessLinux &process = static_cast<ProcessLinux&>(GetProcess()); 64 process.GetThreadList().RefreshStateAfterStop(); 65} 66 67const char * 68LinuxThread::GetInfo() 69{ 70 return NULL; 71} 72 73lldb::RegisterContextSP 74LinuxThread::GetRegisterContext() 75{ 76 if (!m_reg_context_sp) 77 { 78 ArchSpec arch = Host::GetArchitecture(); 79 80 switch (arch.GetCore()) 81 { 82 default: 83 assert(false && "CPU type not supported!"); 84 break; 85 86 case ArchSpec::eCore_x86_32_i386: 87 case ArchSpec::eCore_x86_32_i486: 88 case ArchSpec::eCore_x86_32_i486sx: 89 m_reg_context_sp.reset(new RegisterContextLinux_i386(*this, 0)); 90 break; 91 92 case ArchSpec::eCore_x86_64_x86_64: 93 m_reg_context_sp.reset(new RegisterContextLinux_x86_64(*this, 0)); 94 break; 95 } 96 } 97 return m_reg_context_sp; 98} 99 100lldb::RegisterContextSP 101LinuxThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame) 102{ 103 lldb::RegisterContextSP reg_ctx_sp; 104 uint32_t concrete_frame_idx = 0; 105 106 LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD)); 107 if (log && log->GetMask().Test(LINUX_LOG_VERBOSE)) 108 log->Printf ("LinuxThread::%s ()", __FUNCTION__); 109 110 if (frame) 111 concrete_frame_idx = frame->GetConcreteFrameIndex(); 112 113 if (concrete_frame_idx == 0) 114 reg_ctx_sp = GetRegisterContext(); 115 else 116 { 117 assert(GetUnwinder()); 118 reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame); 119 } 120 121 return reg_ctx_sp; 122} 123 124lldb::StopInfoSP 125LinuxThread::GetPrivateStopReason() 126{ 127 return m_stop_info; 128} 129 130Unwind * 131LinuxThread::GetUnwinder() 132{ 133 if (m_unwinder_ap.get() == NULL) 134 m_unwinder_ap.reset(new UnwindLLDB(*this)); 135 136 return m_unwinder_ap.get(); 137} 138 139bool 140LinuxThread::WillResume(lldb::StateType resume_state) 141{ 142 SetResumeState(resume_state); 143 144 ClearStackFrames(); 145 if (m_unwinder_ap.get()) 146 m_unwinder_ap->Clear(); 147 148 return Thread::WillResume(resume_state); 149} 150 151bool 152LinuxThread::Resume() 153{ 154 lldb::StateType resume_state = GetResumeState(); 155 ProcessMonitor &monitor = GetMonitor(); 156 bool status; 157 158 LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD)); 159 if (log && log->GetMask().Test(LINUX_LOG_VERBOSE)) 160 log->Printf ("LinuxThread::%s ()", __FUNCTION__); 161 162 switch (resume_state) 163 { 164 default: 165 assert(false && "Unexpected state for resume!"); 166 status = false; 167 break; 168 169 case lldb::eStateRunning: 170 SetState(resume_state); 171 status = monitor.Resume(GetID(), GetResumeSignal()); 172 break; 173 174 case lldb::eStateStepping: 175 SetState(resume_state); 176 status = monitor.SingleStep(GetID(), GetResumeSignal()); 177 break; 178 } 179 180 return status; 181} 182 183void 184LinuxThread::Notify(const ProcessMessage &message) 185{ 186 LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD)); 187 if (log) 188 log->Printf ("LinuxThread::%s () message kind = '%s'", __FUNCTION__, message.PrintKind()); 189 190 switch (message.GetKind()) 191 { 192 default: 193 assert(false && "Unexpected message kind!"); 194 break; 195 196 case ProcessMessage::eLimboMessage: 197 LimboNotify(message); 198 break; 199 200 case ProcessMessage::eSignalMessage: 201 SignalNotify(message); 202 break; 203 204 case ProcessMessage::eSignalDeliveredMessage: 205 SignalDeliveredNotify(message); 206 break; 207 208 case ProcessMessage::eTraceMessage: 209 TraceNotify(message); 210 break; 211 212 case ProcessMessage::eBreakpointMessage: 213 BreakNotify(message); 214 break; 215 216 case ProcessMessage::eCrashMessage: 217 CrashNotify(message); 218 break; 219 } 220} 221 222void 223LinuxThread::BreakNotify(const ProcessMessage &message) 224{ 225 bool status; 226 LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD)); 227 228 assert(GetRegisterContextLinux()); 229 status = GetRegisterContextLinux()->UpdateAfterBreakpoint(); 230 assert(status && "Breakpoint update failed!"); 231 232 // With our register state restored, resolve the breakpoint object 233 // corresponding to our current PC. 234 assert(GetRegisterContext()); 235 lldb::addr_t pc = GetRegisterContext()->GetPC(); 236 if (log) 237 log->Printf ("LinuxThread::%s () PC=0x%8.8llx", __FUNCTION__, pc); 238 lldb::BreakpointSiteSP bp_site(GetProcess().GetBreakpointSiteList().FindByAddress(pc)); 239 assert(bp_site); 240 lldb::break_id_t bp_id = bp_site->GetID(); 241 assert(bp_site && bp_site->ValidForThisThread(this)); 242 243 244 m_breakpoint = bp_site; 245 m_stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id); 246} 247 248void 249LinuxThread::TraceNotify(const ProcessMessage &message) 250{ 251 m_stop_info = StopInfo::CreateStopReasonToTrace(*this); 252} 253 254void 255LinuxThread::LimboNotify(const ProcessMessage &message) 256{ 257 m_stop_info = lldb::StopInfoSP(new LinuxLimboStopInfo(*this)); 258} 259 260void 261LinuxThread::SignalNotify(const ProcessMessage &message) 262{ 263 int signo = message.GetSignal(); 264 265 m_stop_info = StopInfo::CreateStopReasonWithSignal(*this, signo); 266 SetResumeSignal(signo); 267} 268 269void 270LinuxThread::SignalDeliveredNotify(const ProcessMessage &message) 271{ 272 int signo = message.GetSignal(); 273 274 // Just treat debugger generated signal events like breakpoints for now. 275 m_stop_info = StopInfo::CreateStopReasonToTrace(*this); 276 SetResumeSignal(signo); 277} 278 279void 280LinuxThread::CrashNotify(const ProcessMessage &message) 281{ 282 int signo = message.GetSignal(); 283 284 assert(message.GetKind() == ProcessMessage::eCrashMessage); 285 286 LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD)); 287 if (log) 288 log->Printf ("LinuxThread::%s () signo = %i, reason = '%s'", __FUNCTION__, signo, message.PrintCrashReason()); 289 290 m_stop_info = lldb::StopInfoSP(new LinuxCrashStopInfo( 291 *this, signo, message.GetCrashReason())); 292 SetResumeSignal(signo); 293} 294 295unsigned 296LinuxThread::GetRegisterIndexFromOffset(unsigned offset) 297{ 298 unsigned reg; 299 ArchSpec arch = Host::GetArchitecture(); 300 301 switch (arch.GetCore()) 302 { 303 default: 304 assert(false && "CPU type not supported!"); 305 break; 306 307 case ArchSpec::eCore_x86_32_i386: 308 case ArchSpec::eCore_x86_32_i486: 309 case ArchSpec::eCore_x86_32_i486sx: 310 reg = RegisterContextLinux_i386::GetRegisterIndexFromOffset(offset); 311 break; 312 313 case ArchSpec::eCore_x86_64_x86_64: 314 reg = RegisterContextLinux_x86_64::GetRegisterIndexFromOffset(offset); 315 break; 316 } 317 return reg; 318} 319 320const char * 321LinuxThread::GetRegisterName(unsigned reg) 322{ 323 const char * name; 324 ArchSpec arch = Host::GetArchitecture(); 325 326 switch (arch.GetCore()) 327 { 328 default: 329 assert(false && "CPU type not supported!"); 330 break; 331 332 case ArchSpec::eCore_x86_32_i386: 333 case ArchSpec::eCore_x86_32_i486: 334 case ArchSpec::eCore_x86_32_i486sx: 335 name = RegisterContextLinux_i386::GetRegisterName(reg); 336 break; 337 338 case ArchSpec::eCore_x86_64_x86_64: 339 name = RegisterContextLinux_x86_64::GetRegisterName(reg); 340 break; 341 } 342 return name; 343} 344 345const char * 346LinuxThread::GetRegisterNameFromOffset(unsigned offset) 347{ 348 return GetRegisterName(GetRegisterIndexFromOffset(offset)); 349} 350 351