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 14 #include "NativeProcessLinux.h" 15 #include "NativeRegisterContextLinux_x86_64.h" 16 17 #include "lldb/Core/Log.h" 18 #include "lldb/Core/State.h" 19 #include "lldb/Host/Host.h" 20 #include "lldb/Host/HostInfo.h" 21 #include "lldb/lldb-enumerations.h" 22 #include "lldb/lldb-private-log.h" 23 #include "Plugins/Process/Utility/RegisterContextLinux_i386.h" 24 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" 25 #include "Plugins/Process/Utility/RegisterInfoInterface.h" 26 27 using namespace lldb; 28 using namespace lldb_private; 29 30 namespace 31 { 32 void LogThreadStopInfo (Log &log, const ThreadStopInfo &stop_info, const char *const header) 33 { 34 switch (stop_info.reason) 35 { 36 case eStopReasonSignal: 37 log.Printf ("%s: %s signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo); 38 return; 39 case eStopReasonException: 40 log.Printf ("%s: %s exception type 0x%" PRIx64, __FUNCTION__, header, stop_info.details.exception.type); 41 return; 42 case eStopReasonExec: 43 log.Printf ("%s: %s exec, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo); 44 return; 45 default: 46 log.Printf ("%s: %s invalid stop reason %" PRIu32, __FUNCTION__, header, static_cast<uint32_t> (stop_info.reason)); 47 } 48 } 49 } 50 51 NativeThreadLinux::NativeThreadLinux (NativeProcessLinux *process, lldb::tid_t tid) : 52 NativeThreadProtocol (process, tid), 53 m_state (StateType::eStateInvalid), 54 m_stop_info (), 55 m_reg_context_sp () 56 { 57 } 58 59 const char * 60 NativeThreadLinux::GetName() 61 { 62 NativeProcessProtocolSP process_sp = m_process_wp.lock (); 63 if (!process_sp) 64 return "<unknown: no process>"; 65 66 // const NativeProcessLinux *const process = reinterpret_cast<NativeProcessLinux*> (process_sp->get ()); 67 return Host::GetThreadName (process_sp->GetID (), GetID ()).c_str (); 68 } 69 70 lldb::StateType 71 NativeThreadLinux::GetState () 72 { 73 return m_state; 74 } 75 76 77 bool 78 NativeThreadLinux::GetStopReason (ThreadStopInfo &stop_info) 79 { 80 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 81 switch (m_state) 82 { 83 case eStateStopped: 84 case eStateCrashed: 85 case eStateExited: 86 case eStateSuspended: 87 case eStateUnloaded: 88 if (log) 89 LogThreadStopInfo (*log, m_stop_info, "m_stop_info in thread:"); 90 stop_info = m_stop_info; 91 if (log) 92 LogThreadStopInfo (*log, stop_info, "returned stop_info:"); 93 return true; 94 95 case eStateInvalid: 96 case eStateConnected: 97 case eStateAttaching: 98 case eStateLaunching: 99 case eStateRunning: 100 case eStateStepping: 101 case eStateDetached: 102 if (log) 103 { 104 log->Printf ("NativeThreadLinux::%s tid %" PRIu64 " in state %s cannot answer stop reason", 105 __FUNCTION__, GetID (), StateAsCString (m_state)); 106 } 107 return false; 108 } 109 } 110 111 lldb_private::NativeRegisterContextSP 112 NativeThreadLinux::GetRegisterContext () 113 { 114 // Return the register context if we already created it. 115 if (m_reg_context_sp) 116 return m_reg_context_sp; 117 118 // First select the appropriate RegisterInfoInterface. 119 RegisterInfoInterface *reg_interface = nullptr; 120 NativeProcessProtocolSP m_process_sp = m_process_wp.lock (); 121 if (!m_process_sp) 122 return NativeRegisterContextSP (); 123 124 ArchSpec target_arch; 125 if (!m_process_sp->GetArchitecture (target_arch)) 126 return NativeRegisterContextSP (); 127 128 switch (target_arch.GetTriple().getOS()) 129 { 130 case llvm::Triple::Linux: 131 switch (target_arch.GetMachine()) 132 { 133 case llvm::Triple::x86: 134 case llvm::Triple::x86_64: 135 if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) 136 { 137 // 32-bit hosts run with a RegisterContextLinux_i386 context. 138 reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_i386(target_arch)); 139 } 140 else 141 { 142 assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) && 143 "Register setting path assumes this is a 64-bit host"); 144 // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64 register context. 145 reg_interface = static_cast<RegisterInfoInterface*> (new RegisterContextLinux_x86_64 (target_arch)); 146 } 147 break; 148 default: 149 break; 150 } 151 break; 152 default: 153 break; 154 } 155 156 assert(reg_interface && "OS or CPU not supported!"); 157 if (!reg_interface) 158 return NativeRegisterContextSP (); 159 160 // Now create the register context. 161 switch (target_arch.GetMachine()) 162 { 163 #if 0 164 case llvm::Triple::mips64: 165 { 166 RegisterContextPOSIXProcessMonitor_mips64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_mips64(*this, 0, reg_interface); 167 m_posix_thread = reg_ctx; 168 m_reg_context_sp.reset(reg_ctx); 169 break; 170 } 171 #endif 172 #if 0 173 case llvm::Triple::x86: 174 #endif 175 case llvm::Triple::x86_64: 176 { 177 const uint32_t concrete_frame_idx = 0; 178 m_reg_context_sp.reset (new NativeRegisterContextLinux_x86_64(*this, concrete_frame_idx, reg_interface)); 179 break; 180 } 181 default: 182 break; 183 } 184 185 return m_reg_context_sp; 186 } 187 188 Error 189 NativeThreadLinux::SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) 190 { 191 // TODO implement 192 return Error ("not implemented"); 193 } 194 195 Error 196 NativeThreadLinux::RemoveWatchpoint (lldb::addr_t addr) 197 { 198 // TODO implement 199 return Error ("not implemented"); 200 } 201 202 void 203 NativeThreadLinux::SetLaunching () 204 { 205 const StateType new_state = StateType::eStateLaunching; 206 MaybeLogStateChange (new_state); 207 m_state = new_state; 208 209 // Also mark it as stopped since launching temporarily stops the newly created thread 210 // in the ptrace machinery. 211 m_stop_info.reason = StopReason::eStopReasonSignal; 212 m_stop_info.details.signal.signo = SIGSTOP; 213 } 214 215 216 void 217 NativeThreadLinux::SetRunning () 218 { 219 const StateType new_state = StateType::eStateRunning; 220 MaybeLogStateChange (new_state); 221 m_state = new_state; 222 223 m_stop_info.reason = StopReason::eStopReasonNone; 224 } 225 226 void 227 NativeThreadLinux::SetStepping () 228 { 229 const StateType new_state = StateType::eStateStepping; 230 MaybeLogStateChange (new_state); 231 m_state = new_state; 232 233 m_stop_info.reason = StopReason::eStopReasonNone; 234 } 235 236 void 237 NativeThreadLinux::SetStoppedBySignal (uint32_t signo) 238 { 239 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 240 if (log) 241 log->Printf ("NativeThreadLinux::%s called with signal 0x%" PRIx32, __FUNCTION__, signo); 242 243 const StateType new_state = StateType::eStateStopped; 244 MaybeLogStateChange (new_state); 245 m_state = new_state; 246 247 m_stop_info.reason = StopReason::eStopReasonSignal; 248 m_stop_info.details.signal.signo = signo; 249 } 250 251 void 252 NativeThreadLinux::SetStoppedByExec () 253 { 254 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 255 if (log) 256 log->Printf ("NativeThreadLinux::%s()", __FUNCTION__); 257 258 const StateType new_state = StateType::eStateStopped; 259 MaybeLogStateChange (new_state); 260 m_state = new_state; 261 262 m_stop_info.reason = StopReason::eStopReasonExec; 263 m_stop_info.details.signal.signo = SIGSTOP; 264 } 265 266 void 267 NativeThreadLinux::SetStoppedByBreakpoint () 268 { 269 const StateType new_state = StateType::eStateStopped; 270 MaybeLogStateChange (new_state); 271 m_state = new_state; 272 273 m_stop_info.reason = StopReason::eStopReasonSignal; 274 m_stop_info.details.signal.signo = SIGTRAP; 275 } 276 277 bool 278 NativeThreadLinux::IsStoppedAtBreakpoint () 279 { 280 // Are we stopped? If not, this can't be a breakpoint. 281 if (GetState () != StateType::eStateStopped) 282 return false; 283 284 // Was the stop reason a signal with signal number SIGTRAP? If not, not a breakpoint. 285 return (m_stop_info.reason == StopReason::eStopReasonSignal) && 286 (m_stop_info.details.signal.signo == SIGTRAP); 287 } 288 289 void 290 NativeThreadLinux::SetCrashedWithException (uint64_t exception_type, lldb::addr_t exception_addr) 291 { 292 const StateType new_state = StateType::eStateCrashed; 293 MaybeLogStateChange (new_state); 294 m_state = new_state; 295 296 m_stop_info.reason = StopReason::eStopReasonException; 297 m_stop_info.details.exception.type = exception_type; 298 m_stop_info.details.exception.data_count = 1; 299 m_stop_info.details.exception.data[0] = exception_addr; 300 } 301 302 303 void 304 NativeThreadLinux::SetSuspended () 305 { 306 const StateType new_state = StateType::eStateSuspended; 307 MaybeLogStateChange (new_state); 308 m_state = new_state; 309 310 // FIXME what makes sense here? Do we need a suspended StopReason? 311 m_stop_info.reason = StopReason::eStopReasonNone; 312 } 313 314 void 315 NativeThreadLinux::SetExited () 316 { 317 const StateType new_state = StateType::eStateExited; 318 MaybeLogStateChange (new_state); 319 m_state = new_state; 320 321 m_stop_info.reason = StopReason::eStopReasonThreadExiting; 322 } 323 324 void 325 NativeThreadLinux::MaybeLogStateChange (lldb::StateType new_state) 326 { 327 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 328 // If we're not logging, we're done. 329 if (!log) 330 return; 331 332 // If this is a state change to the same state, we're done. 333 lldb::StateType old_state = m_state; 334 if (new_state == old_state) 335 return; 336 337 NativeProcessProtocolSP m_process_sp = m_process_wp.lock (); 338 lldb::pid_t pid = m_process_sp ? m_process_sp->GetID () : LLDB_INVALID_PROCESS_ID; 339 340 // Log it. 341 log->Printf ("NativeThreadLinux: thread (pid=%" PRIu64 ", tid=%" PRIu64 ") changing from state %s to %s", pid, GetID (), StateAsCString (old_state), StateAsCString (new_state)); 342 } 343 344 uint32_t 345 NativeThreadLinux::TranslateStopInfoToGdbSignal (const ThreadStopInfo &stop_info) const 346 { 347 switch (stop_info.reason) 348 { 349 case eStopReasonSignal: 350 // No translation. 351 return stop_info.details.signal.signo; 352 353 case eStopReasonException: 354 { 355 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 356 // FIXME I think the eStopReasonException is a xnu/Mach exception, which we 357 // shouldn't see on Linux. 358 // No translation. 359 if (log) 360 log->Printf ("NativeThreadLinux::%s saw an exception stop type (signo %" 361 PRIu64 "), not expecting to see exceptions on Linux", 362 __FUNCTION__, 363 stop_info.details.exception.type); 364 return static_cast<uint32_t> (stop_info.details.exception.type); 365 } 366 367 default: 368 assert (0 && "unexpected stop_info.reason found"); 369 return 0; 370 } 371 } 372 373