1//===-- NativeThreadLinux.cpp ---------------------------------------------===//
2//
3// 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
6//
7//===----------------------------------------------------------------------===//
8
9#include "NativeThreadLinux.h"
10
11#include <csignal>
12#include <sstream>
13
14#include "NativeProcessLinux.h"
15#include "NativeRegisterContextLinux.h"
16#include "SingleStepCheck.h"
17
18#include "lldb/Host/HostNativeThread.h"
19#include "lldb/Host/linux/Ptrace.h"
20#include "lldb/Host/linux/Support.h"
21#include "lldb/Utility/LLDBAssert.h"
22#include "lldb/Utility/LLDBLog.h"
23#include "lldb/Utility/Log.h"
24#include "lldb/Utility/State.h"
25#include "lldb/lldb-enumerations.h"
26
27#include "llvm/ADT/SmallString.h"
28
29#include "Plugins/Process/POSIX/CrashReason.h"
30#include "Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h"
31
32#include <sys/syscall.h>
33// Try to define a macro to encapsulate the tgkill syscall
34#define tgkill(pid, tid, sig) \
35 syscall(__NR_tgkill, static_cast<::pid_t>(pid), static_cast<::pid_t>(tid), \
36 sig)
37
38using namespace lldb;
39using namespace lldb_private;
40using namespace lldb_private::process_linux;
41
42namespace {
43void LogThreadStopInfo(Log &log, const ThreadStopInfo &stop_info,
44 const char *const header) {
45 switch (stop_info.reason) {
46 case eStopReasonNone:
47 log.Printf(format: "%s: %s no stop reason", __FUNCTION__, header);
48 return;
49 case eStopReasonTrace:
50 log.Printf(format: "%s: %s trace, stopping signal 0x%" PRIx32, __FUNCTION__, header,
51 stop_info.signo);
52 return;
53 case eStopReasonBreakpoint:
54 log.Printf(format: "%s: %s breakpoint, stopping signal 0x%" PRIx32, __FUNCTION__,
55 header, stop_info.signo);
56 return;
57 case eStopReasonWatchpoint:
58 log.Printf(format: "%s: %s watchpoint, stopping signal 0x%" PRIx32, __FUNCTION__,
59 header, stop_info.signo);
60 return;
61 case eStopReasonSignal:
62 log.Printf(format: "%s: %s signal 0x%02" PRIx32, __FUNCTION__, header,
63 stop_info.signo);
64 return;
65 case eStopReasonException:
66 log.Printf(format: "%s: %s exception type 0x%02" PRIx64, __FUNCTION__, header,
67 stop_info.details.exception.type);
68 return;
69 case eStopReasonExec:
70 log.Printf(format: "%s: %s exec, stopping signal 0x%" PRIx32, __FUNCTION__, header,
71 stop_info.signo);
72 return;
73 case eStopReasonPlanComplete:
74 log.Printf(format: "%s: %s plan complete", __FUNCTION__, header);
75 return;
76 case eStopReasonThreadExiting:
77 log.Printf(format: "%s: %s thread exiting", __FUNCTION__, header);
78 return;
79 case eStopReasonInstrumentation:
80 log.Printf(format: "%s: %s instrumentation", __FUNCTION__, header);
81 return;
82 case eStopReasonProcessorTrace:
83 log.Printf(format: "%s: %s processor trace", __FUNCTION__, header);
84 return;
85 default:
86 log.Printf(format: "%s: %s invalid stop reason %" PRIu32, __FUNCTION__, header,
87 static_cast<uint32_t>(stop_info.reason));
88 }
89}
90}
91
92NativeThreadLinux::NativeThreadLinux(NativeProcessLinux &process,
93 lldb::tid_t tid)
94 : NativeThreadProtocol(process, tid), m_state(StateType::eStateInvalid),
95 m_stop_info(),
96 m_reg_context_up(
97 NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
98 target_arch: process.GetArchitecture(), native_thread&: *this)),
99 m_stop_description() {}
100
101std::string NativeThreadLinux::GetName() {
102 NativeProcessLinux &process = GetProcess();
103
104 auto BufferOrError = getProcFile(pid: process.GetID(), tid: GetID(), file: "comm");
105 if (!BufferOrError)
106 return "";
107 return std::string(BufferOrError.get()->getBuffer().rtrim(Char: '\n'));
108}
109
110lldb::StateType NativeThreadLinux::GetState() { return m_state; }
111
112bool NativeThreadLinux::GetStopReason(ThreadStopInfo &stop_info,
113 std::string &description) {
114 Log *log = GetLog(mask: LLDBLog::Thread);
115
116 description.clear();
117
118 switch (m_state) {
119 case eStateStopped:
120 case eStateCrashed:
121 case eStateExited:
122 case eStateSuspended:
123 case eStateUnloaded:
124 if (log)
125 LogThreadStopInfo(log&: *log, stop_info: m_stop_info, header: "m_stop_info in thread:");
126 stop_info = m_stop_info;
127 description = m_stop_description;
128 if (log)
129 LogThreadStopInfo(log&: *log, stop_info, header: "returned stop_info:");
130
131 return true;
132
133 case eStateInvalid:
134 case eStateConnected:
135 case eStateAttaching:
136 case eStateLaunching:
137 case eStateRunning:
138 case eStateStepping:
139 case eStateDetached:
140 if (log) {
141 LLDB_LOGF(log,
142 "NativeThreadLinux::%s tid %" PRIu64
143 " in state %s cannot answer stop reason",
144 __FUNCTION__, GetID(), StateAsCString(m_state));
145 }
146 return false;
147 }
148 llvm_unreachable("unhandled StateType!");
149}
150
151Status NativeThreadLinux::SetWatchpoint(lldb::addr_t addr, size_t size,
152 uint32_t watch_flags, bool hardware) {
153 if (!hardware)
154 return Status("not implemented");
155 if (m_state == eStateLaunching)
156 return Status();
157 Status error = RemoveWatchpoint(addr);
158 if (error.Fail())
159 return error;
160 uint32_t wp_index =
161 m_reg_context_up->SetHardwareWatchpoint(addr, size, watch_flags);
162 if (wp_index == LLDB_INVALID_INDEX32)
163 return Status("Setting hardware watchpoint failed.");
164 m_watchpoint_index_map.insert(x: {addr, wp_index});
165 return Status();
166}
167
168Status NativeThreadLinux::RemoveWatchpoint(lldb::addr_t addr) {
169 auto wp = m_watchpoint_index_map.find(x: addr);
170 if (wp == m_watchpoint_index_map.end())
171 return Status();
172 uint32_t wp_index = wp->second;
173 m_watchpoint_index_map.erase(position: wp);
174 if (m_reg_context_up->ClearHardwareWatchpoint(hw_index: wp_index))
175 return Status();
176 return Status("Clearing hardware watchpoint failed.");
177}
178
179Status NativeThreadLinux::SetHardwareBreakpoint(lldb::addr_t addr,
180 size_t size) {
181 if (m_state == eStateLaunching)
182 return Status();
183
184 Status error = RemoveHardwareBreakpoint(addr);
185 if (error.Fail())
186 return error;
187
188 uint32_t bp_index = m_reg_context_up->SetHardwareBreakpoint(addr, size);
189
190 if (bp_index == LLDB_INVALID_INDEX32)
191 return Status("Setting hardware breakpoint failed.");
192
193 m_hw_break_index_map.insert(x: {addr, bp_index});
194 return Status();
195}
196
197Status NativeThreadLinux::RemoveHardwareBreakpoint(lldb::addr_t addr) {
198 auto bp = m_hw_break_index_map.find(x: addr);
199 if (bp == m_hw_break_index_map.end())
200 return Status();
201
202 uint32_t bp_index = bp->second;
203 if (m_reg_context_up->ClearHardwareBreakpoint(hw_idx: bp_index)) {
204 m_hw_break_index_map.erase(position: bp);
205 return Status();
206 }
207
208 return Status("Clearing hardware breakpoint failed.");
209}
210
211Status NativeThreadLinux::Resume(uint32_t signo) {
212 const StateType new_state = StateType::eStateRunning;
213 MaybeLogStateChange(new_state);
214 m_state = new_state;
215
216 m_stop_info.reason = StopReason::eStopReasonNone;
217 m_stop_description.clear();
218
219 // If watchpoints have been set, but none on this thread, then this is a new
220 // thread. So set all existing watchpoints.
221 if (m_watchpoint_index_map.empty()) {
222 NativeProcessLinux &process = GetProcess();
223
224 const auto &watchpoint_map = process.GetWatchpointMap();
225 m_reg_context_up->ClearAllHardwareWatchpoints();
226 for (const auto &pair : watchpoint_map) {
227 const auto &wp = pair.second;
228 SetWatchpoint(addr: wp.m_addr, size: wp.m_size, watch_flags: wp.m_watch_flags, hardware: wp.m_hardware);
229 }
230 }
231
232 // Set all active hardware breakpoint on all threads.
233 if (m_hw_break_index_map.empty()) {
234 NativeProcessLinux &process = GetProcess();
235
236 const auto &hw_breakpoint_map = process.GetHardwareBreakpointMap();
237 m_reg_context_up->ClearAllHardwareBreakpoints();
238 for (const auto &pair : hw_breakpoint_map) {
239 const auto &bp = pair.second;
240 SetHardwareBreakpoint(addr: bp.m_addr, size: bp.m_size);
241 }
242 }
243
244 intptr_t data = 0;
245
246 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
247 data = signo;
248
249 return NativeProcessLinux::PtraceWrapper(req: PTRACE_CONT, pid: GetID(), addr: nullptr,
250 data: reinterpret_cast<void *>(data));
251}
252
253Status NativeThreadLinux::SingleStep(uint32_t signo) {
254 const StateType new_state = StateType::eStateStepping;
255 MaybeLogStateChange(new_state);
256 m_state = new_state;
257 m_stop_info.reason = StopReason::eStopReasonNone;
258
259 if(!m_step_workaround) {
260 // If we already hava a workaround inplace, don't reset it. Otherwise, the
261 // destructor of the existing instance will run after the new instance has
262 // fetched the cpu mask, and the thread will end up with the wrong mask.
263 m_step_workaround = SingleStepWorkaround::Get(tid: m_tid);
264 }
265
266 intptr_t data = 0;
267 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
268 data = signo;
269
270 // If hardware single-stepping is not supported, we just do a continue. The
271 // breakpoint on the next instruction has been setup in
272 // NativeProcessLinux::Resume.
273 return NativeProcessLinux::PtraceWrapper(
274 req: GetProcess().SupportHardwareSingleStepping() ? PTRACE_SINGLESTEP
275 : PTRACE_CONT,
276 pid: m_tid, addr: nullptr, data: reinterpret_cast<void *>(data));
277}
278
279void NativeThreadLinux::SetStoppedBySignal(uint32_t signo,
280 const siginfo_t *info) {
281 Log *log = GetLog(mask: LLDBLog::Thread);
282 LLDB_LOGF(log, "NativeThreadLinux::%s called with signal 0x%02" PRIx32,
283 __FUNCTION__, signo);
284
285 SetStopped();
286
287 m_stop_info.reason = StopReason::eStopReasonSignal;
288 m_stop_info.signo = signo;
289
290 m_stop_description.clear();
291 if (info) {
292 switch (signo) {
293 case SIGSEGV:
294 case SIGBUS:
295 case SIGFPE:
296 case SIGILL:
297 m_stop_description = GetCrashReasonString(info: *info);
298#ifndef SEGV_MTESERR
299#define SEGV_MTESERR 9
300#endif
301 if (info->si_signo == SIGSEGV && info->si_code == SEGV_MTESERR)
302 AnnotateSyncTagCheckFault(
303 fault_addr: reinterpret_cast<lldb::addr_t>(info->si_addr));
304 break;
305 }
306 }
307}
308
309void NativeThreadLinux::AnnotateSyncTagCheckFault(lldb::addr_t fault_addr) {
310 int32_t allocation_tag_type = 0;
311 switch (GetProcess().GetArchitecture().GetMachine()) {
312 // aarch64_32 deliberately not here because there's no 32 bit MTE
313 case llvm::Triple::aarch64:
314 case llvm::Triple::aarch64_be:
315 allocation_tag_type = MemoryTagManagerAArch64MTE::eMTE_allocation;
316 break;
317 default:
318 return;
319 }
320
321 auto details =
322 GetRegisterContext().GetMemoryTaggingDetails(type: allocation_tag_type);
323 if (!details) {
324 llvm::consumeError(Err: details.takeError());
325 return;
326 }
327
328 // We assume that the stop description is currently:
329 // signal SIGSEGV: sync tag check fault (fault address: <addr>)
330 // Remove the closing )
331 m_stop_description.pop_back();
332
333 std::stringstream ss;
334 std::unique_ptr<MemoryTagManager> manager(std::move(details->manager));
335
336 ss << " logical tag: 0x" << std::hex << manager->GetLogicalTag(addr: fault_addr);
337
338 std::vector<uint8_t> allocation_tag_data;
339 // The fault address may not be granule aligned. ReadMemoryTags will granule
340 // align any range you give it, potentially making it larger.
341 // To prevent this set len to 1. This always results in a range that is at
342 // most 1 granule in size and includes fault_addr.
343 Status status = GetProcess().ReadMemoryTags(type: allocation_tag_type, addr: fault_addr,
344 len: 1, tags&: allocation_tag_data);
345
346 if (status.Success()) {
347 llvm::Expected<std::vector<lldb::addr_t>> allocation_tag =
348 manager->UnpackTagsData(tags: allocation_tag_data, granules: 1);
349 if (allocation_tag) {
350 ss << " allocation tag: 0x" << std::hex << allocation_tag->front() << ")";
351 } else {
352 llvm::consumeError(Err: allocation_tag.takeError());
353 ss << ")";
354 }
355 } else
356 ss << ")";
357
358 m_stop_description += ss.str();
359}
360
361bool NativeThreadLinux::IsStopped(int *signo) {
362 if (!StateIsStoppedState(state: m_state, must_exist: false))
363 return false;
364
365 // If we are stopped by a signal, return the signo.
366 if (signo && m_state == StateType::eStateStopped &&
367 m_stop_info.reason == StopReason::eStopReasonSignal) {
368 *signo = m_stop_info.signo;
369 }
370
371 // Regardless, we are stopped.
372 return true;
373}
374
375void NativeThreadLinux::SetStopped() {
376 if (m_state == StateType::eStateStepping)
377 m_step_workaround.reset();
378
379 // On every stop, clear any cached register data structures
380 GetRegisterContext().InvalidateAllRegisters();
381
382 const StateType new_state = StateType::eStateStopped;
383 MaybeLogStateChange(new_state);
384 m_state = new_state;
385 m_stop_description.clear();
386}
387
388void NativeThreadLinux::SetStoppedByExec() {
389 Log *log = GetLog(mask: LLDBLog::Thread);
390 LLDB_LOGF(log, "NativeThreadLinux::%s()", __FUNCTION__);
391
392 SetStopped();
393
394 m_stop_info.reason = StopReason::eStopReasonExec;
395 m_stop_info.signo = SIGSTOP;
396}
397
398void NativeThreadLinux::SetStoppedByBreakpoint() {
399 SetStopped();
400
401 m_stop_info.reason = StopReason::eStopReasonBreakpoint;
402 m_stop_info.signo = SIGTRAP;
403 m_stop_description.clear();
404}
405
406void NativeThreadLinux::SetStoppedByWatchpoint(uint32_t wp_index) {
407 SetStopped();
408
409 lldbassert(wp_index != LLDB_INVALID_INDEX32 && "wp_index cannot be invalid");
410
411 std::ostringstream ostr;
412 ostr << m_reg_context_up->GetWatchpointAddress(wp_index) << " ";
413 ostr << wp_index;
414
415 /*
416 * MIPS: Last 3bits of the watchpoint address are masked by the kernel. For
417 * example:
418 * 'n' is at 0x120010d00 and 'm' is 0x120010d04. When a watchpoint is set at
419 * 'm', then
420 * watch exception is generated even when 'n' is read/written. To handle this
421 * case,
422 * find the base address of the load/store instruction and append it in the
423 * stop-info
424 * packet.
425 */
426 ostr << " " << m_reg_context_up->GetWatchpointHitAddress(wp_index);
427
428 m_stop_description = ostr.str();
429
430 m_stop_info.reason = StopReason::eStopReasonWatchpoint;
431 m_stop_info.signo = SIGTRAP;
432}
433
434bool NativeThreadLinux::IsStoppedAtBreakpoint() {
435 return GetState() == StateType::eStateStopped &&
436 m_stop_info.reason == StopReason::eStopReasonBreakpoint;
437}
438
439bool NativeThreadLinux::IsStoppedAtWatchpoint() {
440 return GetState() == StateType::eStateStopped &&
441 m_stop_info.reason == StopReason::eStopReasonWatchpoint;
442}
443
444void NativeThreadLinux::SetStoppedByTrace() {
445 SetStopped();
446
447 m_stop_info.reason = StopReason::eStopReasonTrace;
448 m_stop_info.signo = SIGTRAP;
449}
450
451void NativeThreadLinux::SetStoppedByFork(bool is_vfork, lldb::pid_t child_pid) {
452 SetStopped();
453
454 m_stop_info.reason =
455 is_vfork ? StopReason::eStopReasonVFork : StopReason::eStopReasonFork;
456 m_stop_info.signo = SIGTRAP;
457 m_stop_info.details.fork.child_pid = child_pid;
458 m_stop_info.details.fork.child_tid = child_pid;
459 m_stop_description = std::to_string(val: child_pid);
460 m_stop_description += " ";
461 m_stop_description += std::to_string(val: child_pid);
462}
463
464void NativeThreadLinux::SetStoppedByVForkDone() {
465 SetStopped();
466
467 m_stop_info.reason = StopReason::eStopReasonVForkDone;
468 m_stop_info.signo = SIGTRAP;
469}
470
471void NativeThreadLinux::SetStoppedWithNoReason() {
472 SetStopped();
473
474 m_stop_info.reason = StopReason::eStopReasonNone;
475 m_stop_info.signo = 0;
476}
477
478void NativeThreadLinux::SetStoppedByProcessorTrace(
479 llvm::StringRef description) {
480 SetStopped();
481
482 m_stop_info.reason = StopReason::eStopReasonProcessorTrace;
483 m_stop_info.signo = 0;
484 m_stop_description = description.str();
485}
486
487void NativeThreadLinux::SetExited() {
488 const StateType new_state = StateType::eStateExited;
489 MaybeLogStateChange(new_state);
490 m_state = new_state;
491
492 m_stop_info.reason = StopReason::eStopReasonThreadExiting;
493}
494
495Status NativeThreadLinux::RequestStop() {
496 Log *log = GetLog(mask: LLDBLog::Thread);
497
498 NativeProcessLinux &process = GetProcess();
499
500 lldb::pid_t pid = process.GetID();
501 lldb::tid_t tid = GetID();
502
503 LLDB_LOGF(log,
504 "NativeThreadLinux::%s requesting thread stop(pid: %" PRIu64
505 ", tid: %" PRIu64 ")",
506 __FUNCTION__, pid, tid);
507
508 Status err;
509 errno = 0;
510 if (::tgkill(pid, tid, SIGSTOP) != 0) {
511 err.SetErrorToErrno();
512 LLDB_LOGF(log,
513 "NativeThreadLinux::%s tgkill(%" PRIu64 ", %" PRIu64
514 ", SIGSTOP) failed: %s",
515 __FUNCTION__, pid, tid, err.AsCString());
516 }
517
518 return err;
519}
520
521void NativeThreadLinux::MaybeLogStateChange(lldb::StateType new_state) {
522 Log *log = GetLog(mask: LLDBLog::Thread);
523 // If we're not logging, we're done.
524 if (!log)
525 return;
526
527 // If this is a state change to the same state, we're done.
528 lldb::StateType old_state = m_state;
529 if (new_state == old_state)
530 return;
531
532 LLDB_LOG(log, "pid={0}, tid={1}: changing from state {2} to {3}",
533 m_process.GetID(), GetID(), old_state, new_state);
534}
535
536NativeProcessLinux &NativeThreadLinux::GetProcess() {
537 return static_cast<NativeProcessLinux &>(m_process);
538}
539
540const NativeProcessLinux &NativeThreadLinux::GetProcess() const {
541 return static_cast<const NativeProcessLinux &>(m_process);
542}
543
544llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
545NativeThreadLinux::GetSiginfo() const {
546 auto siginfo_buf =
547 llvm::WritableMemoryBuffer::getNewUninitMemBuffer(Size: sizeof(siginfo_t));
548 Status error =
549 GetProcess().GetSignalInfo(tid: GetID(), siginfo: siginfo_buf->getBufferStart());
550 if (!error.Success())
551 return error.ToError();
552 return std::move(siginfo_buf);
553}
554

source code of lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp