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::SetLaunching () 304 { 305 const StateType new_state = StateType::eStateLaunching; 306 MaybeLogStateChange (new_state); 307 m_state = new_state; 308 309 // Also mark it as stopped since launching temporarily stops the newly created thread 310 // in the ptrace machinery. 311 m_stop_info.reason = StopReason::eStopReasonSignal; 312 m_stop_info.details.signal.signo = SIGSTOP; 313 } 314 315 316 void 317 NativeThreadLinux::SetRunning () 318 { 319 const StateType new_state = StateType::eStateRunning; 320 MaybeLogStateChange (new_state); 321 m_state = new_state; 322 323 m_stop_info.reason = StopReason::eStopReasonNone; 324 m_stop_description.clear(); 325 326 // If watchpoints have been set, but none on this thread, 327 // then this is a new thread. So set all existing watchpoints. 328 if (m_watchpoint_index_map.empty()) 329 { 330 const auto process_sp = GetProcess(); 331 if (process_sp) 332 { 333 const auto &watchpoint_map = process_sp->GetWatchpointMap(); 334 if (watchpoint_map.empty()) return; 335 GetRegisterContext()->ClearAllHardwareWatchpoints(); 336 for (const auto &pair : watchpoint_map) 337 { 338 const auto& wp = pair.second; 339 SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags, wp.m_hardware); 340 } 341 } 342 } 343 } 344 345 void 346 NativeThreadLinux::SetStepping () 347 { 348 const StateType new_state = StateType::eStateStepping; 349 MaybeLogStateChange (new_state); 350 m_state = new_state; 351 352 m_stop_info.reason = StopReason::eStopReasonNone; 353 } 354 355 void 356 NativeThreadLinux::SetStoppedBySignal (uint32_t signo) 357 { 358 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 359 if (log) 360 log->Printf ("NativeThreadLinux::%s called with signal 0x%02" PRIx32, __FUNCTION__, signo); 361 362 const StateType new_state = StateType::eStateStopped; 363 MaybeLogStateChange (new_state); 364 m_state = new_state; 365 366 m_stop_info.reason = StopReason::eStopReasonSignal; 367 m_stop_info.details.signal.signo = signo; 368 } 369 370 bool 371 NativeThreadLinux::IsStopped (int *signo) 372 { 373 if (!StateIsStoppedState (m_state, false)) 374 return false; 375 376 // If we are stopped by a signal, return the signo. 377 if (signo && 378 m_state == StateType::eStateStopped && 379 m_stop_info.reason == StopReason::eStopReasonSignal) 380 { 381 *signo = m_stop_info.details.signal.signo; 382 } 383 384 // Regardless, we are stopped. 385 return true; 386 } 387 388 389 void 390 NativeThreadLinux::SetStoppedByExec () 391 { 392 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 393 if (log) 394 log->Printf ("NativeThreadLinux::%s()", __FUNCTION__); 395 396 const StateType new_state = StateType::eStateStopped; 397 MaybeLogStateChange (new_state); 398 m_state = new_state; 399 400 m_stop_info.reason = StopReason::eStopReasonExec; 401 m_stop_info.details.signal.signo = SIGSTOP; 402 } 403 404 void 405 NativeThreadLinux::SetStoppedByBreakpoint () 406 { 407 const StateType new_state = StateType::eStateStopped; 408 MaybeLogStateChange (new_state); 409 m_state = new_state; 410 411 m_stop_info.reason = StopReason::eStopReasonBreakpoint; 412 m_stop_info.details.signal.signo = SIGTRAP; 413 m_stop_description.clear(); 414 } 415 416 void 417 NativeThreadLinux::SetStoppedByWatchpoint (uint32_t wp_index) 418 { 419 const StateType new_state = StateType::eStateStopped; 420 MaybeLogStateChange (new_state); 421 m_state = new_state; 422 m_stop_description.clear (); 423 424 lldbassert(wp_index != LLDB_INVALID_INDEX32 && 425 "wp_index cannot be invalid"); 426 427 std::ostringstream ostr; 428 ostr << GetRegisterContext()->GetWatchpointAddress(wp_index) << " "; 429 ostr << wp_index; 430 m_stop_description = ostr.str(); 431 432 m_stop_info.reason = StopReason::eStopReasonWatchpoint; 433 m_stop_info.details.signal.signo = SIGTRAP; 434 } 435 436 bool 437 NativeThreadLinux::IsStoppedAtBreakpoint () 438 { 439 return GetState () == StateType::eStateStopped && 440 m_stop_info.reason == StopReason::eStopReasonBreakpoint; 441 } 442 443 bool 444 NativeThreadLinux::IsStoppedAtWatchpoint () 445 { 446 return GetState () == StateType::eStateStopped && 447 m_stop_info.reason == StopReason::eStopReasonWatchpoint; 448 } 449 450 void 451 NativeThreadLinux::SetStoppedByTrace () 452 { 453 const StateType new_state = StateType::eStateStopped; 454 MaybeLogStateChange (new_state); 455 m_state = new_state; 456 457 m_stop_info.reason = StopReason::eStopReasonTrace; 458 m_stop_info.details.signal.signo = SIGTRAP; 459 } 460 461 void 462 NativeThreadLinux::SetCrashedWithException (const siginfo_t& info) 463 { 464 const StateType new_state = StateType::eStateCrashed; 465 MaybeLogStateChange (new_state); 466 m_state = new_state; 467 468 m_stop_info.reason = StopReason::eStopReasonException; 469 m_stop_info.details.signal.signo = info.si_signo; 470 471 const auto reason = GetCrashReason (info); 472 m_stop_description = GetCrashReasonString (reason, reinterpret_cast<uintptr_t>(info.si_addr)); 473 } 474 475 void 476 NativeThreadLinux::SetSuspended () 477 { 478 const StateType new_state = StateType::eStateSuspended; 479 MaybeLogStateChange (new_state); 480 m_state = new_state; 481 482 // FIXME what makes sense here? Do we need a suspended StopReason? 483 m_stop_info.reason = StopReason::eStopReasonNone; 484 } 485 486 void 487 NativeThreadLinux::SetExited () 488 { 489 const StateType new_state = StateType::eStateExited; 490 MaybeLogStateChange (new_state); 491 m_state = new_state; 492 493 m_stop_info.reason = StopReason::eStopReasonThreadExiting; 494 } 495 496 void 497 NativeThreadLinux::MaybeLogStateChange (lldb::StateType new_state) 498 { 499 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 500 // If we're not logging, we're done. 501 if (!log) 502 return; 503 504 // If this is a state change to the same state, we're done. 505 lldb::StateType old_state = m_state; 506 if (new_state == old_state) 507 return; 508 509 NativeProcessProtocolSP m_process_sp = m_process_wp.lock (); 510 lldb::pid_t pid = m_process_sp ? m_process_sp->GetID () : LLDB_INVALID_PROCESS_ID; 511 512 // Log it. 513 log->Printf ("NativeThreadLinux: thread (pid=%" PRIu64 ", tid=%" PRIu64 ") changing from state %s to %s", pid, GetID (), StateAsCString (old_state), StateAsCString (new_state)); 514 } 515