blob: 287a271689a49fa37e1d697281021cf91f1331e7 [file] [log] [blame]
Todd Fialaaf245d12014-06-30 21:05:18 +00001//===-- NativeThreadLinux.cpp --------------------------------- -*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Todd Fialaaf245d12014-06-30 21:05:18 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "NativeThreadLinux.h"
10
11#include <signal.h>
Chaoren Lin18fe6402015-02-03 01:51:47 +000012#include <sstream>
Todd Fialaaf245d12014-06-30 21:05:18 +000013
14#include "NativeProcessLinux.h"
Pavel Labath0f4b17d2015-08-24 13:25:54 +000015#include "NativeRegisterContextLinux.h"
Pavel Labath605b51b2016-02-23 13:56:30 +000016#include "SingleStepCheck.h"
Todd Fiala2850b1b2014-06-30 23:51:35 +000017
Zachary Turner39de3112014-09-09 20:54:56 +000018#include "lldb/Host/HostNativeThread.h"
Pavel Labath605b51b2016-02-23 13:56:30 +000019#include "lldb/Host/linux/Ptrace.h"
Pavel Labath225b7952017-03-17 09:51:23 +000020#include "lldb/Host/linux/Support.h"
Chaoren Linc16f5dc2015-03-19 23:28:10 +000021#include "lldb/Utility/LLDBAssert.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000022#include "lldb/Utility/Log.h"
Pavel Labathd821c992018-08-07 11:07:21 +000023#include "lldb/Utility/State.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
Kate Stoneb9c1b512016-09-06 20:57:50 +000032#define tgkill(pid, tid, sig) \
33 syscall(__NR_tgkill, static_cast<::pid_t>(pid), static_cast<::pid_t>(tid), \
34 sig)
Pavel Labath8c8ff7a2015-05-11 10:03:10 +000035
Todd Fialaaf245d12014-06-30 21:05:18 +000036using namespace lldb;
37using namespace lldb_private;
Tamas Berghammerdb264a62015-03-31 09:52:22 +000038using namespace lldb_private::process_linux;
Todd Fialaaf245d12014-06-30 21:05:18 +000039
Kate Stoneb9c1b512016-09-06 20:57:50 +000040namespace {
41void LogThreadStopInfo(Log &log, const ThreadStopInfo &stop_info,
42 const char *const header) {
43 switch (stop_info.reason) {
44 case eStopReasonNone:
45 log.Printf("%s: %s no stop reason", __FUNCTION__, header);
46 return;
47 case eStopReasonTrace:
48 log.Printf("%s: %s trace, stopping signal 0x%" PRIx32, __FUNCTION__, header,
49 stop_info.details.signal.signo);
50 return;
51 case eStopReasonBreakpoint:
52 log.Printf("%s: %s breakpoint, stopping signal 0x%" PRIx32, __FUNCTION__,
53 header, stop_info.details.signal.signo);
54 return;
55 case eStopReasonWatchpoint:
56 log.Printf("%s: %s watchpoint, stopping signal 0x%" PRIx32, __FUNCTION__,
57 header, stop_info.details.signal.signo);
58 return;
59 case eStopReasonSignal:
60 log.Printf("%s: %s signal 0x%02" PRIx32, __FUNCTION__, header,
61 stop_info.details.signal.signo);
62 return;
63 case eStopReasonException:
64 log.Printf("%s: %s exception type 0x%02" PRIx64, __FUNCTION__, header,
65 stop_info.details.exception.type);
66 return;
67 case eStopReasonExec:
68 log.Printf("%s: %s exec, stopping signal 0x%" PRIx32, __FUNCTION__, header,
69 stop_info.details.signal.signo);
70 return;
71 case eStopReasonPlanComplete:
72 log.Printf("%s: %s plan complete", __FUNCTION__, header);
73 return;
74 case eStopReasonThreadExiting:
75 log.Printf("%s: %s thread exiting", __FUNCTION__, header);
76 return;
77 case eStopReasonInstrumentation:
78 log.Printf("%s: %s instrumentation", __FUNCTION__, header);
79 return;
80 default:
81 log.Printf("%s: %s invalid stop reason %" PRIu32, __FUNCTION__, header,
82 static_cast<uint32_t>(stop_info.reason));
83 }
84}
Todd Fialaaf245d12014-06-30 21:05:18 +000085}
86
Pavel Labath82abefa2017-07-18 09:24:48 +000087NativeThreadLinux::NativeThreadLinux(NativeProcessLinux &process,
Kate Stoneb9c1b512016-09-06 20:57:50 +000088 lldb::tid_t tid)
89 : NativeThreadProtocol(process, tid), m_state(StateType::eStateInvalid),
Pavel Labathd37349f2017-11-10 11:05:49 +000090 m_stop_info(),
91 m_reg_context_up(
92 NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
93 process.GetArchitecture(), *this)),
94 m_stop_description() {}
Kate Stoneb9c1b512016-09-06 20:57:50 +000095
96std::string NativeThreadLinux::GetName() {
Pavel Labath225b7952017-03-17 09:51:23 +000097 NativeProcessLinux &process = GetProcess();
Kate Stoneb9c1b512016-09-06 20:57:50 +000098
Pavel Labath225b7952017-03-17 09:51:23 +000099 auto BufferOrError = getProcFile(process.GetID(), GetID(), "comm");
100 if (!BufferOrError)
101 return "";
102 return BufferOrError.get()->getBuffer().rtrim('\n');
Todd Fialaaf245d12014-06-30 21:05:18 +0000103}
104
Kate Stoneb9c1b512016-09-06 20:57:50 +0000105lldb::StateType NativeThreadLinux::GetState() { return m_state; }
Todd Fialaaf245d12014-06-30 21:05:18 +0000106
Kate Stoneb9c1b512016-09-06 20:57:50 +0000107bool NativeThreadLinux::GetStopReason(ThreadStopInfo &stop_info,
108 std::string &description) {
109 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
Todd Fialaaf245d12014-06-30 21:05:18 +0000110
Kate Stoneb9c1b512016-09-06 20:57:50 +0000111 description.clear();
Todd Fialaaf245d12014-06-30 21:05:18 +0000112
Kate Stoneb9c1b512016-09-06 20:57:50 +0000113 switch (m_state) {
114 case eStateStopped:
115 case eStateCrashed:
116 case eStateExited:
117 case eStateSuspended:
118 case eStateUnloaded:
Todd Fialaaf245d12014-06-30 21:05:18 +0000119 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000120 LogThreadStopInfo(*log, m_stop_info, "m_stop_info in thread:");
121 stop_info = m_stop_info;
122 description = m_stop_description;
123 if (log)
124 LogThreadStopInfo(*log, stop_info, "returned stop_info:");
Todd Fialaaf245d12014-06-30 21:05:18 +0000125
Todd Fiala511e5cd2014-09-11 23:29:14 +0000126 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000127
128 case eStateInvalid:
129 case eStateConnected:
130 case eStateAttaching:
131 case eStateLaunching:
132 case eStateRunning:
133 case eStateStepping:
134 case eStateDetached:
135 if (log) {
136 log->Printf("NativeThreadLinux::%s tid %" PRIu64
137 " in state %s cannot answer stop reason",
138 __FUNCTION__, GetID(), StateAsCString(m_state));
139 }
140 return false;
141 }
142 llvm_unreachable("unhandled StateType!");
Todd Fiala511e5cd2014-09-11 23:29:14 +0000143}
144
Zachary Turner97206d52017-05-12 04:51:55 +0000145Status NativeThreadLinux::SetWatchpoint(lldb::addr_t addr, size_t size,
146 uint32_t watch_flags, bool hardware) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000147 if (!hardware)
Zachary Turner97206d52017-05-12 04:51:55 +0000148 return Status("not implemented");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000149 if (m_state == eStateLaunching)
Zachary Turner97206d52017-05-12 04:51:55 +0000150 return Status();
151 Status error = RemoveWatchpoint(addr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000152 if (error.Fail())
153 return error;
Pavel Labathd37349f2017-11-10 11:05:49 +0000154 uint32_t wp_index =
155 m_reg_context_up->SetHardwareWatchpoint(addr, size, watch_flags);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000156 if (wp_index == LLDB_INVALID_INDEX32)
Zachary Turner97206d52017-05-12 04:51:55 +0000157 return Status("Setting hardware watchpoint failed.");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000158 m_watchpoint_index_map.insert({addr, wp_index});
Zachary Turner97206d52017-05-12 04:51:55 +0000159 return Status();
Todd Fialaa9882ce2014-08-28 15:46:54 +0000160}
161
Zachary Turner97206d52017-05-12 04:51:55 +0000162Status NativeThreadLinux::RemoveWatchpoint(lldb::addr_t addr) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000163 auto wp = m_watchpoint_index_map.find(addr);
164 if (wp == m_watchpoint_index_map.end())
Zachary Turner97206d52017-05-12 04:51:55 +0000165 return Status();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000166 uint32_t wp_index = wp->second;
167 m_watchpoint_index_map.erase(wp);
Pavel Labathd37349f2017-11-10 11:05:49 +0000168 if (m_reg_context_up->ClearHardwareWatchpoint(wp_index))
Zachary Turner97206d52017-05-12 04:51:55 +0000169 return Status();
170 return Status("Clearing hardware watchpoint failed.");
Chaoren Lin18fe6402015-02-03 01:51:47 +0000171}
172
Zachary Turner97206d52017-05-12 04:51:55 +0000173Status NativeThreadLinux::SetHardwareBreakpoint(lldb::addr_t addr,
174 size_t size) {
Omair Javaidd5ffbad2017-02-24 13:27:31 +0000175 if (m_state == eStateLaunching)
Zachary Turner97206d52017-05-12 04:51:55 +0000176 return Status();
Omair Javaidd5ffbad2017-02-24 13:27:31 +0000177
Zachary Turner97206d52017-05-12 04:51:55 +0000178 Status error = RemoveHardwareBreakpoint(addr);
Omair Javaidd5ffbad2017-02-24 13:27:31 +0000179 if (error.Fail())
180 return error;
181
Pavel Labathd37349f2017-11-10 11:05:49 +0000182 uint32_t bp_index = m_reg_context_up->SetHardwareBreakpoint(addr, size);
Omair Javaidd5ffbad2017-02-24 13:27:31 +0000183
184 if (bp_index == LLDB_INVALID_INDEX32)
Zachary Turner97206d52017-05-12 04:51:55 +0000185 return Status("Setting hardware breakpoint failed.");
Omair Javaidd5ffbad2017-02-24 13:27:31 +0000186
187 m_hw_break_index_map.insert({addr, bp_index});
Zachary Turner97206d52017-05-12 04:51:55 +0000188 return Status();
Omair Javaidd5ffbad2017-02-24 13:27:31 +0000189}
190
Zachary Turner97206d52017-05-12 04:51:55 +0000191Status NativeThreadLinux::RemoveHardwareBreakpoint(lldb::addr_t addr) {
Omair Javaidd5ffbad2017-02-24 13:27:31 +0000192 auto bp = m_hw_break_index_map.find(addr);
193 if (bp == m_hw_break_index_map.end())
Zachary Turner97206d52017-05-12 04:51:55 +0000194 return Status();
Omair Javaidd5ffbad2017-02-24 13:27:31 +0000195
196 uint32_t bp_index = bp->second;
Pavel Labathd37349f2017-11-10 11:05:49 +0000197 if (m_reg_context_up->ClearHardwareBreakpoint(bp_index)) {
Omair Javaidd5ffbad2017-02-24 13:27:31 +0000198 m_hw_break_index_map.erase(bp);
Zachary Turner97206d52017-05-12 04:51:55 +0000199 return Status();
Omair Javaidd5ffbad2017-02-24 13:27:31 +0000200 }
201
Zachary Turner97206d52017-05-12 04:51:55 +0000202 return Status("Clearing hardware breakpoint failed.");
Omair Javaidd5ffbad2017-02-24 13:27:31 +0000203}
204
Zachary Turner97206d52017-05-12 04:51:55 +0000205Status NativeThreadLinux::Resume(uint32_t signo) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000206 const StateType new_state = StateType::eStateRunning;
207 MaybeLogStateChange(new_state);
208 m_state = new_state;
Tamas Berghammereadb2a92015-03-17 14:40:57 +0000209
Kate Stoneb9c1b512016-09-06 20:57:50 +0000210 m_stop_info.reason = StopReason::eStopReasonNone;
211 m_stop_description.clear();
Tamas Berghammereadb2a92015-03-17 14:40:57 +0000212
Adrian Prantl05097242018-04-30 16:49:04 +0000213 // If watchpoints have been set, but none on this thread, then this is a new
214 // thread. So set all existing watchpoints.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000215 if (m_watchpoint_index_map.empty()) {
Pavel Labath605b51b2016-02-23 13:56:30 +0000216 NativeProcessLinux &process = GetProcess();
Pavel Labath8c8ff7a2015-05-11 10:03:10 +0000217
Kate Stoneb9c1b512016-09-06 20:57:50 +0000218 const auto &watchpoint_map = process.GetWatchpointMap();
Pavel Labathd37349f2017-11-10 11:05:49 +0000219 m_reg_context_up->ClearAllHardwareWatchpoints();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000220 for (const auto &pair : watchpoint_map) {
221 const auto &wp = pair.second;
222 SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags, wp.m_hardware);
Pavel Labath8c8ff7a2015-05-11 10:03:10 +0000223 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000224 }
Pavel Labath8c8ff7a2015-05-11 10:03:10 +0000225
Omair Javaidd5ffbad2017-02-24 13:27:31 +0000226 // Set all active hardware breakpoint on all threads.
227 if (m_hw_break_index_map.empty()) {
228 NativeProcessLinux &process = GetProcess();
229
230 const auto &hw_breakpoint_map = process.GetHardwareBreakpointMap();
Pavel Labathd37349f2017-11-10 11:05:49 +0000231 m_reg_context_up->ClearAllHardwareBreakpoints();
Omair Javaidd5ffbad2017-02-24 13:27:31 +0000232 for (const auto &pair : hw_breakpoint_map) {
233 const auto &bp = pair.second;
234 SetHardwareBreakpoint(bp.m_addr, bp.m_size);
235 }
236 }
237
Kate Stoneb9c1b512016-09-06 20:57:50 +0000238 intptr_t data = 0;
239
240 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
241 data = signo;
242
243 return NativeProcessLinux::PtraceWrapper(PTRACE_CONT, GetID(), nullptr,
244 reinterpret_cast<void *>(data));
Pavel Labath8c8ff7a2015-05-11 10:03:10 +0000245}
246
Zachary Turner97206d52017-05-12 04:51:55 +0000247Status NativeThreadLinux::SingleStep(uint32_t signo) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000248 const StateType new_state = StateType::eStateStepping;
249 MaybeLogStateChange(new_state);
250 m_state = new_state;
251 m_stop_info.reason = StopReason::eStopReasonNone;
Pavel Labatha37bbbd2017-02-17 11:48:34 +0000252
253 if(!m_step_workaround) {
254 // If we already hava a workaround inplace, don't reset it. Otherwise, the
255 // destructor of the existing instance will run after the new instance has
256 // fetched the cpu mask, and the thread will end up with the wrong mask.
257 m_step_workaround = SingleStepWorkaround::Get(m_tid);
258 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000259
260 intptr_t data = 0;
261 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
262 data = signo;
263
264 // If hardware single-stepping is not supported, we just do a continue. The
Adrian Prantl05097242018-04-30 16:49:04 +0000265 // breakpoint on the next instruction has been setup in
266 // NativeProcessLinux::Resume.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000267 return NativeProcessLinux::PtraceWrapper(
268 GetProcess().SupportHardwareSingleStepping() ? PTRACE_SINGLESTEP
269 : PTRACE_CONT,
270 m_tid, nullptr, reinterpret_cast<void *>(data));
271}
272
273void NativeThreadLinux::SetStoppedBySignal(uint32_t signo,
274 const siginfo_t *info) {
275 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
276 if (log)
277 log->Printf("NativeThreadLinux::%s called with signal 0x%02" PRIx32,
278 __FUNCTION__, signo);
279
280 SetStopped();
281
282 m_stop_info.reason = StopReason::eStopReasonSignal;
283 m_stop_info.details.signal.signo = signo;
284
285 m_stop_description.clear();
286 if (info) {
287 switch (signo) {
288 case SIGSEGV:
289 case SIGBUS:
290 case SIGFPE:
291 case SIGILL:
292 // In case of MIPS64 target, SI_KERNEL is generated for invalid 64bit
293 // address.
294 const auto reason =
295 (info->si_signo == SIGBUS && info->si_code == SI_KERNEL)
296 ? CrashReason::eInvalidAddress
297 : GetCrashReason(*info);
Valentina Giusti6f8c1f82016-10-06 18:05:12 +0000298 m_stop_description = GetCrashReasonString(reason, *info);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000299 break;
300 }
301 }
302}
303
304bool NativeThreadLinux::IsStopped(int *signo) {
305 if (!StateIsStoppedState(m_state, false))
306 return false;
307
308 // If we are stopped by a signal, return the signo.
309 if (signo && m_state == StateType::eStateStopped &&
310 m_stop_info.reason == StopReason::eStopReasonSignal) {
311 *signo = m_stop_info.details.signal.signo;
312 }
313
314 // Regardless, we are stopped.
315 return true;
316}
317
318void NativeThreadLinux::SetStopped() {
319 if (m_state == StateType::eStateStepping)
Pavel Labath8abd34f2017-01-25 11:19:45 +0000320 m_step_workaround.reset();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000321
322 const StateType new_state = StateType::eStateStopped;
323 MaybeLogStateChange(new_state);
324 m_state = new_state;
325 m_stop_description.clear();
326}
327
328void NativeThreadLinux::SetStoppedByExec() {
329 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
330 if (log)
331 log->Printf("NativeThreadLinux::%s()", __FUNCTION__);
332
333 SetStopped();
334
335 m_stop_info.reason = StopReason::eStopReasonExec;
336 m_stop_info.details.signal.signo = SIGSTOP;
337}
338
339void NativeThreadLinux::SetStoppedByBreakpoint() {
340 SetStopped();
341
342 m_stop_info.reason = StopReason::eStopReasonBreakpoint;
343 m_stop_info.details.signal.signo = SIGTRAP;
344 m_stop_description.clear();
345}
346
347void NativeThreadLinux::SetStoppedByWatchpoint(uint32_t wp_index) {
348 SetStopped();
349
350 lldbassert(wp_index != LLDB_INVALID_INDEX32 && "wp_index cannot be invalid");
351
352 std::ostringstream ostr;
Pavel Labathd37349f2017-11-10 11:05:49 +0000353 ostr << m_reg_context_up->GetWatchpointAddress(wp_index) << " ";
Kate Stoneb9c1b512016-09-06 20:57:50 +0000354 ostr << wp_index;
355
356 /*
357 * MIPS: Last 3bits of the watchpoint address are masked by the kernel. For
358 * example:
359 * 'n' is at 0x120010d00 and 'm' is 0x120010d04. When a watchpoint is set at
360 * 'm', then
361 * watch exception is generated even when 'n' is read/written. To handle this
362 * case,
363 * find the base address of the load/store instruction and append it in the
364 * stop-info
365 * packet.
366 */
Pavel Labathd37349f2017-11-10 11:05:49 +0000367 ostr << " " << m_reg_context_up->GetWatchpointHitAddress(wp_index);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000368
369 m_stop_description = ostr.str();
370
371 m_stop_info.reason = StopReason::eStopReasonWatchpoint;
372 m_stop_info.details.signal.signo = SIGTRAP;
373}
374
375bool NativeThreadLinux::IsStoppedAtBreakpoint() {
376 return GetState() == StateType::eStateStopped &&
377 m_stop_info.reason == StopReason::eStopReasonBreakpoint;
378}
379
380bool NativeThreadLinux::IsStoppedAtWatchpoint() {
381 return GetState() == StateType::eStateStopped &&
382 m_stop_info.reason == StopReason::eStopReasonWatchpoint;
383}
384
385void NativeThreadLinux::SetStoppedByTrace() {
386 SetStopped();
387
388 m_stop_info.reason = StopReason::eStopReasonTrace;
389 m_stop_info.details.signal.signo = SIGTRAP;
390}
391
392void NativeThreadLinux::SetStoppedWithNoReason() {
393 SetStopped();
394
395 m_stop_info.reason = StopReason::eStopReasonNone;
396 m_stop_info.details.signal.signo = 0;
397}
398
399void NativeThreadLinux::SetExited() {
400 const StateType new_state = StateType::eStateExited;
401 MaybeLogStateChange(new_state);
402 m_state = new_state;
403
404 m_stop_info.reason = StopReason::eStopReasonThreadExiting;
405}
406
Zachary Turner97206d52017-05-12 04:51:55 +0000407Status NativeThreadLinux::RequestStop() {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000408 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
409
410 NativeProcessLinux &process = GetProcess();
411
412 lldb::pid_t pid = process.GetID();
413 lldb::tid_t tid = GetID();
414
415 if (log)
416 log->Printf("NativeThreadLinux::%s requesting thread stop(pid: %" PRIu64
417 ", tid: %" PRIu64 ")",
418 __FUNCTION__, pid, tid);
419
Zachary Turner97206d52017-05-12 04:51:55 +0000420 Status err;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000421 errno = 0;
422 if (::tgkill(pid, tid, SIGSTOP) != 0) {
423 err.SetErrorToErrno();
424 if (log)
425 log->Printf("NativeThreadLinux::%s tgkill(%" PRIu64 ", %" PRIu64
426 ", SIGSTOP) failed: %s",
427 __FUNCTION__, pid, tid, err.AsCString());
428 }
429
430 return err;
431}
432
433void NativeThreadLinux::MaybeLogStateChange(lldb::StateType new_state) {
434 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
435 // If we're not logging, we're done.
436 if (!log)
437 return;
438
439 // If this is a state change to the same state, we're done.
440 lldb::StateType old_state = m_state;
441 if (new_state == old_state)
442 return;
443
Pavel Labath82abefa2017-07-18 09:24:48 +0000444 LLDB_LOG(log, "pid={0}, tid={1}: changing from state {2} to {3}",
445 m_process.GetID(), GetID(), old_state, new_state);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000446}
447
448NativeProcessLinux &NativeThreadLinux::GetProcess() {
Pavel Labath82abefa2017-07-18 09:24:48 +0000449 return static_cast<NativeProcessLinux &>(m_process);
Pavel Labath605b51b2016-02-23 13:56:30 +0000450}