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