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