1af245d11STodd Fiala //===-- NativeThreadLinux.cpp --------------------------------- -*- C++ -*-===//
2af245d11STodd Fiala //
3af245d11STodd Fiala //                     The LLVM Compiler Infrastructure
4af245d11STodd Fiala //
5af245d11STodd Fiala // This file is distributed under the University of Illinois Open Source
6af245d11STodd Fiala // License. See LICENSE.TXT for details.
7af245d11STodd Fiala //
8af245d11STodd Fiala //===----------------------------------------------------------------------===//
9af245d11STodd Fiala 
10af245d11STodd Fiala #include "NativeThreadLinux.h"
11af245d11STodd Fiala 
12af245d11STodd Fiala #include <signal.h>
1318fe6404SChaoren Lin #include <sstream>
14af245d11STodd Fiala 
15af245d11STodd Fiala #include "NativeProcessLinux.h"
160f4b17d1SPavel Labath #include "NativeRegisterContextLinux.h"
17*605b51b8SPavel Labath #include "SingleStepCheck.h"
182850b1beSTodd Fiala 
19af245d11STodd Fiala #include "lldb/Core/Log.h"
20af245d11STodd Fiala #include "lldb/Core/State.h"
2139de3110SZachary Turner #include "lldb/Host/HostNativeThread.h"
22*605b51b8SPavel Labath #include "lldb/Host/linux/Ptrace.h"
23c16f5dcaSChaoren Lin #include "lldb/Utility/LLDBAssert.h"
24af245d11STodd Fiala #include "lldb/lldb-enumerations.h"
2539de3110SZachary Turner 
2639de3110SZachary Turner #include "llvm/ADT/SmallString.h"
2739de3110SZachary Turner 
2828e57429SChaoren Lin #include "Plugins/Process/POSIX/CrashReason.h"
2928e57429SChaoren Lin 
308c8ff7afSPavel Labath #include <sys/syscall.h>
318c8ff7afSPavel Labath // Try to define a macro to encapsulate the tgkill syscall
328c8ff7afSPavel Labath #define tgkill(pid, tid, sig) \
338c8ff7afSPavel Labath     syscall(SYS_tgkill, static_cast< ::pid_t>(pid), static_cast< ::pid_t>(tid), sig)
348c8ff7afSPavel Labath 
35af245d11STodd Fiala using namespace lldb;
36af245d11STodd Fiala using namespace lldb_private;
37db264a6dSTamas Berghammer using namespace lldb_private::process_linux;
38af245d11STodd Fiala 
39af245d11STodd Fiala namespace
40af245d11STodd Fiala {
41af245d11STodd Fiala     void LogThreadStopInfo (Log &log, const ThreadStopInfo &stop_info, const char *const header)
42af245d11STodd Fiala     {
43af245d11STodd Fiala         switch (stop_info.reason)
44af245d11STodd Fiala         {
4512fd3756SPavel Labath             case eStopReasonNone:
4612fd3756SPavel Labath                 log.Printf ("%s: %s no stop reason", __FUNCTION__, header);
4712fd3756SPavel Labath                 return;
4812fd3756SPavel Labath             case eStopReasonTrace:
4912fd3756SPavel Labath                 log.Printf ("%s: %s trace, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
5012fd3756SPavel Labath                 return;
5112fd3756SPavel Labath             case eStopReasonBreakpoint:
5212fd3756SPavel Labath                 log.Printf ("%s: %s breakpoint, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
5312fd3756SPavel Labath                 return;
5412fd3756SPavel Labath             case eStopReasonWatchpoint:
5512fd3756SPavel Labath                 log.Printf ("%s: %s watchpoint, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
5612fd3756SPavel Labath                 return;
57af245d11STodd Fiala             case eStopReasonSignal:
58ae29d395SChaoren Lin                 log.Printf ("%s: %s signal 0x%02" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
59af245d11STodd Fiala                 return;
60af245d11STodd Fiala             case eStopReasonException:
61ae29d395SChaoren Lin                 log.Printf ("%s: %s exception type 0x%02" PRIx64, __FUNCTION__, header, stop_info.details.exception.type);
62a9882ceeSTodd Fiala                 return;
63a9882ceeSTodd Fiala             case eStopReasonExec:
64a9882ceeSTodd Fiala                 log.Printf ("%s: %s exec, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
65af245d11STodd Fiala                 return;
6612fd3756SPavel Labath             case eStopReasonPlanComplete:
6712fd3756SPavel Labath                 log.Printf ("%s: %s plan complete", __FUNCTION__, header);
6812fd3756SPavel Labath                 return;
6912fd3756SPavel Labath             case eStopReasonThreadExiting:
7012fd3756SPavel Labath                 log.Printf ("%s: %s thread exiting", __FUNCTION__, header);
7112fd3756SPavel Labath                 return;
7212fd3756SPavel Labath             case eStopReasonInstrumentation:
7312fd3756SPavel Labath                 log.Printf ("%s: %s instrumentation", __FUNCTION__, header);
7412fd3756SPavel Labath                 return;
75af245d11STodd Fiala             default:
76a9882ceeSTodd Fiala                 log.Printf ("%s: %s invalid stop reason %" PRIu32, __FUNCTION__, header, static_cast<uint32_t> (stop_info.reason));
77af245d11STodd Fiala         }
78af245d11STodd Fiala     }
79af245d11STodd Fiala }
80af245d11STodd Fiala 
81af245d11STodd Fiala NativeThreadLinux::NativeThreadLinux (NativeProcessLinux *process, lldb::tid_t tid) :
82af245d11STodd Fiala     NativeThreadProtocol (process, tid),
83af245d11STodd Fiala     m_state (StateType::eStateInvalid),
84af245d11STodd Fiala     m_stop_info (),
8528e57429SChaoren Lin     m_reg_context_sp (),
8628e57429SChaoren Lin     m_stop_description ()
87af245d11STodd Fiala {
88af245d11STodd Fiala }
89af245d11STodd Fiala 
907206c6d1STodd Fiala std::string
91af245d11STodd Fiala NativeThreadLinux::GetName()
92af245d11STodd Fiala {
93af245d11STodd Fiala     NativeProcessProtocolSP process_sp = m_process_wp.lock ();
94af245d11STodd Fiala     if (!process_sp)
95af245d11STodd Fiala         return "<unknown: no process>";
96af245d11STodd Fiala 
97af245d11STodd Fiala     // const NativeProcessLinux *const process = reinterpret_cast<NativeProcessLinux*> (process_sp->get ());
9839de3110SZachary Turner     llvm::SmallString<32> thread_name;
9939de3110SZachary Turner     HostNativeThread::GetName(GetID(), thread_name);
10039de3110SZachary Turner     return thread_name.c_str();
101af245d11STodd Fiala }
102af245d11STodd Fiala 
103af245d11STodd Fiala lldb::StateType
104af245d11STodd Fiala NativeThreadLinux::GetState ()
105af245d11STodd Fiala {
106af245d11STodd Fiala     return m_state;
107af245d11STodd Fiala }
108af245d11STodd Fiala 
109af245d11STodd Fiala 
110af245d11STodd Fiala bool
11128e57429SChaoren Lin NativeThreadLinux::GetStopReason (ThreadStopInfo &stop_info, std::string& description)
112af245d11STodd Fiala {
113af245d11STodd Fiala     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
11428e57429SChaoren Lin 
11528e57429SChaoren Lin     description.clear();
11628e57429SChaoren Lin 
117af245d11STodd Fiala     switch (m_state)
118af245d11STodd Fiala     {
119af245d11STodd Fiala     case eStateStopped:
120af245d11STodd Fiala     case eStateCrashed:
121af245d11STodd Fiala     case eStateExited:
122af245d11STodd Fiala     case eStateSuspended:
123af245d11STodd Fiala     case eStateUnloaded:
124af245d11STodd Fiala         if (log)
125af245d11STodd Fiala             LogThreadStopInfo (*log, m_stop_info, "m_stop_info in thread:");
126af245d11STodd Fiala         stop_info = m_stop_info;
12728e57429SChaoren Lin         description = m_stop_description;
128af245d11STodd Fiala         if (log)
129af245d11STodd Fiala             LogThreadStopInfo (*log, stop_info, "returned stop_info:");
13028e57429SChaoren Lin 
131af245d11STodd Fiala         return true;
132af245d11STodd Fiala 
133af245d11STodd Fiala     case eStateInvalid:
134af245d11STodd Fiala     case eStateConnected:
135af245d11STodd Fiala     case eStateAttaching:
136af245d11STodd Fiala     case eStateLaunching:
137af245d11STodd Fiala     case eStateRunning:
138af245d11STodd Fiala     case eStateStepping:
139af245d11STodd Fiala     case eStateDetached:
140af245d11STodd Fiala         if (log)
141af245d11STodd Fiala         {
142af245d11STodd Fiala             log->Printf ("NativeThreadLinux::%s tid %" PRIu64 " in state %s cannot answer stop reason",
143af245d11STodd Fiala                     __FUNCTION__, GetID (), StateAsCString (m_state));
144af245d11STodd Fiala         }
145af245d11STodd Fiala         return false;
146af245d11STodd Fiala     }
1478faf9370SDavid Majnemer     llvm_unreachable("unhandled StateType!");
148af245d11STodd Fiala }
149af245d11STodd Fiala 
150db264a6dSTamas Berghammer NativeRegisterContextSP
151af245d11STodd Fiala NativeThreadLinux::GetRegisterContext ()
152af245d11STodd Fiala {
153af245d11STodd Fiala     // Return the register context if we already created it.
154af245d11STodd Fiala     if (m_reg_context_sp)
155af245d11STodd Fiala         return m_reg_context_sp;
156af245d11STodd Fiala 
157af245d11STodd Fiala     NativeProcessProtocolSP m_process_sp = m_process_wp.lock ();
158af245d11STodd Fiala     if (!m_process_sp)
159af245d11STodd Fiala         return NativeRegisterContextSP ();
160af245d11STodd Fiala 
161af245d11STodd Fiala     ArchSpec target_arch;
162af245d11STodd Fiala     if (!m_process_sp->GetArchitecture (target_arch))
163af245d11STodd Fiala         return NativeRegisterContextSP ();
164af245d11STodd Fiala 
1653df471c3SMohit K. Bhakkad     const uint32_t concrete_frame_idx = 0;
166068f8a7eSTamas Berghammer     m_reg_context_sp.reset (NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(target_arch,
167068f8a7eSTamas Berghammer                                                                                              *this,
168068f8a7eSTamas Berghammer                                                                                              concrete_frame_idx));
169af245d11STodd Fiala 
170af245d11STodd Fiala     return m_reg_context_sp;
171af245d11STodd Fiala }
172af245d11STodd Fiala 
173af245d11STodd Fiala Error
174af245d11STodd Fiala NativeThreadLinux::SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware)
175af245d11STodd Fiala {
17618fe6404SChaoren Lin     if (!hardware)
177af245d11STodd Fiala         return Error ("not implemented");
178f591f69fSChaoren Lin     if (m_state == eStateLaunching)
179f591f69fSChaoren Lin         return Error ();
18018fe6404SChaoren Lin     Error error = RemoveWatchpoint(addr);
18118fe6404SChaoren Lin     if (error.Fail()) return error;
18218fe6404SChaoren Lin     NativeRegisterContextSP reg_ctx = GetRegisterContext ();
18318fe6404SChaoren Lin     uint32_t wp_index =
18418fe6404SChaoren Lin         reg_ctx->SetHardwareWatchpoint (addr, size, watch_flags);
18518fe6404SChaoren Lin     if (wp_index == LLDB_INVALID_INDEX32)
18618fe6404SChaoren Lin         return Error ("Setting hardware watchpoint failed.");
18718fe6404SChaoren Lin     m_watchpoint_index_map.insert({addr, wp_index});
18818fe6404SChaoren Lin     return Error ();
189af245d11STodd Fiala }
190af245d11STodd Fiala 
191af245d11STodd Fiala Error
192af245d11STodd Fiala NativeThreadLinux::RemoveWatchpoint (lldb::addr_t addr)
193af245d11STodd Fiala {
19418fe6404SChaoren Lin     auto wp = m_watchpoint_index_map.find(addr);
19518fe6404SChaoren Lin     if (wp == m_watchpoint_index_map.end())
19618fe6404SChaoren Lin         return Error ();
19718fe6404SChaoren Lin     uint32_t wp_index = wp->second;
19818fe6404SChaoren Lin     m_watchpoint_index_map.erase(wp);
19918fe6404SChaoren Lin     if (GetRegisterContext()->ClearHardwareWatchpoint(wp_index))
20018fe6404SChaoren Lin         return Error ();
20118fe6404SChaoren Lin     return Error ("Clearing hardware watchpoint failed.");
202af245d11STodd Fiala }
203af245d11STodd Fiala 
204*605b51b8SPavel Labath Error
205*605b51b8SPavel Labath NativeThreadLinux::Resume(uint32_t signo)
206af245d11STodd Fiala {
207af245d11STodd Fiala     const StateType new_state = StateType::eStateRunning;
208af245d11STodd Fiala     MaybeLogStateChange (new_state);
209af245d11STodd Fiala     m_state = new_state;
210af245d11STodd Fiala 
211af245d11STodd Fiala     m_stop_info.reason = StopReason::eStopReasonNone;
21228e57429SChaoren Lin     m_stop_description.clear();
21318fe6404SChaoren Lin 
21418fe6404SChaoren Lin     // If watchpoints have been set, but none on this thread,
21518fe6404SChaoren Lin     // then this is a new thread. So set all existing watchpoints.
21618fe6404SChaoren Lin     if (m_watchpoint_index_map.empty())
21718fe6404SChaoren Lin     {
218*605b51b8SPavel Labath         NativeProcessLinux &process = GetProcess();
219*605b51b8SPavel Labath 
220*605b51b8SPavel Labath         const auto &watchpoint_map = process.GetWatchpointMap();
22118fe6404SChaoren Lin         GetRegisterContext()->ClearAllHardwareWatchpoints();
22218fe6404SChaoren Lin         for (const auto &pair : watchpoint_map)
22318fe6404SChaoren Lin         {
22418fe6404SChaoren Lin             const auto &wp = pair.second;
22518fe6404SChaoren Lin             SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags, wp.m_hardware);
22618fe6404SChaoren Lin         }
22718fe6404SChaoren Lin     }
228*605b51b8SPavel Labath 
229*605b51b8SPavel Labath     intptr_t data = 0;
230*605b51b8SPavel Labath 
231*605b51b8SPavel Labath     if (signo != LLDB_INVALID_SIGNAL_NUMBER)
232*605b51b8SPavel Labath         data = signo;
233*605b51b8SPavel Labath 
234*605b51b8SPavel Labath     return NativeProcessLinux::PtraceWrapper(PTRACE_CONT, GetID(), nullptr, reinterpret_cast<void *>(data));
235*605b51b8SPavel Labath }
236*605b51b8SPavel Labath 
237*605b51b8SPavel Labath void
238*605b51b8SPavel Labath NativeThreadLinux::MaybePrepareSingleStepWorkaround()
239*605b51b8SPavel Labath {
240*605b51b8SPavel Labath     if (!SingleStepWorkaroundNeeded())
241*605b51b8SPavel Labath         return;
242*605b51b8SPavel Labath 
243*605b51b8SPavel Labath     Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
244*605b51b8SPavel Labath 
245*605b51b8SPavel Labath     if (sched_getaffinity(static_cast<::pid_t>(m_tid), sizeof m_original_cpu_set, &m_original_cpu_set) != 0)
246*605b51b8SPavel Labath     {
247*605b51b8SPavel Labath         // This should really not fail. But, just in case...
248*605b51b8SPavel Labath         if (log)
249*605b51b8SPavel Labath         {
250*605b51b8SPavel Labath             Error error(errno, eErrorTypePOSIX);
251*605b51b8SPavel Labath             log->Printf("NativeThreadLinux::%s Unable to get cpu affinity for thread %" PRIx64 ": %s", __FUNCTION__,
252*605b51b8SPavel Labath                         m_tid, error.AsCString());
253*605b51b8SPavel Labath         }
254*605b51b8SPavel Labath         return;
255*605b51b8SPavel Labath     }
256*605b51b8SPavel Labath 
257*605b51b8SPavel Labath     cpu_set_t set;
258*605b51b8SPavel Labath     CPU_ZERO(&set);
259*605b51b8SPavel Labath     CPU_SET(0, &set);
260*605b51b8SPavel Labath     if (sched_setaffinity(static_cast<::pid_t>(m_tid), sizeof set, &set) != 0 && log)
261*605b51b8SPavel Labath     {
262*605b51b8SPavel Labath         // This may fail in very locked down systems, if the thread is not allowed to run on
263*605b51b8SPavel Labath         // cpu 0. If that happens, only thing we can do is it log it and continue...
264*605b51b8SPavel Labath         Error error(errno, eErrorTypePOSIX);
265*605b51b8SPavel Labath         log->Printf("NativeThreadLinux::%s Unable to set cpu affinity for thread %" PRIx64 ": %s", __FUNCTION__, m_tid,
266*605b51b8SPavel Labath                     error.AsCString());
267af245d11STodd Fiala     }
2688bc34f4dSOleksiy Vyalov }
269af245d11STodd Fiala 
270af245d11STodd Fiala void
271*605b51b8SPavel Labath NativeThreadLinux::MaybeCleanupSingleStepWorkaround()
272*605b51b8SPavel Labath {
273*605b51b8SPavel Labath     if (!SingleStepWorkaroundNeeded())
274*605b51b8SPavel Labath         return;
275*605b51b8SPavel Labath 
276*605b51b8SPavel Labath     if (sched_setaffinity(static_cast<::pid_t>(m_tid), sizeof m_original_cpu_set, &m_original_cpu_set) != 0)
277*605b51b8SPavel Labath     {
278*605b51b8SPavel Labath         Error error(errno, eErrorTypePOSIX);
279*605b51b8SPavel Labath         Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
280*605b51b8SPavel Labath         log->Printf("NativeThreadLinux::%s Unable to reset cpu affinity for thread %" PRIx64 ": %s", __FUNCTION__,
281*605b51b8SPavel Labath                     m_tid, error.AsCString());
282*605b51b8SPavel Labath     }
283*605b51b8SPavel Labath }
284*605b51b8SPavel Labath 
285*605b51b8SPavel Labath Error
286*605b51b8SPavel Labath NativeThreadLinux::SingleStep(uint32_t signo)
287af245d11STodd Fiala {
288af245d11STodd Fiala     const StateType new_state = StateType::eStateStepping;
289af245d11STodd Fiala     MaybeLogStateChange (new_state);
290af245d11STodd Fiala     m_state = new_state;
291af245d11STodd Fiala     m_stop_info.reason = StopReason::eStopReasonNone;
292*605b51b8SPavel Labath 
293*605b51b8SPavel Labath     MaybePrepareSingleStepWorkaround();
294*605b51b8SPavel Labath 
295*605b51b8SPavel Labath     intptr_t data = 0;
296*605b51b8SPavel Labath     if (signo != LLDB_INVALID_SIGNAL_NUMBER)
297*605b51b8SPavel Labath         data = signo;
298*605b51b8SPavel Labath 
299*605b51b8SPavel Labath     // If hardware single-stepping is not supported, we just do a continue. The breakpoint on the
300*605b51b8SPavel Labath     // next instruction has been setup in NativeProcessLinux::Resume.
301*605b51b8SPavel Labath     return NativeProcessLinux::PtraceWrapper(GetProcess().SupportHardwareSingleStepping() ? PTRACE_SINGLESTEP
302*605b51b8SPavel Labath                                                                                           : PTRACE_CONT,
303*605b51b8SPavel Labath                                              m_tid, nullptr, reinterpret_cast<void *>(data));
304af245d11STodd Fiala }
305af245d11STodd Fiala 
306af245d11STodd Fiala void
307c4e25c96SPavel Labath NativeThreadLinux::SetStoppedBySignal(uint32_t signo, const siginfo_t *info)
308af245d11STodd Fiala {
309af245d11STodd Fiala     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
310af245d11STodd Fiala     if (log)
311b8af31d4SChaoren Lin         log->Printf ("NativeThreadLinux::%s called with signal 0x%02" PRIx32, __FUNCTION__, signo);
312af245d11STodd Fiala 
313*605b51b8SPavel Labath     SetStopped();
314af245d11STodd Fiala 
315af245d11STodd Fiala     m_stop_info.reason = StopReason::eStopReasonSignal;
316af245d11STodd Fiala     m_stop_info.details.signal.signo = signo;
317c4e25c96SPavel Labath 
318c4e25c96SPavel Labath     m_stop_description.clear();
3193681c5b8SMohit K. Bhakkad     if (info)
3203681c5b8SMohit K. Bhakkad     {
321c4e25c96SPavel Labath         switch (signo)
322c4e25c96SPavel Labath         {
323c4e25c96SPavel Labath         case SIGSEGV:
324c4e25c96SPavel Labath         case SIGBUS:
325c4e25c96SPavel Labath         case SIGFPE:
326c4e25c96SPavel Labath         case SIGILL:
3273681c5b8SMohit K. Bhakkad              //In case of MIPS64 target, SI_KERNEL is generated for invalid 64bit address.
3283681c5b8SMohit K. Bhakkad              const auto reason = (info->si_signo == SIGBUS && info->si_code == SI_KERNEL) ?
3293681c5b8SMohit K. Bhakkad                                   CrashReason::eInvalidAddress : GetCrashReason(*info);
330c4e25c96SPavel Labath              m_stop_description = GetCrashReasonString(reason, reinterpret_cast<uintptr_t>(info->si_addr));
331c4e25c96SPavel Labath              break;
332c4e25c96SPavel Labath         }
333af245d11STodd Fiala     }
3343681c5b8SMohit K. Bhakkad }
335af245d11STodd Fiala 
336511e5cdcSTodd Fiala bool
337511e5cdcSTodd Fiala NativeThreadLinux::IsStopped (int *signo)
338511e5cdcSTodd Fiala {
339511e5cdcSTodd Fiala     if (!StateIsStoppedState (m_state, false))
340511e5cdcSTodd Fiala         return false;
341511e5cdcSTodd Fiala 
342511e5cdcSTodd Fiala     // If we are stopped by a signal, return the signo.
343511e5cdcSTodd Fiala     if (signo &&
344511e5cdcSTodd Fiala         m_state == StateType::eStateStopped &&
345511e5cdcSTodd Fiala         m_stop_info.reason == StopReason::eStopReasonSignal)
346511e5cdcSTodd Fiala     {
347511e5cdcSTodd Fiala         *signo = m_stop_info.details.signal.signo;
348511e5cdcSTodd Fiala     }
349511e5cdcSTodd Fiala 
350511e5cdcSTodd Fiala     // Regardless, we are stopped.
351511e5cdcSTodd Fiala     return true;
352511e5cdcSTodd Fiala }
353511e5cdcSTodd Fiala 
354*605b51b8SPavel Labath void
355*605b51b8SPavel Labath NativeThreadLinux::SetStopped()
356*605b51b8SPavel Labath {
357*605b51b8SPavel Labath     if (m_state == StateType::eStateStepping)
358*605b51b8SPavel Labath         MaybeCleanupSingleStepWorkaround();
359*605b51b8SPavel Labath 
360*605b51b8SPavel Labath     const StateType new_state = StateType::eStateStopped;
361*605b51b8SPavel Labath     MaybeLogStateChange(new_state);
362*605b51b8SPavel Labath     m_state = new_state;
363*605b51b8SPavel Labath     m_stop_description.clear();
364*605b51b8SPavel Labath }
365511e5cdcSTodd Fiala 
366af245d11STodd Fiala void
367a9882ceeSTodd Fiala NativeThreadLinux::SetStoppedByExec ()
368a9882ceeSTodd Fiala {
369a9882ceeSTodd Fiala     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
370a9882ceeSTodd Fiala     if (log)
371a9882ceeSTodd Fiala         log->Printf ("NativeThreadLinux::%s()", __FUNCTION__);
372a9882ceeSTodd Fiala 
373*605b51b8SPavel Labath     SetStopped();
374a9882ceeSTodd Fiala 
375a9882ceeSTodd Fiala     m_stop_info.reason = StopReason::eStopReasonExec;
376a9882ceeSTodd Fiala     m_stop_info.details.signal.signo = SIGSTOP;
377a9882ceeSTodd Fiala }
378a9882ceeSTodd Fiala 
379a9882ceeSTodd Fiala void
380af245d11STodd Fiala NativeThreadLinux::SetStoppedByBreakpoint ()
381af245d11STodd Fiala {
382*605b51b8SPavel Labath     SetStopped();
383af245d11STodd Fiala 
38428e57429SChaoren Lin     m_stop_info.reason = StopReason::eStopReasonBreakpoint;
385af245d11STodd Fiala     m_stop_info.details.signal.signo = SIGTRAP;
38618fe6404SChaoren Lin     m_stop_description.clear();
38718fe6404SChaoren Lin }
38818fe6404SChaoren Lin 
38918fe6404SChaoren Lin void
390c16f5dcaSChaoren Lin NativeThreadLinux::SetStoppedByWatchpoint (uint32_t wp_index)
39118fe6404SChaoren Lin {
392*605b51b8SPavel Labath     SetStopped();
393c16f5dcaSChaoren Lin 
394c16f5dcaSChaoren Lin     lldbassert(wp_index != LLDB_INVALID_INDEX32 &&
395c16f5dcaSChaoren Lin                "wp_index cannot be invalid");
396eadb2a9eSTamas Berghammer 
39718fe6404SChaoren Lin     std::ostringstream ostr;
398c16f5dcaSChaoren Lin     ostr << GetRegisterContext()->GetWatchpointAddress(wp_index) << " ";
399c16f5dcaSChaoren Lin     ostr << wp_index;
40083143504SJaydeep Patil 
40183143504SJaydeep Patil     /*
40283143504SJaydeep Patil      * MIPS: Last 3bits of the watchpoint address are masked by the kernel. For example:
40383143504SJaydeep Patil      * 'n' is at 0x120010d00 and 'm' is 0x120010d04. When a watchpoint is set at 'm', then
40483143504SJaydeep Patil      * watch exception is generated even when 'n' is read/written. To handle this case,
40583143504SJaydeep Patil      * find the base address of the load/store instruction and append it in the stop-info
40683143504SJaydeep Patil      * packet.
40783143504SJaydeep Patil     */
40883143504SJaydeep Patil     ostr << " " << GetRegisterContext()->GetWatchpointHitAddress(wp_index);
40983143504SJaydeep Patil 
41018fe6404SChaoren Lin     m_stop_description = ostr.str();
411eadb2a9eSTamas Berghammer 
412eadb2a9eSTamas Berghammer     m_stop_info.reason = StopReason::eStopReasonWatchpoint;
413eadb2a9eSTamas Berghammer     m_stop_info.details.signal.signo = SIGTRAP;
414af245d11STodd Fiala }
415af245d11STodd Fiala 
416af245d11STodd Fiala bool
417af245d11STodd Fiala NativeThreadLinux::IsStoppedAtBreakpoint ()
418af245d11STodd Fiala {
41918fe6404SChaoren Lin     return GetState () == StateType::eStateStopped &&
42018fe6404SChaoren Lin         m_stop_info.reason == StopReason::eStopReasonBreakpoint;
42118fe6404SChaoren Lin }
422af245d11STodd Fiala 
42318fe6404SChaoren Lin bool
42418fe6404SChaoren Lin NativeThreadLinux::IsStoppedAtWatchpoint ()
42518fe6404SChaoren Lin {
42618fe6404SChaoren Lin     return GetState () == StateType::eStateStopped &&
42718fe6404SChaoren Lin         m_stop_info.reason == StopReason::eStopReasonWatchpoint;
428af245d11STodd Fiala }
429af245d11STodd Fiala 
430af245d11STodd Fiala void
43128e57429SChaoren Lin NativeThreadLinux::SetStoppedByTrace ()
43228e57429SChaoren Lin {
433*605b51b8SPavel Labath     SetStopped();
43428e57429SChaoren Lin 
43528e57429SChaoren Lin     m_stop_info.reason = StopReason::eStopReasonTrace;
43628e57429SChaoren Lin     m_stop_info.details.signal.signo = SIGTRAP;
43728e57429SChaoren Lin }
43828e57429SChaoren Lin 
43928e57429SChaoren Lin void
44005569f67SPavel Labath NativeThreadLinux::SetStoppedWithNoReason ()
441af245d11STodd Fiala {
442*605b51b8SPavel Labath     SetStopped();
443af245d11STodd Fiala 
444af245d11STodd Fiala     m_stop_info.reason = StopReason::eStopReasonNone;
44505569f67SPavel Labath     m_stop_info.details.signal.signo = 0;
446af245d11STodd Fiala }
447af245d11STodd Fiala 
448af245d11STodd Fiala void
449af245d11STodd Fiala NativeThreadLinux::SetExited ()
450af245d11STodd Fiala {
451af245d11STodd Fiala     const StateType new_state = StateType::eStateExited;
452af245d11STodd Fiala     MaybeLogStateChange (new_state);
453af245d11STodd Fiala     m_state = new_state;
454af245d11STodd Fiala 
455af245d11STodd Fiala     m_stop_info.reason = StopReason::eStopReasonThreadExiting;
456af245d11STodd Fiala }
457af245d11STodd Fiala 
4588c8ff7afSPavel Labath Error
4598c8ff7afSPavel Labath NativeThreadLinux::RequestStop ()
4608c8ff7afSPavel Labath {
4618c8ff7afSPavel Labath     Log* log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
4628c8ff7afSPavel Labath 
463*605b51b8SPavel Labath     NativeProcessLinux &process = GetProcess();
4648c8ff7afSPavel Labath 
465*605b51b8SPavel Labath     lldb::pid_t pid = process.GetID();
4668c8ff7afSPavel Labath     lldb::tid_t tid = GetID();
4678c8ff7afSPavel Labath 
4688c8ff7afSPavel Labath     if (log)
4698c8ff7afSPavel Labath         log->Printf ("NativeThreadLinux::%s requesting thread stop(pid: %" PRIu64 ", tid: %" PRIu64 ")", __FUNCTION__, pid, tid);
4708c8ff7afSPavel Labath 
4718c8ff7afSPavel Labath     Error err;
4728c8ff7afSPavel Labath     errno = 0;
4738c8ff7afSPavel Labath     if (::tgkill (pid, tid, SIGSTOP) != 0)
4748c8ff7afSPavel Labath     {
4758c8ff7afSPavel Labath         err.SetErrorToErrno ();
4768c8ff7afSPavel Labath         if (log)
4778c8ff7afSPavel Labath             log->Printf ("NativeThreadLinux::%s tgkill(%" PRIu64 ", %" PRIu64 ", SIGSTOP) failed: %s", __FUNCTION__, pid, tid, err.AsCString ());
4788c8ff7afSPavel Labath     }
4798c8ff7afSPavel Labath 
4808c8ff7afSPavel Labath     return err;
4818c8ff7afSPavel Labath }
4828c8ff7afSPavel Labath 
483af245d11STodd Fiala void
484af245d11STodd Fiala NativeThreadLinux::MaybeLogStateChange (lldb::StateType new_state)
485af245d11STodd Fiala {
486af245d11STodd Fiala     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
487af245d11STodd Fiala     // If we're not logging, we're done.
488af245d11STodd Fiala     if (!log)
489af245d11STodd Fiala         return;
490af245d11STodd Fiala 
491af245d11STodd Fiala     // If this is a state change to the same state, we're done.
492af245d11STodd Fiala     lldb::StateType old_state = m_state;
493af245d11STodd Fiala     if (new_state == old_state)
494af245d11STodd Fiala         return;
495af245d11STodd Fiala 
496af245d11STodd Fiala     NativeProcessProtocolSP m_process_sp = m_process_wp.lock ();
497af245d11STodd Fiala     lldb::pid_t pid = m_process_sp ? m_process_sp->GetID () : LLDB_INVALID_PROCESS_ID;
498af245d11STodd Fiala 
499af245d11STodd Fiala     // Log it.
500af245d11STodd Fiala     log->Printf ("NativeThreadLinux: thread (pid=%" PRIu64 ", tid=%" PRIu64 ") changing from state %s to %s", pid, GetID (), StateAsCString (old_state), StateAsCString (new_state));
501af245d11STodd Fiala }
502*605b51b8SPavel Labath 
503*605b51b8SPavel Labath NativeProcessLinux &
504*605b51b8SPavel Labath NativeThreadLinux::GetProcess()
505*605b51b8SPavel Labath {
506*605b51b8SPavel Labath     auto process_sp = std::static_pointer_cast<NativeProcessLinux>(NativeThreadProtocol::GetProcess());
507*605b51b8SPavel Labath     assert(process_sp);
508*605b51b8SPavel Labath     return *process_sp;
509*605b51b8SPavel Labath }
510