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