POSIXThread.cpp revision 010a8d85100602eff09bd61a85987efd0001188a
1//===-- POSIXThread.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#include "lldb/lldb-python.h" 11 12// C Includes 13#include <errno.h> 14 15// C++ Includes 16// Other libraries and framework includes 17// Project includes 18#include "lldb/Breakpoint/Watchpoint.h" 19#include "lldb/Core/Debugger.h" 20#include "lldb/Core/State.h" 21#include "lldb/Host/Host.h" 22#include "lldb/Target/Process.h" 23#include "lldb/Target/StopInfo.h" 24#include "lldb/Target/Target.h" 25#include "POSIXStopInfo.h" 26#include "POSIXThread.h" 27#include "ProcessPOSIX.h" 28#include "ProcessPOSIXLog.h" 29#include "ProcessMonitor.h" 30#include "RegisterContext_i386.h" 31#include "RegisterContext_x86_64.h" 32#include "RegisterContextPOSIX.h" 33#include "RegisterContextLinux_x86_64.h" 34#include "RegisterContextFreeBSD_x86_64.h" 35 36#include "UnwindLLDB.h" 37 38using namespace lldb; 39using namespace lldb_private; 40 41 42POSIXThread::POSIXThread(Process &process, lldb::tid_t tid) 43 : Thread(process, tid), 44 m_frame_ap() 45{ 46 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 47 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) 48 log->Printf ("POSIXThread::%s (tid = %" PRIi64 ")", __FUNCTION__, tid); 49 50 // Set the current watchpoints for this thread. 51 Target &target = GetProcess()->GetTarget(); 52 const WatchpointList &wp_list = target.GetWatchpointList(); 53 size_t wp_size = wp_list.GetSize(); 54 55 for (uint32_t wp_idx = 0; wp_idx < wp_size; wp_idx++) 56 { 57 lldb::WatchpointSP wp = wp_list.GetByIndex(wp_idx); 58 if (wp.get() && wp->IsEnabled()) 59 { 60 assert(EnableHardwareWatchpoint(wp.get())); 61 } 62 } 63} 64 65POSIXThread::~POSIXThread() 66{ 67 DestroyThread(); 68} 69 70ProcessMonitor & 71POSIXThread::GetMonitor() 72{ 73 ProcessSP base = GetProcess(); 74 ProcessPOSIX &process = static_cast<ProcessPOSIX&>(*base); 75 return process.GetMonitor(); 76} 77 78void 79POSIXThread::RefreshStateAfterStop() 80{ 81 // Invalidate all registers in our register context. We don't set "force" to 82 // true because the stop reply packet might have had some register values 83 // that were expedited and these will already be copied into the register 84 // context by the time this function gets called. The KDPRegisterContext 85 // class has been made smart enough to detect when it needs to invalidate 86 // which registers are valid by putting hooks in the register read and 87 // register supply functions where they check the process stop ID and do 88 // the right thing. 89 //if (StateIsStoppedState(GetState()) 90 { 91 const bool force = false; 92 GetRegisterContext()->InvalidateIfNeeded (force); 93 } 94 // FIXME: This should probably happen somewhere else. 95 SetResumeState(eStateRunning); 96 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 97 if (log) 98 log->Printf ("POSIXThread::%s (tid = %" PRIi64 ") setting thread resume state to running", __FUNCTION__, GetID()); 99} 100 101const char * 102POSIXThread::GetInfo() 103{ 104 return NULL; 105} 106 107lldb::RegisterContextSP 108POSIXThread::GetRegisterContext() 109{ 110 if (!m_reg_context_sp) 111 { 112 ArchSpec arch = Host::GetArchitecture(); 113 114 switch (arch.GetCore()) 115 { 116 default: 117 assert(false && "CPU type not supported!"); 118 break; 119 120 case ArchSpec::eCore_x86_32_i386: 121 case ArchSpec::eCore_x86_32_i486: 122 case ArchSpec::eCore_x86_32_i486sx: 123 m_reg_context_sp.reset(new RegisterContext_i386(*this, 0)); 124 break; 125 126 case ArchSpec::eCore_x86_64_x86_64: 127// TODO: Use target OS/architecture detection rather than ifdefs so that 128// lldb built on FreeBSD can debug on Linux and vice-versa. 129#ifdef __linux__ 130 m_reg_context_sp.reset(new RegisterContextLinux_x86_64(*this, 0)); 131#endif 132#ifdef __FreeBSD__ 133 m_reg_context_sp.reset(new RegisterContextFreeBSD_x86_64(*this, 0)); 134#endif 135 break; 136 } 137 } 138 return m_reg_context_sp; 139} 140 141lldb::RegisterContextSP 142POSIXThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame) 143{ 144 lldb::RegisterContextSP reg_ctx_sp; 145 uint32_t concrete_frame_idx = 0; 146 147 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 148 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) 149 log->Printf ("POSIXThread::%s ()", __FUNCTION__); 150 151 if (frame) 152 concrete_frame_idx = frame->GetConcreteFrameIndex(); 153 154 if (concrete_frame_idx == 0) 155 reg_ctx_sp = GetRegisterContext(); 156 else 157 { 158 assert(GetUnwinder()); 159 reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame); 160 } 161 162 return reg_ctx_sp; 163} 164 165bool 166POSIXThread::CalculateStopInfo() 167{ 168 SetStopInfo (m_stop_info_sp); 169 return true; 170} 171 172Unwind * 173POSIXThread::GetUnwinder() 174{ 175 if (m_unwinder_ap.get() == NULL) 176 m_unwinder_ap.reset(new UnwindLLDB(*this)); 177 178 return m_unwinder_ap.get(); 179} 180 181void 182POSIXThread::WillResume(lldb::StateType resume_state) 183{ 184 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 185 if (log) 186 log->Printf ("POSIXThread::%s (tid = %" PRIi64 ") setting thread resume state to %s", __FUNCTION__, GetID(), StateAsCString(resume_state)); 187 // TODO: the line below shouldn't really be done, but 188 // the POSIXThread might rely on this so I will leave this in for now 189 SetResumeState(resume_state); 190} 191 192void 193POSIXThread::DidStop() 194{ 195 // Don't set the thread state to stopped unless we really stopped. 196} 197 198bool 199POSIXThread::Resume() 200{ 201 lldb::StateType resume_state = GetResumeState(); 202 ProcessMonitor &monitor = GetMonitor(); 203 bool status; 204 205 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 206 if (log) 207 log->Printf ("POSIXThread::%s (), resume_state = %s", __FUNCTION__, 208 StateAsCString(resume_state)); 209 210 switch (resume_state) 211 { 212 default: 213 assert(false && "Unexpected state for resume!"); 214 status = false; 215 break; 216 217 case lldb::eStateRunning: 218 SetState(resume_state); 219 status = monitor.Resume(GetID(), GetResumeSignal()); 220 break; 221 222 case lldb::eStateStepping: 223 SetState(resume_state); 224 status = monitor.SingleStep(GetID(), GetResumeSignal()); 225 break; 226 case lldb::eStateStopped: 227 case lldb::eStateSuspended: 228 status = true; 229 break; 230 } 231 232 return status; 233} 234 235void 236POSIXThread::Notify(const ProcessMessage &message) 237{ 238 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 239 if (log) 240 log->Printf ("POSIXThread::%s () message kind = '%s' for tid %" PRIu64, 241 __FUNCTION__, message.PrintKind(), GetID()); 242 243 switch (message.GetKind()) 244 { 245 default: 246 assert(false && "Unexpected message kind!"); 247 break; 248 249 case ProcessMessage::eExitMessage: 250 // Nothing to be done. 251 break; 252 253 case ProcessMessage::eLimboMessage: 254 LimboNotify(message); 255 break; 256 257 case ProcessMessage::eSignalMessage: 258 SignalNotify(message); 259 break; 260 261 case ProcessMessage::eSignalDeliveredMessage: 262 SignalDeliveredNotify(message); 263 break; 264 265 case ProcessMessage::eTraceMessage: 266 TraceNotify(message); 267 break; 268 269 case ProcessMessage::eBreakpointMessage: 270 BreakNotify(message); 271 break; 272 273 case ProcessMessage::eWatchpointMessage: 274 WatchNotify(message); 275 break; 276 277 case ProcessMessage::eCrashMessage: 278 CrashNotify(message); 279 break; 280 281 case ProcessMessage::eNewThreadMessage: 282 ThreadNotify(message); 283 break; 284 } 285} 286 287bool 288POSIXThread::EnableHardwareWatchpoint(Watchpoint *wp) 289{ 290 bool wp_set = false; 291 if (wp) 292 { 293 addr_t wp_addr = wp->GetLoadAddress(); 294 size_t wp_size = wp->GetByteSize(); 295 bool wp_read = wp->WatchpointRead(); 296 bool wp_write = wp->WatchpointWrite(); 297 uint32_t wp_hw_index = wp->GetHardwareIndex(); 298 RegisterContextPOSIX* reg_ctx = GetRegisterContextPOSIX(); 299 if (reg_ctx) 300 wp_set = reg_ctx->SetHardwareWatchpointWithIndex(wp_addr, wp_size, 301 wp_read, wp_write, 302 wp_hw_index); 303 } 304 return wp_set; 305} 306 307bool 308POSIXThread::DisableHardwareWatchpoint(Watchpoint *wp) 309{ 310 bool result = false; 311 if (wp) 312 { 313 lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext(); 314 if (reg_ctx_sp.get()) 315 result = reg_ctx_sp->ClearHardwareWatchpoint(wp->GetHardwareIndex()); 316 } 317 return result; 318} 319 320uint32_t 321POSIXThread::NumSupportedHardwareWatchpoints() 322{ 323 lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext(); 324 if (reg_ctx_sp.get()) 325 return reg_ctx_sp->NumSupportedHardwareWatchpoints(); 326 return 0; 327} 328 329uint32_t 330POSIXThread::FindVacantWatchpointIndex() 331{ 332 uint32_t hw_index = LLDB_INVALID_INDEX32; 333 uint32_t num_hw_wps = NumSupportedHardwareWatchpoints(); 334 uint32_t wp_idx; 335 RegisterContextPOSIX* reg_ctx = GetRegisterContextPOSIX(); 336 if (reg_ctx) 337 { 338 for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) 339 { 340 if (reg_ctx->IsWatchpointVacant(wp_idx)) 341 { 342 hw_index = wp_idx; 343 break; 344 } 345 } 346 } 347 return hw_index; 348} 349 350void 351POSIXThread::BreakNotify(const ProcessMessage &message) 352{ 353 bool status; 354 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 355 356 assert(GetRegisterContext()); 357 status = GetRegisterContextPOSIX()->UpdateAfterBreakpoint(); 358 assert(status && "Breakpoint update failed!"); 359 360 // With our register state restored, resolve the breakpoint object 361 // corresponding to our current PC. 362 assert(GetRegisterContext()); 363 lldb::addr_t pc = GetRegisterContext()->GetPC(); 364 if (log) 365 log->Printf ("POSIXThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc); 366 lldb::BreakpointSiteSP bp_site(GetProcess()->GetBreakpointSiteList().FindByAddress(pc)); 367 assert(bp_site); 368 lldb::break_id_t bp_id = bp_site->GetID(); 369 assert(bp_site && bp_site->ValidForThisThread(this)); 370 371 // Make this thread the selected thread 372 GetProcess()->GetThreadList().SetSelectedThreadByID(GetID()); 373 374 m_breakpoint = bp_site; 375 SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id)); 376} 377 378void 379POSIXThread::WatchNotify(const ProcessMessage &message) 380{ 381 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 382 383 lldb::addr_t halt_addr = message.GetHWAddress(); 384 if (log) 385 log->Printf ("POSIXThread::%s () Hardware Watchpoint Address = 0x%8.8" 386 PRIx64, __FUNCTION__, halt_addr); 387 388 RegisterContextPOSIX* reg_ctx = GetRegisterContextPOSIX(); 389 if (reg_ctx) 390 { 391 uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints(); 392 uint32_t wp_idx; 393 for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) 394 { 395 if (reg_ctx->IsWatchpointHit(wp_idx)) 396 { 397 // Clear the watchpoint hit here 398 reg_ctx->ClearWatchpointHits(); 399 break; 400 } 401 } 402 403 if (wp_idx == num_hw_wps) 404 return; 405 406 Target &target = GetProcess()->GetTarget(); 407 lldb::addr_t wp_monitor_addr = reg_ctx->GetWatchpointAddress(wp_idx); 408 const WatchpointList &wp_list = target.GetWatchpointList(); 409 lldb::WatchpointSP wp_sp = wp_list.FindByAddress(wp_monitor_addr); 410 411 if (wp_sp) 412 SetStopInfo (StopInfo::CreateStopReasonWithWatchpointID(*this, 413 wp_sp->GetID())); 414 } 415} 416 417void 418POSIXThread::TraceNotify(const ProcessMessage &message) 419{ 420 RegisterContextPOSIX* reg_ctx = GetRegisterContextPOSIX(); 421 if (reg_ctx) 422 { 423 uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints(); 424 uint32_t wp_idx; 425 for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) 426 { 427 if (reg_ctx->IsWatchpointHit(wp_idx)) 428 { 429 WatchNotify(message); 430 return; 431 } 432 } 433 } 434 SetStopInfo (StopInfo::CreateStopReasonToTrace(*this)); 435} 436 437void 438POSIXThread::LimboNotify(const ProcessMessage &message) 439{ 440 SetStopInfo (lldb::StopInfoSP(new POSIXLimboStopInfo(*this))); 441} 442 443void 444POSIXThread::SignalNotify(const ProcessMessage &message) 445{ 446 int signo = message.GetSignal(); 447 448 SetStopInfo (StopInfo::CreateStopReasonWithSignal(*this, signo)); 449 SetResumeSignal(signo); 450} 451 452void 453POSIXThread::SignalDeliveredNotify(const ProcessMessage &message) 454{ 455 int signo = message.GetSignal(); 456 457 SetStopInfo (StopInfo::CreateStopReasonWithSignal(*this, signo)); 458 SetResumeSignal(signo); 459} 460 461void 462POSIXThread::CrashNotify(const ProcessMessage &message) 463{ 464 // FIXME: Update stop reason as per bugzilla 14598 465 int signo = message.GetSignal(); 466 467 assert(message.GetKind() == ProcessMessage::eCrashMessage); 468 469 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 470 if (log) 471 log->Printf ("POSIXThread::%s () signo = %i, reason = '%s'", 472 __FUNCTION__, signo, message.PrintCrashReason()); 473 474 SetStopInfo (lldb::StopInfoSP(new POSIXCrashStopInfo(*this, signo, 475 message.GetCrashReason(), 476 message.GetFaultAddress()))); 477 SetResumeSignal(signo); 478} 479 480void 481POSIXThread::ThreadNotify(const ProcessMessage &message) 482{ 483 SetStopInfo (lldb::StopInfoSP(new POSIXNewThreadStopInfo(*this))); 484} 485 486unsigned 487POSIXThread::GetRegisterIndexFromOffset(unsigned offset) 488{ 489 unsigned reg; 490 ArchSpec arch = Host::GetArchitecture(); 491 492 switch (arch.GetCore()) 493 { 494 default: 495 assert(false && "CPU type not supported!"); 496 break; 497 498 case ArchSpec::eCore_x86_32_i386: 499 case ArchSpec::eCore_x86_32_i486: 500 case ArchSpec::eCore_x86_32_i486sx: 501 case ArchSpec::eCore_x86_64_x86_64: 502 { 503 RegisterContextSP base = GetRegisterContext(); 504 if (base) { 505 RegisterContextPOSIX &context = static_cast<RegisterContextPOSIX &>(*base); 506 reg = context.GetRegisterIndexFromOffset(offset); 507 } 508 } 509 break; 510 } 511 return reg; 512} 513 514const char * 515POSIXThread::GetRegisterName(unsigned reg) 516{ 517 const char * name = nullptr; 518 ArchSpec arch = Host::GetArchitecture(); 519 520 switch (arch.GetCore()) 521 { 522 default: 523 assert(false && "CPU type not supported!"); 524 break; 525 526 case ArchSpec::eCore_x86_32_i386: 527 case ArchSpec::eCore_x86_32_i486: 528 case ArchSpec::eCore_x86_32_i486sx: 529 case ArchSpec::eCore_x86_64_x86_64: 530 name = GetRegisterContext()->GetRegisterName(reg); 531 break; 532 } 533 return name; 534} 535 536const char * 537POSIXThread::GetRegisterNameFromOffset(unsigned offset) 538{ 539 return GetRegisterName(GetRegisterIndexFromOffset(offset)); 540} 541 542