xref: /llvm-project/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp (revision 831435042e887d35876eba411a07082eb6f6a246)
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         description = m_stop_description;
129         if (log)
130             LogThreadStopInfo (*log, stop_info, "returned stop_info:");
131 
132         return true;
133 
134     case eStateInvalid:
135     case eStateConnected:
136     case eStateAttaching:
137     case eStateLaunching:
138     case eStateRunning:
139     case eStateStepping:
140     case eStateDetached:
141         if (log)
142         {
143             log->Printf ("NativeThreadLinux::%s tid %" PRIu64 " in state %s cannot answer stop reason",
144                     __FUNCTION__, GetID (), StateAsCString (m_state));
145         }
146         return false;
147     }
148     llvm_unreachable("unhandled StateType!");
149 }
150 
151 NativeRegisterContextSP
152 NativeThreadLinux::GetRegisterContext ()
153 {
154     // Return the register context if we already created it.
155     if (m_reg_context_sp)
156         return m_reg_context_sp;
157 
158     NativeProcessProtocolSP m_process_sp = m_process_wp.lock ();
159     if (!m_process_sp)
160         return NativeRegisterContextSP ();
161 
162     ArchSpec target_arch;
163     if (!m_process_sp->GetArchitecture (target_arch))
164         return NativeRegisterContextSP ();
165 
166     const uint32_t concrete_frame_idx = 0;
167     m_reg_context_sp.reset (NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(target_arch,
168                                                                                              *this,
169                                                                                              concrete_frame_idx));
170 
171     return m_reg_context_sp;
172 }
173 
174 Error
175 NativeThreadLinux::SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware)
176 {
177     if (!hardware)
178         return Error ("not implemented");
179     if (m_state == eStateLaunching)
180         return Error ();
181     Error error = RemoveWatchpoint(addr);
182     if (error.Fail()) return error;
183     NativeRegisterContextSP reg_ctx = GetRegisterContext ();
184     uint32_t wp_index =
185         reg_ctx->SetHardwareWatchpoint (addr, size, watch_flags);
186     if (wp_index == LLDB_INVALID_INDEX32)
187         return Error ("Setting hardware watchpoint failed.");
188     m_watchpoint_index_map.insert({addr, wp_index});
189     return Error ();
190 }
191 
192 Error
193 NativeThreadLinux::RemoveWatchpoint (lldb::addr_t addr)
194 {
195     auto wp = m_watchpoint_index_map.find(addr);
196     if (wp == m_watchpoint_index_map.end())
197         return Error ();
198     uint32_t wp_index = wp->second;
199     m_watchpoint_index_map.erase(wp);
200     if (GetRegisterContext()->ClearHardwareWatchpoint(wp_index))
201         return Error ();
202     return Error ("Clearing hardware watchpoint failed.");
203 }
204 
205 void
206 NativeThreadLinux::SetRunning ()
207 {
208     const StateType new_state = StateType::eStateRunning;
209     MaybeLogStateChange (new_state);
210     m_state = new_state;
211 
212     m_stop_info.reason = StopReason::eStopReasonNone;
213     m_stop_description.clear();
214 
215     // If watchpoints have been set, but none on this thread,
216     // then this is a new thread. So set all existing watchpoints.
217     if (m_watchpoint_index_map.empty())
218     {
219         const auto process_sp = GetProcess();
220         if (process_sp)
221         {
222             const auto &watchpoint_map = process_sp->GetWatchpointMap();
223             if (watchpoint_map.empty()) return;
224             GetRegisterContext()->ClearAllHardwareWatchpoints();
225             for (const auto &pair : watchpoint_map)
226             {
227                 const auto& wp = pair.second;
228                 SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags, wp.m_hardware);
229             }
230         }
231     }
232 }
233 
234 void
235 NativeThreadLinux::SetStepping ()
236 {
237     const StateType new_state = StateType::eStateStepping;
238     MaybeLogStateChange (new_state);
239     m_state = new_state;
240 
241     m_stop_info.reason = StopReason::eStopReasonNone;
242 }
243 
244 void
245 NativeThreadLinux::SetStoppedBySignal(uint32_t signo, const siginfo_t *info)
246 {
247     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
248     if (log)
249         log->Printf ("NativeThreadLinux::%s called with signal 0x%02" PRIx32, __FUNCTION__, signo);
250 
251     const StateType new_state = StateType::eStateStopped;
252     MaybeLogStateChange (new_state);
253     m_state = new_state;
254 
255     m_stop_info.reason = StopReason::eStopReasonSignal;
256     m_stop_info.details.signal.signo = signo;
257 
258     m_stop_description.clear();
259     if (info)
260     {
261         switch (signo)
262         {
263         case SIGSEGV:
264         case SIGBUS:
265         case SIGFPE:
266         case SIGILL:
267              //In case of MIPS64 target, SI_KERNEL is generated for invalid 64bit address.
268              const auto reason = (info->si_signo == SIGBUS && info->si_code == SI_KERNEL) ?
269                                   CrashReason::eInvalidAddress : GetCrashReason(*info);
270              m_stop_description = GetCrashReasonString(reason, reinterpret_cast<uintptr_t>(info->si_addr));
271              break;
272         }
273     }
274 }
275 
276 bool
277 NativeThreadLinux::IsStopped (int *signo)
278 {
279     if (!StateIsStoppedState (m_state, false))
280         return false;
281 
282     // If we are stopped by a signal, return the signo.
283     if (signo &&
284         m_state == StateType::eStateStopped &&
285         m_stop_info.reason == StopReason::eStopReasonSignal)
286     {
287         *signo = m_stop_info.details.signal.signo;
288     }
289 
290     // Regardless, we are stopped.
291     return true;
292 }
293 
294 
295 void
296 NativeThreadLinux::SetStoppedByExec ()
297 {
298     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
299     if (log)
300         log->Printf ("NativeThreadLinux::%s()", __FUNCTION__);
301 
302     const StateType new_state = StateType::eStateStopped;
303     MaybeLogStateChange (new_state);
304     m_state = new_state;
305 
306     m_stop_info.reason = StopReason::eStopReasonExec;
307     m_stop_info.details.signal.signo = SIGSTOP;
308 }
309 
310 void
311 NativeThreadLinux::SetStoppedByBreakpoint ()
312 {
313     const StateType new_state = StateType::eStateStopped;
314     MaybeLogStateChange (new_state);
315     m_state = new_state;
316 
317     m_stop_info.reason = StopReason::eStopReasonBreakpoint;
318     m_stop_info.details.signal.signo = SIGTRAP;
319     m_stop_description.clear();
320 }
321 
322 void
323 NativeThreadLinux::SetStoppedByWatchpoint (uint32_t wp_index)
324 {
325     const StateType new_state = StateType::eStateStopped;
326     MaybeLogStateChange (new_state);
327     m_state = new_state;
328     m_stop_description.clear ();
329 
330     lldbassert(wp_index != LLDB_INVALID_INDEX32 &&
331                "wp_index cannot be invalid");
332 
333     std::ostringstream ostr;
334     ostr << GetRegisterContext()->GetWatchpointAddress(wp_index) << " ";
335     ostr << wp_index;
336 
337     /*
338      * MIPS: Last 3bits of the watchpoint address are masked by the kernel. For example:
339      * 'n' is at 0x120010d00 and 'm' is 0x120010d04. When a watchpoint is set at 'm', then
340      * watch exception is generated even when 'n' is read/written. To handle this case,
341      * find the base address of the load/store instruction and append it in the stop-info
342      * packet.
343     */
344     ostr << " " << GetRegisterContext()->GetWatchpointHitAddress(wp_index);
345 
346     m_stop_description = ostr.str();
347 
348     m_stop_info.reason = StopReason::eStopReasonWatchpoint;
349     m_stop_info.details.signal.signo = SIGTRAP;
350 }
351 
352 bool
353 NativeThreadLinux::IsStoppedAtBreakpoint ()
354 {
355     return GetState () == StateType::eStateStopped &&
356         m_stop_info.reason == StopReason::eStopReasonBreakpoint;
357 }
358 
359 bool
360 NativeThreadLinux::IsStoppedAtWatchpoint ()
361 {
362     return GetState () == StateType::eStateStopped &&
363         m_stop_info.reason == StopReason::eStopReasonWatchpoint;
364 }
365 
366 void
367 NativeThreadLinux::SetStoppedByTrace ()
368 {
369     const StateType new_state = StateType::eStateStopped;
370     MaybeLogStateChange (new_state);
371     m_state = new_state;
372 
373     m_stop_info.reason = StopReason::eStopReasonTrace;
374     m_stop_info.details.signal.signo = SIGTRAP;
375 }
376 
377 void
378 NativeThreadLinux::SetStoppedWithNoReason ()
379 {
380     const StateType new_state = StateType::eStateStopped;
381     MaybeLogStateChange (new_state);
382     m_state = new_state;
383 
384     m_stop_info.reason = StopReason::eStopReasonNone;
385     m_stop_info.details.signal.signo = 0;
386 }
387 
388 void
389 NativeThreadLinux::SetExited ()
390 {
391     const StateType new_state = StateType::eStateExited;
392     MaybeLogStateChange (new_state);
393     m_state = new_state;
394 
395     m_stop_info.reason = StopReason::eStopReasonThreadExiting;
396 }
397 
398 Error
399 NativeThreadLinux::RequestStop ()
400 {
401     Log* log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
402 
403     const auto process_sp = GetProcess();
404     if (! process_sp)
405         return Error("Process is null.");
406 
407     lldb::pid_t pid = process_sp->GetID();
408     lldb::tid_t tid = GetID();
409 
410     if (log)
411         log->Printf ("NativeThreadLinux::%s requesting thread stop(pid: %" PRIu64 ", tid: %" PRIu64 ")", __FUNCTION__, pid, tid);
412 
413     Error err;
414     errno = 0;
415     if (::tgkill (pid, tid, SIGSTOP) != 0)
416     {
417         err.SetErrorToErrno ();
418         if (log)
419             log->Printf ("NativeThreadLinux::%s tgkill(%" PRIu64 ", %" PRIu64 ", SIGSTOP) failed: %s", __FUNCTION__, pid, tid, err.AsCString ());
420     }
421     else
422         m_thread_context.stop_requested = true;
423 
424     return err;
425 }
426 
427 void
428 NativeThreadLinux::MaybeLogStateChange (lldb::StateType new_state)
429 {
430     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
431     // If we're not logging, we're done.
432     if (!log)
433         return;
434 
435     // If this is a state change to the same state, we're done.
436     lldb::StateType old_state = m_state;
437     if (new_state == old_state)
438         return;
439 
440     NativeProcessProtocolSP m_process_sp = m_process_wp.lock ();
441     lldb::pid_t pid = m_process_sp ? m_process_sp->GetID () : LLDB_INVALID_PROCESS_ID;
442 
443     // Log it.
444     log->Printf ("NativeThreadLinux: thread (pid=%" PRIu64 ", tid=%" PRIu64 ") changing from state %s to %s", pid, GetID (), StateAsCString (old_state), StateAsCString (new_state));
445 }
446