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