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