blob: 070b1bcda3b8751eaaad29fa8b2302e9ce4a5865 [file] [log] [blame]
Todd Fialaaf245d12014-06-30 21:05:18 +00001//===-- 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>
Chaoren Lin18fe6402015-02-03 01:51:47 +000013#include <sstream>
Todd Fialaaf245d12014-06-30 21:05:18 +000014
15#include "NativeProcessLinux.h"
Pavel Labath0f4b17d2015-08-24 13:25:54 +000016#include "NativeRegisterContextLinux.h"
Pavel Labath605b51b2016-02-23 13:56:30 +000017#include "SingleStepCheck.h"
Todd Fiala2850b1b2014-06-30 23:51:35 +000018
Todd Fialaaf245d12014-06-30 21:05:18 +000019#include "lldb/Core/Log.h"
20#include "lldb/Core/State.h"
Zachary Turner39de3112014-09-09 20:54:56 +000021#include "lldb/Host/HostNativeThread.h"
Pavel Labath605b51b2016-02-23 13:56:30 +000022#include "lldb/Host/linux/Ptrace.h"
Chaoren Linc16f5dc2015-03-19 23:28:10 +000023#include "lldb/Utility/LLDBAssert.h"
Todd Fialaaf245d12014-06-30 21:05:18 +000024#include "lldb/lldb-enumerations.h"
Zachary Turner39de3112014-09-09 20:54:56 +000025
26#include "llvm/ADT/SmallString.h"
27
Chaoren Lin28e57422015-02-03 01:51:25 +000028#include "Plugins/Process/POSIX/CrashReason.h"
29
Pavel Labath8c8ff7a2015-05-11 10:03:10 +000030#include <sys/syscall.h>
31// Try to define a macro to encapsulate the tgkill syscall
32#define tgkill(pid, tid, sig) \
Omair Javaid20405482015-08-09 19:04:41 +000033 syscall(SYS_tgkill, static_cast< ::pid_t>(pid), static_cast< ::pid_t>(tid), sig)
Pavel Labath8c8ff7a2015-05-11 10:03:10 +000034
Todd Fialaaf245d12014-06-30 21:05:18 +000035using namespace lldb;
36using namespace lldb_private;
Tamas Berghammerdb264a62015-03-31 09:52:22 +000037using namespace lldb_private::process_linux;
Todd Fialaaf245d12014-06-30 21:05:18 +000038
39namespace
40{
41 void LogThreadStopInfo (Log &log, const ThreadStopInfo &stop_info, const char *const header)
42 {
43 switch (stop_info.reason)
44 {
Pavel Labath12fd3752015-03-20 14:45:13 +000045 case eStopReasonNone:
46 log.Printf ("%s: %s no stop reason", __FUNCTION__, header);
47 return;
48 case eStopReasonTrace:
49 log.Printf ("%s: %s trace, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
50 return;
51 case eStopReasonBreakpoint:
52 log.Printf ("%s: %s breakpoint, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
53 return;
54 case eStopReasonWatchpoint:
55 log.Printf ("%s: %s watchpoint, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
56 return;
Todd Fialaaf245d12014-06-30 21:05:18 +000057 case eStopReasonSignal:
Chaoren Linae29d392015-02-03 01:50:46 +000058 log.Printf ("%s: %s signal 0x%02" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
Todd Fialaaf245d12014-06-30 21:05:18 +000059 return;
60 case eStopReasonException:
Chaoren Linae29d392015-02-03 01:50:46 +000061 log.Printf ("%s: %s exception type 0x%02" PRIx64, __FUNCTION__, header, stop_info.details.exception.type);
Todd Fialaa9882ce2014-08-28 15:46:54 +000062 return;
63 case eStopReasonExec:
64 log.Printf ("%s: %s exec, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
Todd Fialaaf245d12014-06-30 21:05:18 +000065 return;
Pavel Labath12fd3752015-03-20 14:45:13 +000066 case eStopReasonPlanComplete:
67 log.Printf ("%s: %s plan complete", __FUNCTION__, header);
68 return;
69 case eStopReasonThreadExiting:
70 log.Printf ("%s: %s thread exiting", __FUNCTION__, header);
71 return;
72 case eStopReasonInstrumentation:
73 log.Printf ("%s: %s instrumentation", __FUNCTION__, header);
74 return;
Todd Fialaaf245d12014-06-30 21:05:18 +000075 default:
Todd Fialaa9882ce2014-08-28 15:46:54 +000076 log.Printf ("%s: %s invalid stop reason %" PRIu32, __FUNCTION__, header, static_cast<uint32_t> (stop_info.reason));
Todd Fialaaf245d12014-06-30 21:05:18 +000077 }
78 }
79}
80
81NativeThreadLinux::NativeThreadLinux (NativeProcessLinux *process, lldb::tid_t tid) :
82 NativeThreadProtocol (process, tid),
83 m_state (StateType::eStateInvalid),
84 m_stop_info (),
Chaoren Lin28e57422015-02-03 01:51:25 +000085 m_reg_context_sp (),
86 m_stop_description ()
Todd Fialaaf245d12014-06-30 21:05:18 +000087{
88}
89
Todd Fiala7206c6d2014-09-12 22:51:49 +000090std::string
Todd Fialaaf245d12014-06-30 21:05:18 +000091NativeThreadLinux::GetName()
92{
93 NativeProcessProtocolSP process_sp = m_process_wp.lock ();
94 if (!process_sp)
95 return "<unknown: no process>";
96
97 // const NativeProcessLinux *const process = reinterpret_cast<NativeProcessLinux*> (process_sp->get ());
Zachary Turner39de3112014-09-09 20:54:56 +000098 llvm::SmallString<32> thread_name;
99 HostNativeThread::GetName(GetID(), thread_name);
100 return thread_name.c_str();
Todd Fialaaf245d12014-06-30 21:05:18 +0000101}
102
103lldb::StateType
104NativeThreadLinux::GetState ()
105{
106 return m_state;
107}
108
109
110bool
Chaoren Lin28e57422015-02-03 01:51:25 +0000111NativeThreadLinux::GetStopReason (ThreadStopInfo &stop_info, std::string& description)
Todd Fialaaf245d12014-06-30 21:05:18 +0000112{
113 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
Chaoren Lin28e57422015-02-03 01:51:25 +0000114
115 description.clear();
116
Todd Fialaaf245d12014-06-30 21:05:18 +0000117 switch (m_state)
118 {
119 case eStateStopped:
120 case eStateCrashed:
121 case eStateExited:
122 case eStateSuspended:
123 case eStateUnloaded:
124 if (log)
Todd Fialaa9882ce2014-08-28 15:46:54 +0000125 LogThreadStopInfo (*log, m_stop_info, "m_stop_info in thread:");
Todd Fialaaf245d12014-06-30 21:05:18 +0000126 stop_info = m_stop_info;
Pavel Labathc4e25c92015-05-29 10:13:03 +0000127 description = m_stop_description;
Todd Fialaaf245d12014-06-30 21:05:18 +0000128 if (log)
Todd Fialaa9882ce2014-08-28 15:46:54 +0000129 LogThreadStopInfo (*log, stop_info, "returned stop_info:");
Chaoren Lin28e57422015-02-03 01:51:25 +0000130
Todd Fialaaf245d12014-06-30 21:05:18 +0000131 return true;
132
133 case eStateInvalid:
134 case eStateConnected:
135 case eStateAttaching:
136 case eStateLaunching:
137 case eStateRunning:
138 case eStateStepping:
139 case eStateDetached:
Todd Fialaaf245d12014-06-30 21:05:18 +0000140 if (log)
141 {
142 log->Printf ("NativeThreadLinux::%s tid %" PRIu64 " in state %s cannot answer stop reason",
143 __FUNCTION__, GetID (), StateAsCString (m_state));
144 }
145 return false;
146 }
David Majnemer8faf9372014-09-16 06:34:29 +0000147 llvm_unreachable("unhandled StateType!");
Todd Fialaaf245d12014-06-30 21:05:18 +0000148}
149
Tamas Berghammerdb264a62015-03-31 09:52:22 +0000150NativeRegisterContextSP
Todd Fialaaf245d12014-06-30 21:05:18 +0000151NativeThreadLinux::GetRegisterContext ()
152{
153 // Return the register context if we already created it.
154 if (m_reg_context_sp)
155 return m_reg_context_sp;
156
Todd Fialaaf245d12014-06-30 21:05:18 +0000157 NativeProcessProtocolSP m_process_sp = m_process_wp.lock ();
158 if (!m_process_sp)
159 return NativeRegisterContextSP ();
160
161 ArchSpec target_arch;
162 if (!m_process_sp->GetArchitecture (target_arch))
163 return NativeRegisterContextSP ();
164
Tamas Berghammer068f8a72015-05-26 11:58:52 +0000165 const uint32_t concrete_frame_idx = 0;
166 m_reg_context_sp.reset (NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(target_arch,
167 *this,
168 concrete_frame_idx));
Todd Fialaaf245d12014-06-30 21:05:18 +0000169
170 return m_reg_context_sp;
171}
172
173Error
174NativeThreadLinux::SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware)
175{
Chaoren Lin18fe6402015-02-03 01:51:47 +0000176 if (!hardware)
177 return Error ("not implemented");
Chaoren Linf591f692015-02-26 19:48:15 +0000178 if (m_state == eStateLaunching)
179 return Error ();
Chaoren Lin18fe6402015-02-03 01:51:47 +0000180 Error error = RemoveWatchpoint(addr);
181 if (error.Fail()) return error;
182 NativeRegisterContextSP reg_ctx = GetRegisterContext ();
183 uint32_t wp_index =
184 reg_ctx->SetHardwareWatchpoint (addr, size, watch_flags);
185 if (wp_index == LLDB_INVALID_INDEX32)
186 return Error ("Setting hardware watchpoint failed.");
187 m_watchpoint_index_map.insert({addr, wp_index});
188 return Error ();
Todd Fialaaf245d12014-06-30 21:05:18 +0000189}
190
191Error
192NativeThreadLinux::RemoveWatchpoint (lldb::addr_t addr)
193{
Chaoren Lin18fe6402015-02-03 01:51:47 +0000194 auto wp = m_watchpoint_index_map.find(addr);
195 if (wp == m_watchpoint_index_map.end())
196 return Error ();
197 uint32_t wp_index = wp->second;
198 m_watchpoint_index_map.erase(wp);
199 if (GetRegisterContext()->ClearHardwareWatchpoint(wp_index))
200 return Error ();
201 return Error ("Clearing hardware watchpoint failed.");
Todd Fialaaf245d12014-06-30 21:05:18 +0000202}
203
Pavel Labath605b51b2016-02-23 13:56:30 +0000204Error
205NativeThreadLinux::Resume(uint32_t signo)
Todd Fialaaf245d12014-06-30 21:05:18 +0000206{
207 const StateType new_state = StateType::eStateRunning;
208 MaybeLogStateChange (new_state);
209 m_state = new_state;
210
211 m_stop_info.reason = StopReason::eStopReasonNone;
Chaoren Lin28e57422015-02-03 01:51:25 +0000212 m_stop_description.clear();
Chaoren Lin18fe6402015-02-03 01:51:47 +0000213
214 // If watchpoints have been set, but none on this thread,
215 // then this is a new thread. So set all existing watchpoints.
216 if (m_watchpoint_index_map.empty())
217 {
Pavel Labath605b51b2016-02-23 13:56:30 +0000218 NativeProcessLinux &process = GetProcess();
219
220 const auto &watchpoint_map = process.GetWatchpointMap();
221 GetRegisterContext()->ClearAllHardwareWatchpoints();
222 for (const auto &pair : watchpoint_map)
Chaoren Lin18fe6402015-02-03 01:51:47 +0000223 {
Pavel Labath605b51b2016-02-23 13:56:30 +0000224 const auto &wp = pair.second;
225 SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags, wp.m_hardware);
Chaoren Lin18fe6402015-02-03 01:51:47 +0000226 }
227 }
Pavel Labath605b51b2016-02-23 13:56:30 +0000228
229 intptr_t data = 0;
230
231 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
232 data = signo;
233
234 return NativeProcessLinux::PtraceWrapper(PTRACE_CONT, GetID(), nullptr, reinterpret_cast<void *>(data));
235}
236
237void
238NativeThreadLinux::MaybePrepareSingleStepWorkaround()
239{
240 if (!SingleStepWorkaroundNeeded())
241 return;
242
243 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
244
245 if (sched_getaffinity(static_cast<::pid_t>(m_tid), sizeof m_original_cpu_set, &m_original_cpu_set) != 0)
246 {
247 // This should really not fail. But, just in case...
248 if (log)
249 {
250 Error error(errno, eErrorTypePOSIX);
251 log->Printf("NativeThreadLinux::%s Unable to get cpu affinity for thread %" PRIx64 ": %s", __FUNCTION__,
252 m_tid, error.AsCString());
253 }
254 return;
255 }
256
257 cpu_set_t set;
258 CPU_ZERO(&set);
259 CPU_SET(0, &set);
260 if (sched_setaffinity(static_cast<::pid_t>(m_tid), sizeof set, &set) != 0 && log)
261 {
262 // This may fail in very locked down systems, if the thread is not allowed to run on
263 // cpu 0. If that happens, only thing we can do is it log it and continue...
264 Error error(errno, eErrorTypePOSIX);
265 log->Printf("NativeThreadLinux::%s Unable to set cpu affinity for thread %" PRIx64 ": %s", __FUNCTION__, m_tid,
266 error.AsCString());
267 }
Todd Fialaaf245d12014-06-30 21:05:18 +0000268}
269
270void
Pavel Labath605b51b2016-02-23 13:56:30 +0000271NativeThreadLinux::MaybeCleanupSingleStepWorkaround()
272{
273 if (!SingleStepWorkaroundNeeded())
274 return;
275
276 if (sched_setaffinity(static_cast<::pid_t>(m_tid), sizeof m_original_cpu_set, &m_original_cpu_set) != 0)
277 {
278 Error error(errno, eErrorTypePOSIX);
279 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
280 log->Printf("NativeThreadLinux::%s Unable to reset cpu affinity for thread %" PRIx64 ": %s", __FUNCTION__,
281 m_tid, error.AsCString());
282 }
283}
284
285Error
286NativeThreadLinux::SingleStep(uint32_t signo)
Todd Fialaaf245d12014-06-30 21:05:18 +0000287{
288 const StateType new_state = StateType::eStateStepping;
289 MaybeLogStateChange (new_state);
290 m_state = new_state;
Todd Fialaaf245d12014-06-30 21:05:18 +0000291 m_stop_info.reason = StopReason::eStopReasonNone;
Pavel Labath605b51b2016-02-23 13:56:30 +0000292
293 MaybePrepareSingleStepWorkaround();
294
295 intptr_t data = 0;
296 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
297 data = signo;
298
299 // If hardware single-stepping is not supported, we just do a continue. The breakpoint on the
300 // next instruction has been setup in NativeProcessLinux::Resume.
301 return NativeProcessLinux::PtraceWrapper(GetProcess().SupportHardwareSingleStepping() ? PTRACE_SINGLESTEP
302 : PTRACE_CONT,
303 m_tid, nullptr, reinterpret_cast<void *>(data));
Todd Fialaaf245d12014-06-30 21:05:18 +0000304}
305
306void
Pavel Labathc4e25c92015-05-29 10:13:03 +0000307NativeThreadLinux::SetStoppedBySignal(uint32_t signo, const siginfo_t *info)
Todd Fialaaf245d12014-06-30 21:05:18 +0000308{
309 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
310 if (log)
Chaoren Linb8af31d2015-02-03 01:50:51 +0000311 log->Printf ("NativeThreadLinux::%s called with signal 0x%02" PRIx32, __FUNCTION__, signo);
Todd Fialaaf245d12014-06-30 21:05:18 +0000312
Pavel Labath605b51b2016-02-23 13:56:30 +0000313 SetStopped();
Todd Fialaaf245d12014-06-30 21:05:18 +0000314
315 m_stop_info.reason = StopReason::eStopReasonSignal;
316 m_stop_info.details.signal.signo = signo;
Pavel Labathc4e25c92015-05-29 10:13:03 +0000317
318 m_stop_description.clear();
Mohit K. Bhakkad3681c5b2015-07-30 05:38:11 +0000319 if (info)
Pavel Labathc4e25c92015-05-29 10:13:03 +0000320 {
Mohit K. Bhakkad3681c5b2015-07-30 05:38:11 +0000321 switch (signo)
322 {
323 case SIGSEGV:
324 case SIGBUS:
325 case SIGFPE:
326 case SIGILL:
327 //In case of MIPS64 target, SI_KERNEL is generated for invalid 64bit address.
328 const auto reason = (info->si_signo == SIGBUS && info->si_code == SI_KERNEL) ?
329 CrashReason::eInvalidAddress : GetCrashReason(*info);
330 m_stop_description = GetCrashReasonString(reason, reinterpret_cast<uintptr_t>(info->si_addr));
331 break;
332 }
Pavel Labathc4e25c92015-05-29 10:13:03 +0000333 }
Todd Fialaaf245d12014-06-30 21:05:18 +0000334}
335
Todd Fiala511e5cd2014-09-11 23:29:14 +0000336bool
337NativeThreadLinux::IsStopped (int *signo)
338{
339 if (!StateIsStoppedState (m_state, false))
340 return false;
341
342 // If we are stopped by a signal, return the signo.
343 if (signo &&
344 m_state == StateType::eStateStopped &&
345 m_stop_info.reason == StopReason::eStopReasonSignal)
346 {
347 *signo = m_stop_info.details.signal.signo;
348 }
349
350 // Regardless, we are stopped.
351 return true;
352}
353
Pavel Labath605b51b2016-02-23 13:56:30 +0000354void
355NativeThreadLinux::SetStopped()
356{
357 if (m_state == StateType::eStateStepping)
358 MaybeCleanupSingleStepWorkaround();
359
360 const StateType new_state = StateType::eStateStopped;
361 MaybeLogStateChange(new_state);
362 m_state = new_state;
363 m_stop_description.clear();
364}
Todd Fiala511e5cd2014-09-11 23:29:14 +0000365
Todd Fialaaf245d12014-06-30 21:05:18 +0000366void
Todd Fialaa9882ce2014-08-28 15:46:54 +0000367NativeThreadLinux::SetStoppedByExec ()
368{
369 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
370 if (log)
371 log->Printf ("NativeThreadLinux::%s()", __FUNCTION__);
372
Pavel Labath605b51b2016-02-23 13:56:30 +0000373 SetStopped();
Todd Fialaa9882ce2014-08-28 15:46:54 +0000374
375 m_stop_info.reason = StopReason::eStopReasonExec;
376 m_stop_info.details.signal.signo = SIGSTOP;
377}
378
379void
Todd Fialaaf245d12014-06-30 21:05:18 +0000380NativeThreadLinux::SetStoppedByBreakpoint ()
381{
Pavel Labath605b51b2016-02-23 13:56:30 +0000382 SetStopped();
Todd Fialaaf245d12014-06-30 21:05:18 +0000383
Chaoren Lin28e57422015-02-03 01:51:25 +0000384 m_stop_info.reason = StopReason::eStopReasonBreakpoint;
Todd Fialaaf245d12014-06-30 21:05:18 +0000385 m_stop_info.details.signal.signo = SIGTRAP;
Chaoren Lin18fe6402015-02-03 01:51:47 +0000386 m_stop_description.clear();
387}
388
389void
Chaoren Linc16f5dc2015-03-19 23:28:10 +0000390NativeThreadLinux::SetStoppedByWatchpoint (uint32_t wp_index)
Chaoren Lin18fe6402015-02-03 01:51:47 +0000391{
Pavel Labath605b51b2016-02-23 13:56:30 +0000392 SetStopped();
Tamas Berghammereadb2a92015-03-17 14:40:57 +0000393
Chaoren Linc16f5dc2015-03-19 23:28:10 +0000394 lldbassert(wp_index != LLDB_INVALID_INDEX32 &&
395 "wp_index cannot be invalid");
Tamas Berghammereadb2a92015-03-17 14:40:57 +0000396
Chaoren Linc16f5dc2015-03-19 23:28:10 +0000397 std::ostringstream ostr;
398 ostr << GetRegisterContext()->GetWatchpointAddress(wp_index) << " ";
399 ostr << wp_index;
Jaydeep Patil83143502015-08-13 03:44:09 +0000400
401 /*
402 * MIPS: Last 3bits of the watchpoint address are masked by the kernel. For example:
403 * 'n' is at 0x120010d00 and 'm' is 0x120010d04. When a watchpoint is set at 'm', then
404 * watch exception is generated even when 'n' is read/written. To handle this case,
405 * find the base address of the load/store instruction and append it in the stop-info
406 * packet.
407 */
408 ostr << " " << GetRegisterContext()->GetWatchpointHitAddress(wp_index);
409
Chaoren Linc16f5dc2015-03-19 23:28:10 +0000410 m_stop_description = ostr.str();
Tamas Berghammereadb2a92015-03-17 14:40:57 +0000411
Chaoren Linc16f5dc2015-03-19 23:28:10 +0000412 m_stop_info.reason = StopReason::eStopReasonWatchpoint;
413 m_stop_info.details.signal.signo = SIGTRAP;
Todd Fialaaf245d12014-06-30 21:05:18 +0000414}
415
416bool
417NativeThreadLinux::IsStoppedAtBreakpoint ()
418{
Chaoren Lin18fe6402015-02-03 01:51:47 +0000419 return GetState () == StateType::eStateStopped &&
420 m_stop_info.reason == StopReason::eStopReasonBreakpoint;
421}
Todd Fialaaf245d12014-06-30 21:05:18 +0000422
Chaoren Lin18fe6402015-02-03 01:51:47 +0000423bool
424NativeThreadLinux::IsStoppedAtWatchpoint ()
425{
426 return GetState () == StateType::eStateStopped &&
427 m_stop_info.reason == StopReason::eStopReasonWatchpoint;
Todd Fialaaf245d12014-06-30 21:05:18 +0000428}
429
430void
Chaoren Lin28e57422015-02-03 01:51:25 +0000431NativeThreadLinux::SetStoppedByTrace ()
432{
Pavel Labath605b51b2016-02-23 13:56:30 +0000433 SetStopped();
Chaoren Lin28e57422015-02-03 01:51:25 +0000434
435 m_stop_info.reason = StopReason::eStopReasonTrace;
436 m_stop_info.details.signal.signo = SIGTRAP;
437}
438
439void
Pavel Labath05569f62015-07-23 09:09:29 +0000440NativeThreadLinux::SetStoppedWithNoReason ()
Todd Fialaaf245d12014-06-30 21:05:18 +0000441{
Pavel Labath605b51b2016-02-23 13:56:30 +0000442 SetStopped();
Todd Fialaaf245d12014-06-30 21:05:18 +0000443
Todd Fialaaf245d12014-06-30 21:05:18 +0000444 m_stop_info.reason = StopReason::eStopReasonNone;
Pavel Labath05569f62015-07-23 09:09:29 +0000445 m_stop_info.details.signal.signo = 0;
Todd Fialaaf245d12014-06-30 21:05:18 +0000446}
447
448void
449NativeThreadLinux::SetExited ()
450{
451 const StateType new_state = StateType::eStateExited;
452 MaybeLogStateChange (new_state);
453 m_state = new_state;
454
455 m_stop_info.reason = StopReason::eStopReasonThreadExiting;
456}
457
Pavel Labath8c8ff7a2015-05-11 10:03:10 +0000458Error
459NativeThreadLinux::RequestStop ()
460{
461 Log* log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
462
Pavel Labath605b51b2016-02-23 13:56:30 +0000463 NativeProcessLinux &process = GetProcess();
Pavel Labath8c8ff7a2015-05-11 10:03:10 +0000464
Pavel Labath605b51b2016-02-23 13:56:30 +0000465 lldb::pid_t pid = process.GetID();
Pavel Labath8c8ff7a2015-05-11 10:03:10 +0000466 lldb::tid_t tid = GetID();
467
468 if (log)
469 log->Printf ("NativeThreadLinux::%s requesting thread stop(pid: %" PRIu64 ", tid: %" PRIu64 ")", __FUNCTION__, pid, tid);
470
471 Error err;
472 errno = 0;
473 if (::tgkill (pid, tid, SIGSTOP) != 0)
474 {
475 err.SetErrorToErrno ();
476 if (log)
477 log->Printf ("NativeThreadLinux::%s tgkill(%" PRIu64 ", %" PRIu64 ", SIGSTOP) failed: %s", __FUNCTION__, pid, tid, err.AsCString ());
478 }
Pavel Labath8c8ff7a2015-05-11 10:03:10 +0000479
480 return err;
481}
482
Todd Fialaaf245d12014-06-30 21:05:18 +0000483void
484NativeThreadLinux::MaybeLogStateChange (lldb::StateType new_state)
485{
486 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
487 // If we're not logging, we're done.
488 if (!log)
489 return;
490
491 // If this is a state change to the same state, we're done.
492 lldb::StateType old_state = m_state;
493 if (new_state == old_state)
494 return;
495
496 NativeProcessProtocolSP m_process_sp = m_process_wp.lock ();
497 lldb::pid_t pid = m_process_sp ? m_process_sp->GetID () : LLDB_INVALID_PROCESS_ID;
498
499 // Log it.
500 log->Printf ("NativeThreadLinux: thread (pid=%" PRIu64 ", tid=%" PRIu64 ") changing from state %s to %s", pid, GetID (), StateAsCString (old_state), StateAsCString (new_state));
501}
Pavel Labath605b51b2016-02-23 13:56:30 +0000502
503NativeProcessLinux &
504NativeThreadLinux::GetProcess()
505{
506 auto process_sp = std::static_pointer_cast<NativeProcessLinux>(NativeThreadProtocol::GetProcess());
507 assert(process_sp);
508 return *process_sp;
509}