blob: 240803ab9559c03ef20493d559e4ca6bcee08286 [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"
Tamas Berghammer1e209fc2015-03-13 11:36:47 +000016#include "NativeRegisterContextLinux_arm64.h"
Todd Fiala2850b1b2014-06-30 23:51:35 +000017#include "NativeRegisterContextLinux_x86_64.h"
Mohit K. Bhakkad3df471c2015-03-17 11:43:56 +000018#include "NativeRegisterContextLinux_mips64.h"
Todd Fiala2850b1b2014-06-30 23:51:35 +000019
Todd Fialaaf245d12014-06-30 21:05:18 +000020#include "lldb/Core/Log.h"
21#include "lldb/Core/State.h"
22#include "lldb/Host/Host.h"
Zachary Turner13b18262014-08-20 16:42:51 +000023#include "lldb/Host/HostInfo.h"
Zachary Turner39de3112014-09-09 20:54:56 +000024#include "lldb/Host/HostNativeThread.h"
Chaoren Linc16f5dc2015-03-19 23:28:10 +000025#include "lldb/Utility/LLDBAssert.h"
Todd Fialaaf245d12014-06-30 21:05:18 +000026#include "lldb/lldb-enumerations.h"
Zachary Turner39de3112014-09-09 20:54:56 +000027
28#include "llvm/ADT/SmallString.h"
29
Chaoren Lin28e57422015-02-03 01:51:25 +000030#include "Plugins/Process/POSIX/CrashReason.h"
31
Todd Fialab71e89e2014-08-29 16:01:35 +000032#include "Plugins/Process/Utility/RegisterContextLinux_arm64.h"
Todd Fialaaf245d12014-06-30 21:05:18 +000033#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
34#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
Mohit K. Bhakkad3df471c2015-03-17 11:43:56 +000035#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
Todd Fialaaf245d12014-06-30 21:05:18 +000036#include "Plugins/Process/Utility/RegisterInfoInterface.h"
37
38using namespace lldb;
39using namespace lldb_private;
Tamas Berghammerdb264a62015-03-31 09:52:22 +000040using namespace lldb_private::process_linux;
Todd Fialaaf245d12014-06-30 21:05:18 +000041
42namespace
43{
44 void LogThreadStopInfo (Log &log, const ThreadStopInfo &stop_info, const char *const header)
45 {
46 switch (stop_info.reason)
47 {
Pavel Labath12fd3752015-03-20 14:45:13 +000048 case eStopReasonNone:
49 log.Printf ("%s: %s no stop reason", __FUNCTION__, header);
50 return;
51 case eStopReasonTrace:
52 log.Printf ("%s: %s trace, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
53 return;
54 case eStopReasonBreakpoint:
55 log.Printf ("%s: %s breakpoint, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
56 return;
57 case eStopReasonWatchpoint:
58 log.Printf ("%s: %s watchpoint, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
59 return;
Todd Fialaaf245d12014-06-30 21:05:18 +000060 case eStopReasonSignal:
Chaoren Linae29d392015-02-03 01:50:46 +000061 log.Printf ("%s: %s signal 0x%02" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
Todd Fialaaf245d12014-06-30 21:05:18 +000062 return;
63 case eStopReasonException:
Chaoren Linae29d392015-02-03 01:50:46 +000064 log.Printf ("%s: %s exception type 0x%02" PRIx64, __FUNCTION__, header, stop_info.details.exception.type);
Todd Fialaa9882ce2014-08-28 15:46:54 +000065 return;
66 case eStopReasonExec:
67 log.Printf ("%s: %s exec, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
Todd Fialaaf245d12014-06-30 21:05:18 +000068 return;
Pavel Labath12fd3752015-03-20 14:45:13 +000069 case eStopReasonPlanComplete:
70 log.Printf ("%s: %s plan complete", __FUNCTION__, header);
71 return;
72 case eStopReasonThreadExiting:
73 log.Printf ("%s: %s thread exiting", __FUNCTION__, header);
74 return;
75 case eStopReasonInstrumentation:
76 log.Printf ("%s: %s instrumentation", __FUNCTION__, header);
77 return;
Todd Fialaaf245d12014-06-30 21:05:18 +000078 default:
Todd Fialaa9882ce2014-08-28 15:46:54 +000079 log.Printf ("%s: %s invalid stop reason %" PRIu32, __FUNCTION__, header, static_cast<uint32_t> (stop_info.reason));
Todd Fialaaf245d12014-06-30 21:05:18 +000080 }
81 }
82}
83
84NativeThreadLinux::NativeThreadLinux (NativeProcessLinux *process, lldb::tid_t tid) :
85 NativeThreadProtocol (process, tid),
86 m_state (StateType::eStateInvalid),
87 m_stop_info (),
Chaoren Lin28e57422015-02-03 01:51:25 +000088 m_reg_context_sp (),
89 m_stop_description ()
Todd Fialaaf245d12014-06-30 21:05:18 +000090{
91}
92
Todd Fiala7206c6d2014-09-12 22:51:49 +000093std::string
Todd Fialaaf245d12014-06-30 21:05:18 +000094NativeThreadLinux::GetName()
95{
96 NativeProcessProtocolSP process_sp = m_process_wp.lock ();
97 if (!process_sp)
98 return "<unknown: no process>";
99
100 // const NativeProcessLinux *const process = reinterpret_cast<NativeProcessLinux*> (process_sp->get ());
Zachary Turner39de3112014-09-09 20:54:56 +0000101 llvm::SmallString<32> thread_name;
102 HostNativeThread::GetName(GetID(), thread_name);
103 return thread_name.c_str();
Todd Fialaaf245d12014-06-30 21:05:18 +0000104}
105
106lldb::StateType
107NativeThreadLinux::GetState ()
108{
109 return m_state;
110}
111
112
113bool
Chaoren Lin28e57422015-02-03 01:51:25 +0000114NativeThreadLinux::GetStopReason (ThreadStopInfo &stop_info, std::string& description)
Todd Fialaaf245d12014-06-30 21:05:18 +0000115{
116 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
Chaoren Lin28e57422015-02-03 01:51:25 +0000117
118 description.clear();
119
Todd Fialaaf245d12014-06-30 21:05:18 +0000120 switch (m_state)
121 {
122 case eStateStopped:
123 case eStateCrashed:
124 case eStateExited:
125 case eStateSuspended:
126 case eStateUnloaded:
127 if (log)
Todd Fialaa9882ce2014-08-28 15:46:54 +0000128 LogThreadStopInfo (*log, m_stop_info, "m_stop_info in thread:");
Todd Fialaaf245d12014-06-30 21:05:18 +0000129 stop_info = m_stop_info;
Chaoren Lin18fe6402015-02-03 01:51:47 +0000130 switch (m_stop_info.reason)
131 {
132 case StopReason::eStopReasonException:
133 case StopReason::eStopReasonBreakpoint:
134 case StopReason::eStopReasonWatchpoint:
135 description = m_stop_description;
136 default:
137 break;
138 }
Todd Fialaaf245d12014-06-30 21:05:18 +0000139 if (log)
Todd Fialaa9882ce2014-08-28 15:46:54 +0000140 LogThreadStopInfo (*log, stop_info, "returned stop_info:");
Chaoren Lin28e57422015-02-03 01:51:25 +0000141
Todd Fialaaf245d12014-06-30 21:05:18 +0000142 return true;
143
144 case eStateInvalid:
145 case eStateConnected:
146 case eStateAttaching:
147 case eStateLaunching:
148 case eStateRunning:
149 case eStateStepping:
150 case eStateDetached:
Todd Fialaaf245d12014-06-30 21:05:18 +0000151 if (log)
152 {
153 log->Printf ("NativeThreadLinux::%s tid %" PRIu64 " in state %s cannot answer stop reason",
154 __FUNCTION__, GetID (), StateAsCString (m_state));
155 }
156 return false;
157 }
David Majnemer8faf9372014-09-16 06:34:29 +0000158 llvm_unreachable("unhandled StateType!");
Todd Fialaaf245d12014-06-30 21:05:18 +0000159}
160
Tamas Berghammerdb264a62015-03-31 09:52:22 +0000161NativeRegisterContextSP
Todd Fialaaf245d12014-06-30 21:05:18 +0000162NativeThreadLinux::GetRegisterContext ()
163{
164 // Return the register context if we already created it.
165 if (m_reg_context_sp)
166 return m_reg_context_sp;
167
168 // First select the appropriate RegisterInfoInterface.
169 RegisterInfoInterface *reg_interface = nullptr;
170 NativeProcessProtocolSP m_process_sp = m_process_wp.lock ();
171 if (!m_process_sp)
172 return NativeRegisterContextSP ();
173
174 ArchSpec target_arch;
175 if (!m_process_sp->GetArchitecture (target_arch))
176 return NativeRegisterContextSP ();
177
178 switch (target_arch.GetTriple().getOS())
179 {
180 case llvm::Triple::Linux:
181 switch (target_arch.GetMachine())
182 {
Todd Fialab71e89e2014-08-29 16:01:35 +0000183 case llvm::Triple::aarch64:
184 assert((HostInfo::GetArchitecture ().GetAddressByteSize() == 8) && "Register setting path assumes this is a 64-bit host");
185 reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_arm64(target_arch));
186 break;
Todd Fialaaf245d12014-06-30 21:05:18 +0000187 case llvm::Triple::x86:
188 case llvm::Triple::x86_64:
Zachary Turner13b18262014-08-20 16:42:51 +0000189 if (HostInfo::GetArchitecture().GetAddressByteSize() == 4)
Todd Fialaaf245d12014-06-30 21:05:18 +0000190 {
191 // 32-bit hosts run with a RegisterContextLinux_i386 context.
192 reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_i386(target_arch));
193 }
194 else
195 {
Zachary Turner13b18262014-08-20 16:42:51 +0000196 assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
197 "Register setting path assumes this is a 64-bit host");
Todd Fialaaf245d12014-06-30 21:05:18 +0000198 // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64 register context.
199 reg_interface = static_cast<RegisterInfoInterface*> (new RegisterContextLinux_x86_64 (target_arch));
200 }
201 break;
Mohit K. Bhakkad3df471c2015-03-17 11:43:56 +0000202 case llvm::Triple::mips64:
203 case llvm::Triple::mips64el:
204 assert((HostInfo::GetArchitecture ().GetAddressByteSize() == 8)
205 && "Register setting path assumes this is a 64-bit host");
206 reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_mips64 (target_arch));
207 break;
Todd Fialaaf245d12014-06-30 21:05:18 +0000208 default:
209 break;
210 }
211 break;
212 default:
213 break;
214 }
215
216 assert(reg_interface && "OS or CPU not supported!");
217 if (!reg_interface)
218 return NativeRegisterContextSP ();
219
220 // Now create the register context.
221 switch (target_arch.GetMachine())
222 {
223#if 0
224 case llvm::Triple::mips64:
225 {
226 RegisterContextPOSIXProcessMonitor_mips64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_mips64(*this, 0, reg_interface);
227 m_posix_thread = reg_ctx;
228 m_reg_context_sp.reset(reg_ctx);
229 break;
230 }
231#endif
Mohit K. Bhakkad3df471c2015-03-17 11:43:56 +0000232 case llvm::Triple::mips64:
233 case llvm::Triple::mips64el:
234 {
235 const uint32_t concrete_frame_idx = 0;
236 m_reg_context_sp.reset (new NativeRegisterContextLinux_mips64 (*this, concrete_frame_idx, reg_interface));
237 break;
238 }
Tamas Berghammer1e209fc2015-03-13 11:36:47 +0000239 case llvm::Triple::aarch64:
240 {
241 const uint32_t concrete_frame_idx = 0;
242 m_reg_context_sp.reset (new NativeRegisterContextLinux_arm64(*this, concrete_frame_idx, reg_interface));
243 break;
244 }
Todd Fialaaf245d12014-06-30 21:05:18 +0000245 case llvm::Triple::x86:
Todd Fialaaf245d12014-06-30 21:05:18 +0000246 case llvm::Triple::x86_64:
247 {
248 const uint32_t concrete_frame_idx = 0;
249 m_reg_context_sp.reset (new NativeRegisterContextLinux_x86_64(*this, concrete_frame_idx, reg_interface));
250 break;
251 }
252 default:
253 break;
254 }
255
256 return m_reg_context_sp;
257}
258
259Error
260NativeThreadLinux::SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware)
261{
Chaoren Lin18fe6402015-02-03 01:51:47 +0000262 if (!hardware)
263 return Error ("not implemented");
Chaoren Linf591f692015-02-26 19:48:15 +0000264 if (m_state == eStateLaunching)
265 return Error ();
Chaoren Lin18fe6402015-02-03 01:51:47 +0000266 Error error = RemoveWatchpoint(addr);
267 if (error.Fail()) return error;
268 NativeRegisterContextSP reg_ctx = GetRegisterContext ();
269 uint32_t wp_index =
270 reg_ctx->SetHardwareWatchpoint (addr, size, watch_flags);
271 if (wp_index == LLDB_INVALID_INDEX32)
272 return Error ("Setting hardware watchpoint failed.");
273 m_watchpoint_index_map.insert({addr, wp_index});
274 return Error ();
Todd Fialaaf245d12014-06-30 21:05:18 +0000275}
276
277Error
278NativeThreadLinux::RemoveWatchpoint (lldb::addr_t addr)
279{
Chaoren Lin18fe6402015-02-03 01:51:47 +0000280 auto wp = m_watchpoint_index_map.find(addr);
281 if (wp == m_watchpoint_index_map.end())
282 return Error ();
283 uint32_t wp_index = wp->second;
284 m_watchpoint_index_map.erase(wp);
285 if (GetRegisterContext()->ClearHardwareWatchpoint(wp_index))
286 return Error ();
287 return Error ("Clearing hardware watchpoint failed.");
Todd Fialaaf245d12014-06-30 21:05:18 +0000288}
289
290void
291NativeThreadLinux::SetLaunching ()
292{
293 const StateType new_state = StateType::eStateLaunching;
294 MaybeLogStateChange (new_state);
295 m_state = new_state;
296
297 // Also mark it as stopped since launching temporarily stops the newly created thread
298 // in the ptrace machinery.
299 m_stop_info.reason = StopReason::eStopReasonSignal;
300 m_stop_info.details.signal.signo = SIGSTOP;
301}
302
303
304void
305NativeThreadLinux::SetRunning ()
306{
307 const StateType new_state = StateType::eStateRunning;
308 MaybeLogStateChange (new_state);
309 m_state = new_state;
310
311 m_stop_info.reason = StopReason::eStopReasonNone;
Chaoren Lin28e57422015-02-03 01:51:25 +0000312 m_stop_description.clear();
Chaoren Lin18fe6402015-02-03 01:51:47 +0000313
314 // If watchpoints have been set, but none on this thread,
315 // then this is a new thread. So set all existing watchpoints.
316 if (m_watchpoint_index_map.empty())
317 {
Oleksiy Vyalov8bc34f42015-02-19 17:58:04 +0000318 const auto process_sp = GetProcess();
319 if (process_sp)
Chaoren Lin18fe6402015-02-03 01:51:47 +0000320 {
Oleksiy Vyalov8bc34f42015-02-19 17:58:04 +0000321 const auto &watchpoint_map = process_sp->GetWatchpointMap();
322 if (watchpoint_map.empty()) return;
323 GetRegisterContext()->ClearAllHardwareWatchpoints();
324 for (const auto &pair : watchpoint_map)
325 {
326 const auto& wp = pair.second;
327 SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags, wp.m_hardware);
328 }
Chaoren Lin18fe6402015-02-03 01:51:47 +0000329 }
330 }
Todd Fialaaf245d12014-06-30 21:05:18 +0000331}
332
333void
334NativeThreadLinux::SetStepping ()
335{
336 const StateType new_state = StateType::eStateStepping;
337 MaybeLogStateChange (new_state);
338 m_state = new_state;
339
340 m_stop_info.reason = StopReason::eStopReasonNone;
341}
342
343void
344NativeThreadLinux::SetStoppedBySignal (uint32_t signo)
345{
346 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
347 if (log)
Chaoren Linb8af31d2015-02-03 01:50:51 +0000348 log->Printf ("NativeThreadLinux::%s called with signal 0x%02" PRIx32, __FUNCTION__, signo);
Todd Fialaaf245d12014-06-30 21:05:18 +0000349
350 const StateType new_state = StateType::eStateStopped;
351 MaybeLogStateChange (new_state);
352 m_state = new_state;
353
354 m_stop_info.reason = StopReason::eStopReasonSignal;
355 m_stop_info.details.signal.signo = signo;
356}
357
Todd Fiala511e5cd2014-09-11 23:29:14 +0000358bool
359NativeThreadLinux::IsStopped (int *signo)
360{
361 if (!StateIsStoppedState (m_state, false))
362 return false;
363
364 // If we are stopped by a signal, return the signo.
365 if (signo &&
366 m_state == StateType::eStateStopped &&
367 m_stop_info.reason == StopReason::eStopReasonSignal)
368 {
369 *signo = m_stop_info.details.signal.signo;
370 }
371
372 // Regardless, we are stopped.
373 return true;
374}
375
376
Todd Fialaaf245d12014-06-30 21:05:18 +0000377void
Todd Fialaa9882ce2014-08-28 15:46:54 +0000378NativeThreadLinux::SetStoppedByExec ()
379{
380 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
381 if (log)
382 log->Printf ("NativeThreadLinux::%s()", __FUNCTION__);
383
384 const StateType new_state = StateType::eStateStopped;
385 MaybeLogStateChange (new_state);
386 m_state = new_state;
387
388 m_stop_info.reason = StopReason::eStopReasonExec;
389 m_stop_info.details.signal.signo = SIGSTOP;
390}
391
392void
Todd Fialaaf245d12014-06-30 21:05:18 +0000393NativeThreadLinux::SetStoppedByBreakpoint ()
394{
395 const StateType new_state = StateType::eStateStopped;
396 MaybeLogStateChange (new_state);
397 m_state = new_state;
398
Chaoren Lin28e57422015-02-03 01:51:25 +0000399 m_stop_info.reason = StopReason::eStopReasonBreakpoint;
Todd Fialaaf245d12014-06-30 21:05:18 +0000400 m_stop_info.details.signal.signo = SIGTRAP;
Chaoren Lin18fe6402015-02-03 01:51:47 +0000401 m_stop_description.clear();
402}
403
404void
Chaoren Linc16f5dc2015-03-19 23:28:10 +0000405NativeThreadLinux::SetStoppedByWatchpoint (uint32_t wp_index)
Chaoren Lin18fe6402015-02-03 01:51:47 +0000406{
407 const StateType new_state = StateType::eStateStopped;
408 MaybeLogStateChange (new_state);
409 m_state = new_state;
Chaoren Lin18fe6402015-02-03 01:51:47 +0000410 m_stop_description.clear ();
Tamas Berghammereadb2a92015-03-17 14:40:57 +0000411
Chaoren Linc16f5dc2015-03-19 23:28:10 +0000412 lldbassert(wp_index != LLDB_INVALID_INDEX32 &&
413 "wp_index cannot be invalid");
Tamas Berghammereadb2a92015-03-17 14:40:57 +0000414
Chaoren Linc16f5dc2015-03-19 23:28:10 +0000415 std::ostringstream ostr;
416 ostr << GetRegisterContext()->GetWatchpointAddress(wp_index) << " ";
417 ostr << wp_index;
418 m_stop_description = ostr.str();
Tamas Berghammereadb2a92015-03-17 14:40:57 +0000419
Chaoren Linc16f5dc2015-03-19 23:28:10 +0000420 m_stop_info.reason = StopReason::eStopReasonWatchpoint;
421 m_stop_info.details.signal.signo = SIGTRAP;
Todd Fialaaf245d12014-06-30 21:05:18 +0000422}
423
424bool
425NativeThreadLinux::IsStoppedAtBreakpoint ()
426{
Chaoren Lin18fe6402015-02-03 01:51:47 +0000427 return GetState () == StateType::eStateStopped &&
428 m_stop_info.reason == StopReason::eStopReasonBreakpoint;
429}
Todd Fialaaf245d12014-06-30 21:05:18 +0000430
Chaoren Lin18fe6402015-02-03 01:51:47 +0000431bool
432NativeThreadLinux::IsStoppedAtWatchpoint ()
433{
434 return GetState () == StateType::eStateStopped &&
435 m_stop_info.reason == StopReason::eStopReasonWatchpoint;
Todd Fialaaf245d12014-06-30 21:05:18 +0000436}
437
438void
Chaoren Lin28e57422015-02-03 01:51:25 +0000439NativeThreadLinux::SetStoppedByTrace ()
440{
441 const StateType new_state = StateType::eStateStopped;
442 MaybeLogStateChange (new_state);
443 m_state = new_state;
444
445 m_stop_info.reason = StopReason::eStopReasonTrace;
446 m_stop_info.details.signal.signo = SIGTRAP;
447}
448
449void
450NativeThreadLinux::SetCrashedWithException (const siginfo_t& info)
Todd Fialaaf245d12014-06-30 21:05:18 +0000451{
452 const StateType new_state = StateType::eStateCrashed;
453 MaybeLogStateChange (new_state);
454 m_state = new_state;
455
456 m_stop_info.reason = StopReason::eStopReasonException;
Chaoren Lin28e57422015-02-03 01:51:25 +0000457 m_stop_info.details.signal.signo = info.si_signo;
Todd Fialaaf245d12014-06-30 21:05:18 +0000458
Chaoren Lin28e57422015-02-03 01:51:25 +0000459 const auto reason = GetCrashReason (info);
460 m_stop_description = GetCrashReasonString (reason, reinterpret_cast<lldb::addr_t> (info.si_addr));
461}
Todd Fialaaf245d12014-06-30 21:05:18 +0000462
463void
464NativeThreadLinux::SetSuspended ()
465{
466 const StateType new_state = StateType::eStateSuspended;
467 MaybeLogStateChange (new_state);
468 m_state = new_state;
469
470 // FIXME what makes sense here? Do we need a suspended StopReason?
471 m_stop_info.reason = StopReason::eStopReasonNone;
472}
473
474void
475NativeThreadLinux::SetExited ()
476{
477 const StateType new_state = StateType::eStateExited;
478 MaybeLogStateChange (new_state);
479 m_state = new_state;
480
481 m_stop_info.reason = StopReason::eStopReasonThreadExiting;
482}
483
484void
485NativeThreadLinux::MaybeLogStateChange (lldb::StateType new_state)
486{
487 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
488 // If we're not logging, we're done.
489 if (!log)
490 return;
491
492 // If this is a state change to the same state, we're done.
493 lldb::StateType old_state = m_state;
494 if (new_state == old_state)
495 return;
496
497 NativeProcessProtocolSP m_process_sp = m_process_wp.lock ();
498 lldb::pid_t pid = m_process_sp ? m_process_sp->GetID () : LLDB_INVALID_PROCESS_ID;
499
500 // Log it.
501 log->Printf ("NativeThreadLinux: thread (pid=%" PRIu64 ", tid=%" PRIu64 ") changing from state %s to %s", pid, GetID (), StateAsCString (old_state), StateAsCString (new_state));
502}