1 //===-- NativeThreadLinux.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 "NativeThreadLinux.h" 11 12 #include <signal.h> 13 #include <sstream> 14 15 #include "NativeProcessLinux.h" 16 #include "NativeRegisterContextLinux_arm.h" 17 #include "NativeRegisterContextLinux_arm64.h" 18 #include "NativeRegisterContextLinux_x86_64.h" 19 #include "NativeRegisterContextLinux_mips64.h" 20 21 #include "lldb/Core/Log.h" 22 #include "lldb/Core/State.h" 23 #include "lldb/Host/Host.h" 24 #include "lldb/Host/HostInfo.h" 25 #include "lldb/Host/HostNativeThread.h" 26 #include "lldb/Utility/LLDBAssert.h" 27 #include "lldb/lldb-enumerations.h" 28 29 #include "llvm/ADT/SmallString.h" 30 31 #include "Plugins/Process/POSIX/CrashReason.h" 32 33 #include "Plugins/Process/Utility/RegisterContextLinux_arm.h" 34 #include "Plugins/Process/Utility/RegisterContextLinux_arm64.h" 35 #include "Plugins/Process/Utility/RegisterContextLinux_i386.h" 36 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" 37 #include "Plugins/Process/Utility/RegisterContextLinux_mips64.h" 38 #include "Plugins/Process/Utility/RegisterInfoInterface.h" 39 40 using namespace lldb; 41 using namespace lldb_private; 42 using namespace lldb_private::process_linux; 43 44 namespace 45 { 46 void LogThreadStopInfo (Log &log, const ThreadStopInfo &stop_info, const char *const header) 47 { 48 switch (stop_info.reason) 49 { 50 case eStopReasonNone: 51 log.Printf ("%s: %s no stop reason", __FUNCTION__, header); 52 return; 53 case eStopReasonTrace: 54 log.Printf ("%s: %s trace, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo); 55 return; 56 case eStopReasonBreakpoint: 57 log.Printf ("%s: %s breakpoint, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo); 58 return; 59 case eStopReasonWatchpoint: 60 log.Printf ("%s: %s watchpoint, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo); 61 return; 62 case eStopReasonSignal: 63 log.Printf ("%s: %s signal 0x%02" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo); 64 return; 65 case eStopReasonException: 66 log.Printf ("%s: %s exception type 0x%02" PRIx64, __FUNCTION__, header, stop_info.details.exception.type); 67 return; 68 case eStopReasonExec: 69 log.Printf ("%s: %s exec, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo); 70 return; 71 case eStopReasonPlanComplete: 72 log.Printf ("%s: %s plan complete", __FUNCTION__, header); 73 return; 74 case eStopReasonThreadExiting: 75 log.Printf ("%s: %s thread exiting", __FUNCTION__, header); 76 return; 77 case eStopReasonInstrumentation: 78 log.Printf ("%s: %s instrumentation", __FUNCTION__, header); 79 return; 80 default: 81 log.Printf ("%s: %s invalid stop reason %" PRIu32, __FUNCTION__, header, static_cast<uint32_t> (stop_info.reason)); 82 } 83 } 84 } 85 86 NativeThreadLinux::NativeThreadLinux (NativeProcessLinux *process, lldb::tid_t tid) : 87 NativeThreadProtocol (process, tid), 88 m_state (StateType::eStateInvalid), 89 m_stop_info (), 90 m_reg_context_sp (), 91 m_stop_description () 92 { 93 } 94 95 std::string 96 NativeThreadLinux::GetName() 97 { 98 NativeProcessProtocolSP process_sp = m_process_wp.lock (); 99 if (!process_sp) 100 return "<unknown: no process>"; 101 102 // const NativeProcessLinux *const process = reinterpret_cast<NativeProcessLinux*> (process_sp->get ()); 103 llvm::SmallString<32> thread_name; 104 HostNativeThread::GetName(GetID(), thread_name); 105 return thread_name.c_str(); 106 } 107 108 lldb::StateType 109 NativeThreadLinux::GetState () 110 { 111 return m_state; 112 } 113 114 115 bool 116 NativeThreadLinux::GetStopReason (ThreadStopInfo &stop_info, std::string& description) 117 { 118 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 119 120 description.clear(); 121 122 switch (m_state) 123 { 124 case eStateStopped: 125 case eStateCrashed: 126 case eStateExited: 127 case eStateSuspended: 128 case eStateUnloaded: 129 if (log) 130 LogThreadStopInfo (*log, m_stop_info, "m_stop_info in thread:"); 131 stop_info = m_stop_info; 132 switch (m_stop_info.reason) 133 { 134 case StopReason::eStopReasonException: 135 case StopReason::eStopReasonBreakpoint: 136 case StopReason::eStopReasonWatchpoint: 137 description = m_stop_description; 138 default: 139 break; 140 } 141 if (log) 142 LogThreadStopInfo (*log, stop_info, "returned stop_info:"); 143 144 return true; 145 146 case eStateInvalid: 147 case eStateConnected: 148 case eStateAttaching: 149 case eStateLaunching: 150 case eStateRunning: 151 case eStateStepping: 152 case eStateDetached: 153 if (log) 154 { 155 log->Printf ("NativeThreadLinux::%s tid %" PRIu64 " in state %s cannot answer stop reason", 156 __FUNCTION__, GetID (), StateAsCString (m_state)); 157 } 158 return false; 159 } 160 llvm_unreachable("unhandled StateType!"); 161 } 162 163 NativeRegisterContextSP 164 NativeThreadLinux::GetRegisterContext () 165 { 166 // Return the register context if we already created it. 167 if (m_reg_context_sp) 168 return m_reg_context_sp; 169 170 // First select the appropriate RegisterInfoInterface. 171 RegisterInfoInterface *reg_interface = nullptr; 172 NativeProcessProtocolSP m_process_sp = m_process_wp.lock (); 173 if (!m_process_sp) 174 return NativeRegisterContextSP (); 175 176 ArchSpec target_arch; 177 if (!m_process_sp->GetArchitecture (target_arch)) 178 return NativeRegisterContextSP (); 179 180 switch (target_arch.GetTriple().getOS()) 181 { 182 case llvm::Triple::Linux: 183 switch (target_arch.GetMachine()) 184 { 185 case llvm::Triple::aarch64: 186 assert((HostInfo::GetArchitecture ().GetAddressByteSize() == 8) && "Register setting path assumes this is a 64-bit host"); 187 reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_arm64(target_arch)); 188 break; 189 case llvm::Triple::arm: 190 assert(HostInfo::GetArchitecture ().GetAddressByteSize() == 4); 191 reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_arm(target_arch)); 192 break; 193 case llvm::Triple::x86: 194 case llvm::Triple::x86_64: 195 if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) 196 { 197 // 32-bit hosts run with a RegisterContextLinux_i386 context. 198 reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_i386(target_arch)); 199 } 200 else 201 { 202 assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) && 203 "Register setting path assumes this is a 64-bit host"); 204 // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64 register context. 205 reg_interface = static_cast<RegisterInfoInterface*> (new RegisterContextLinux_x86_64 (target_arch)); 206 } 207 break; 208 case llvm::Triple::mips64: 209 case llvm::Triple::mips64el: 210 assert((HostInfo::GetArchitecture ().GetAddressByteSize() == 8) 211 && "Register setting path assumes this is a 64-bit host"); 212 reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_mips64 (target_arch)); 213 break; 214 default: 215 break; 216 } 217 break; 218 default: 219 break; 220 } 221 222 assert(reg_interface && "OS or CPU not supported!"); 223 if (!reg_interface) 224 return NativeRegisterContextSP (); 225 226 // Now create the register context. 227 switch (target_arch.GetMachine()) 228 { 229 #if 0 230 case llvm::Triple::mips64: 231 { 232 RegisterContextPOSIXProcessMonitor_mips64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_mips64(*this, 0, reg_interface); 233 m_posix_thread = reg_ctx; 234 m_reg_context_sp.reset(reg_ctx); 235 break; 236 } 237 #endif 238 case llvm::Triple::mips64: 239 case llvm::Triple::mips64el: 240 { 241 const uint32_t concrete_frame_idx = 0; 242 m_reg_context_sp.reset (new NativeRegisterContextLinux_mips64 (*this, concrete_frame_idx, reg_interface)); 243 break; 244 } 245 case llvm::Triple::aarch64: 246 { 247 const uint32_t concrete_frame_idx = 0; 248 m_reg_context_sp.reset (new NativeRegisterContextLinux_arm64(*this, concrete_frame_idx, reg_interface)); 249 break; 250 } 251 case llvm::Triple::arm: 252 { 253 const uint32_t concrete_frame_idx = 0; 254 m_reg_context_sp.reset (new NativeRegisterContextLinux_arm(*this, concrete_frame_idx, reg_interface)); 255 break; 256 } 257 case llvm::Triple::x86: 258 case llvm::Triple::x86_64: 259 { 260 const uint32_t concrete_frame_idx = 0; 261 m_reg_context_sp.reset (new NativeRegisterContextLinux_x86_64(*this, concrete_frame_idx, reg_interface)); 262 break; 263 } 264 default: 265 break; 266 } 267 268 return m_reg_context_sp; 269 } 270 271 Error 272 NativeThreadLinux::SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) 273 { 274 if (!hardware) 275 return Error ("not implemented"); 276 if (m_state == eStateLaunching) 277 return Error (); 278 Error error = RemoveWatchpoint(addr); 279 if (error.Fail()) return error; 280 NativeRegisterContextSP reg_ctx = GetRegisterContext (); 281 uint32_t wp_index = 282 reg_ctx->SetHardwareWatchpoint (addr, size, watch_flags); 283 if (wp_index == LLDB_INVALID_INDEX32) 284 return Error ("Setting hardware watchpoint failed."); 285 m_watchpoint_index_map.insert({addr, wp_index}); 286 return Error (); 287 } 288 289 Error 290 NativeThreadLinux::RemoveWatchpoint (lldb::addr_t addr) 291 { 292 auto wp = m_watchpoint_index_map.find(addr); 293 if (wp == m_watchpoint_index_map.end()) 294 return Error (); 295 uint32_t wp_index = wp->second; 296 m_watchpoint_index_map.erase(wp); 297 if (GetRegisterContext()->ClearHardwareWatchpoint(wp_index)) 298 return Error (); 299 return Error ("Clearing hardware watchpoint failed."); 300 } 301 302 void 303 NativeThreadLinux::SetRunning () 304 { 305 const StateType new_state = StateType::eStateRunning; 306 MaybeLogStateChange (new_state); 307 m_state = new_state; 308 309 m_stop_info.reason = StopReason::eStopReasonNone; 310 m_stop_description.clear(); 311 312 // If watchpoints have been set, but none on this thread, 313 // then this is a new thread. So set all existing watchpoints. 314 if (m_watchpoint_index_map.empty()) 315 { 316 const auto process_sp = GetProcess(); 317 if (process_sp) 318 { 319 const auto &watchpoint_map = process_sp->GetWatchpointMap(); 320 if (watchpoint_map.empty()) return; 321 GetRegisterContext()->ClearAllHardwareWatchpoints(); 322 for (const auto &pair : watchpoint_map) 323 { 324 const auto& wp = pair.second; 325 SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags, wp.m_hardware); 326 } 327 } 328 } 329 } 330 331 void 332 NativeThreadLinux::SetStepping () 333 { 334 const StateType new_state = StateType::eStateStepping; 335 MaybeLogStateChange (new_state); 336 m_state = new_state; 337 338 m_stop_info.reason = StopReason::eStopReasonNone; 339 } 340 341 void 342 NativeThreadLinux::SetStoppedBySignal (uint32_t signo) 343 { 344 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 345 if (log) 346 log->Printf ("NativeThreadLinux::%s called with signal 0x%02" PRIx32, __FUNCTION__, signo); 347 348 const StateType new_state = StateType::eStateStopped; 349 MaybeLogStateChange (new_state); 350 m_state = new_state; 351 352 m_stop_info.reason = StopReason::eStopReasonSignal; 353 m_stop_info.details.signal.signo = signo; 354 } 355 356 bool 357 NativeThreadLinux::IsStopped (int *signo) 358 { 359 if (!StateIsStoppedState (m_state, false)) 360 return false; 361 362 // If we are stopped by a signal, return the signo. 363 if (signo && 364 m_state == StateType::eStateStopped && 365 m_stop_info.reason == StopReason::eStopReasonSignal) 366 { 367 *signo = m_stop_info.details.signal.signo; 368 } 369 370 // Regardless, we are stopped. 371 return true; 372 } 373 374 375 void 376 NativeThreadLinux::SetStoppedByExec () 377 { 378 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 379 if (log) 380 log->Printf ("NativeThreadLinux::%s()", __FUNCTION__); 381 382 const StateType new_state = StateType::eStateStopped; 383 MaybeLogStateChange (new_state); 384 m_state = new_state; 385 386 m_stop_info.reason = StopReason::eStopReasonExec; 387 m_stop_info.details.signal.signo = SIGSTOP; 388 } 389 390 void 391 NativeThreadLinux::SetStoppedByBreakpoint () 392 { 393 const StateType new_state = StateType::eStateStopped; 394 MaybeLogStateChange (new_state); 395 m_state = new_state; 396 397 m_stop_info.reason = StopReason::eStopReasonBreakpoint; 398 m_stop_info.details.signal.signo = SIGTRAP; 399 m_stop_description.clear(); 400 } 401 402 void 403 NativeThreadLinux::SetStoppedByWatchpoint (uint32_t wp_index) 404 { 405 const StateType new_state = StateType::eStateStopped; 406 MaybeLogStateChange (new_state); 407 m_state = new_state; 408 m_stop_description.clear (); 409 410 lldbassert(wp_index != LLDB_INVALID_INDEX32 && 411 "wp_index cannot be invalid"); 412 413 std::ostringstream ostr; 414 ostr << GetRegisterContext()->GetWatchpointAddress(wp_index) << " "; 415 ostr << wp_index; 416 m_stop_description = ostr.str(); 417 418 m_stop_info.reason = StopReason::eStopReasonWatchpoint; 419 m_stop_info.details.signal.signo = SIGTRAP; 420 } 421 422 bool 423 NativeThreadLinux::IsStoppedAtBreakpoint () 424 { 425 return GetState () == StateType::eStateStopped && 426 m_stop_info.reason == StopReason::eStopReasonBreakpoint; 427 } 428 429 bool 430 NativeThreadLinux::IsStoppedAtWatchpoint () 431 { 432 return GetState () == StateType::eStateStopped && 433 m_stop_info.reason == StopReason::eStopReasonWatchpoint; 434 } 435 436 void 437 NativeThreadLinux::SetStoppedByTrace () 438 { 439 const StateType new_state = StateType::eStateStopped; 440 MaybeLogStateChange (new_state); 441 m_state = new_state; 442 443 m_stop_info.reason = StopReason::eStopReasonTrace; 444 m_stop_info.details.signal.signo = SIGTRAP; 445 } 446 447 void 448 NativeThreadLinux::SetCrashedWithException (const siginfo_t& info) 449 { 450 const StateType new_state = StateType::eStateCrashed; 451 MaybeLogStateChange (new_state); 452 m_state = new_state; 453 454 m_stop_info.reason = StopReason::eStopReasonException; 455 m_stop_info.details.signal.signo = info.si_signo; 456 457 const auto reason = GetCrashReason (info); 458 m_stop_description = GetCrashReasonString (reason, reinterpret_cast<uintptr_t>(info.si_addr)); 459 } 460 461 void 462 NativeThreadLinux::SetSuspended () 463 { 464 const StateType new_state = StateType::eStateSuspended; 465 MaybeLogStateChange (new_state); 466 m_state = new_state; 467 468 // FIXME what makes sense here? Do we need a suspended StopReason? 469 m_stop_info.reason = StopReason::eStopReasonNone; 470 } 471 472 void 473 NativeThreadLinux::SetExited () 474 { 475 const StateType new_state = StateType::eStateExited; 476 MaybeLogStateChange (new_state); 477 m_state = new_state; 478 479 m_stop_info.reason = StopReason::eStopReasonThreadExiting; 480 } 481 482 void 483 NativeThreadLinux::MaybeLogStateChange (lldb::StateType new_state) 484 { 485 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 486 // If we're not logging, we're done. 487 if (!log) 488 return; 489 490 // If this is a state change to the same state, we're done. 491 lldb::StateType old_state = m_state; 492 if (new_state == old_state) 493 return; 494 495 NativeProcessProtocolSP m_process_sp = m_process_wp.lock (); 496 lldb::pid_t pid = m_process_sp ? m_process_sp->GetID () : LLDB_INVALID_PROCESS_ID; 497 498 // Log it. 499 log->Printf ("NativeThreadLinux: thread (pid=%" PRIu64 ", tid=%" PRIu64 ") changing from state %s to %s", pid, GetID (), StateAsCString (old_state), StateAsCString (new_state)); 500 } 501