1 //===-- NativeProcessFreeBSD.cpp ------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "NativeProcessFreeBSD.h"
12 #include <sys/types.h>
13 #include <sys/ptrace.h>
14 #include <sys/sysctl.h>
17 #include <machine/elf.h>
20 #include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
21 #include "lldb/Host/HostProcess.h"
22 #include "lldb/Host/posix/ProcessLauncherPosixFork.h"
23 #include "lldb/Target/Process.h"
24 #include "lldb/Utility/State.h"
25 #include "llvm/Support/Errno.h"
28 using namespace lldb_private
;
29 using namespace lldb_private::process_freebsd
;
32 // Simple helper function to ensure flags are enabled on the given file
34 static Status
EnsureFDFlags(int fd
, int flags
) {
37 int status
= fcntl(fd
, F_GETFL
);
39 error
.SetErrorToErrno();
43 if (fcntl(fd
, F_SETFL
, status
| flags
) == -1) {
44 error
.SetErrorToErrno();
51 // Public Static Methods
53 llvm::Expected
<std::unique_ptr
<NativeProcessProtocol
>>
54 NativeProcessFreeBSD::Manager::Launch(ProcessLaunchInfo
&launch_info
,
55 NativeDelegate
&native_delegate
) {
56 Log
*log
= GetLog(POSIXLog::Process
);
59 ::pid_t pid
= ProcessLauncherPosixFork()
60 .LaunchProcess(launch_info
, status
)
62 LLDB_LOG(log
, "pid = {0:x}", pid
);
64 LLDB_LOG(log
, "failed to launch process: {0}", status
);
65 return status
.ToError();
68 // Wait for the child process to trap on its call to execve.
70 ::pid_t wpid
= llvm::sys::RetryAfterSignal(-1, ::waitpid
, pid
, &wstatus
, 0);
73 if (!WIFSTOPPED(wstatus
)) {
74 LLDB_LOG(log
, "Could not sync with inferior process: wstatus={1}",
75 WaitStatus::Decode(wstatus
));
76 return llvm::make_error
<StringError
>("Could not sync with inferior process",
77 llvm::inconvertibleErrorCode());
79 LLDB_LOG(log
, "inferior started, now in stopped state");
81 ProcessInstanceInfo Info
;
82 if (!Host::GetProcessInfo(pid
, Info
)) {
83 return llvm::make_error
<StringError
>("Cannot get process architecture",
84 llvm::inconvertibleErrorCode());
87 // Set the architecture to the exe architecture.
88 LLDB_LOG(log
, "pid = {0:x}, detected architecture {1}", pid
,
89 Info
.GetArchitecture().GetArchitectureName());
91 std::unique_ptr
<NativeProcessFreeBSD
> process_up(new NativeProcessFreeBSD(
92 pid
, launch_info
.GetPTY().ReleasePrimaryFileDescriptor(), native_delegate
,
93 Info
.GetArchitecture(), m_mainloop
));
95 status
= process_up
->SetupTrace();
97 return status
.ToError();
99 for (const auto &thread
: process_up
->m_threads
)
100 static_cast<NativeThreadFreeBSD
&>(*thread
).SetStoppedBySignal(SIGSTOP
);
101 process_up
->SetState(StateType::eStateStopped
, false);
103 return std::move(process_up
);
106 llvm::Expected
<std::unique_ptr
<NativeProcessProtocol
>>
107 NativeProcessFreeBSD::Manager::Attach(
108 lldb::pid_t pid
, NativeProcessProtocol::NativeDelegate
&native_delegate
) {
109 Log
*log
= GetLog(POSIXLog::Process
);
110 LLDB_LOG(log
, "pid = {0:x}", pid
);
112 // Retrieve the architecture for the running process.
113 ProcessInstanceInfo Info
;
114 if (!Host::GetProcessInfo(pid
, Info
)) {
115 return llvm::make_error
<StringError
>("Cannot get process architecture",
116 llvm::inconvertibleErrorCode());
119 std::unique_ptr
<NativeProcessFreeBSD
> process_up(new NativeProcessFreeBSD(
120 pid
, -1, native_delegate
, Info
.GetArchitecture(), m_mainloop
));
122 Status status
= process_up
->Attach();
123 if (!status
.Success())
124 return status
.ToError();
126 return std::move(process_up
);
129 NativeProcessFreeBSD::Extension
130 NativeProcessFreeBSD::Manager::GetSupportedExtensions() const {
132 #if defined(PT_COREDUMP)
133 Extension::savecore
|
135 Extension::multiprocess
| Extension::fork
| Extension::vfork
|
136 Extension::pass_signals
| Extension::auxv
| Extension::libraries_svr4
|
137 Extension::siginfo_read
;
140 // Public Instance Methods
142 NativeProcessFreeBSD::NativeProcessFreeBSD(::pid_t pid
, int terminal_fd
,
143 NativeDelegate
&delegate
,
144 const ArchSpec
&arch
,
146 : NativeProcessELF(pid
, terminal_fd
, delegate
), m_arch(arch
),
147 m_main_loop(mainloop
) {
148 if (m_terminal_fd
!= -1) {
149 Status status
= EnsureFDFlags(m_terminal_fd
, O_NONBLOCK
);
150 assert(status
.Success());
154 m_sigchld_handle
= mainloop
.RegisterSignal(
155 SIGCHLD
, [this](MainLoopBase
&) { SigchldHandler(); }, status
);
156 assert(m_sigchld_handle
&& status
.Success());
159 // Handles all waitpid events from the inferior process.
160 void NativeProcessFreeBSD::MonitorCallback(lldb::pid_t pid
, int signal
) {
163 return MonitorSIGTRAP(pid
);
165 return MonitorSIGSTOP(pid
);
167 return MonitorSignal(pid
, signal
);
171 void NativeProcessFreeBSD::MonitorExited(lldb::pid_t pid
, WaitStatus status
) {
172 Log
*log
= GetLog(POSIXLog::Process
);
174 LLDB_LOG(log
, "got exit signal({0}) , pid = {1}", status
, pid
);
176 /* Stop Tracking All Threads attached to Process */
179 SetExitStatus(status
, true);
181 // Notify delegate that our process has exited.
182 SetState(StateType::eStateExited
, true);
185 void NativeProcessFreeBSD::MonitorSIGSTOP(lldb::pid_t pid
) {
186 /* Stop all Threads attached to Process */
187 for (const auto &thread
: m_threads
) {
188 static_cast<NativeThreadFreeBSD
&>(*thread
).SetStoppedBySignal(SIGSTOP
,
191 SetState(StateType::eStateStopped
, true);
194 void NativeProcessFreeBSD::MonitorSIGTRAP(lldb::pid_t pid
) {
195 Log
*log
= GetLog(POSIXLog::Process
);
196 struct ptrace_lwpinfo info
;
198 const auto siginfo_err
= PtraceWrapper(PT_LWPINFO
, pid
, &info
, sizeof(info
));
199 if (siginfo_err
.Fail()) {
200 LLDB_LOG(log
, "PT_LWPINFO failed {0}", siginfo_err
);
203 assert(info
.pl_event
== PL_EVENT_SIGNAL
);
205 LLDB_LOG(log
, "got SIGTRAP, pid = {0}, lwpid = {1}, flags = {2:x}", pid
,
206 info
.pl_lwpid
, info
.pl_flags
);
207 NativeThreadFreeBSD
*thread
= nullptr;
209 if (info
.pl_flags
& (PL_FLAG_BORN
| PL_FLAG_EXITED
)) {
210 if (info
.pl_flags
& PL_FLAG_BORN
) {
211 LLDB_LOG(log
, "monitoring new thread, tid = {0}", info
.pl_lwpid
);
212 NativeThreadFreeBSD
&t
= AddThread(info
.pl_lwpid
);
214 // Technically, the FreeBSD kernel copies the debug registers to new
215 // threads. However, there is a non-negligible delay between acquiring
216 // the DR values and reporting the new thread during which the user may
217 // establish a new watchpoint. In order to ensure that watchpoints
218 // established during this period are propagated to new threads,
219 // explicitly copy the DR value at the time the new thread is reported.
221 // See also: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=250954
223 llvm::Error error
= t
.CopyWatchpointsFrom(
224 static_cast<NativeThreadFreeBSD
&>(*GetCurrentThread()));
226 LLDB_LOG_ERROR(log
, std::move(error
),
227 "failed to copy watchpoints to new thread {1}: {0}",
229 SetState(StateType::eStateInvalid
);
232 } else /*if (info.pl_flags & PL_FLAG_EXITED)*/ {
233 LLDB_LOG(log
, "thread exited, tid = {0}", info
.pl_lwpid
);
234 RemoveThread(info
.pl_lwpid
);
238 PtraceWrapper(PT_CONTINUE
, pid
, reinterpret_cast<void *>(1), 0);
240 SetState(StateType::eStateInvalid
);
244 if (info
.pl_flags
& PL_FLAG_EXEC
) {
245 Status error
= ReinitializeThreads();
247 SetState(StateType::eStateInvalid
);
251 // Let our delegate know we have just exec'd.
254 for (const auto &thread
: m_threads
)
255 static_cast<NativeThreadFreeBSD
&>(*thread
).SetStoppedByExec();
256 SetCurrentThreadID(m_threads
.front()->GetID());
257 SetState(StateType::eStateStopped
, true);
261 if (info
.pl_lwpid
> 0) {
262 for (const auto &t
: m_threads
) {
263 if (t
->GetID() == static_cast<lldb::tid_t
>(info
.pl_lwpid
))
264 thread
= static_cast<NativeThreadFreeBSD
*>(t
.get());
265 static_cast<NativeThreadFreeBSD
*>(t
.get())->SetStoppedWithNoReason();
268 LLDB_LOG(log
, "thread not found in m_threads, pid = {0}, LWP = {1}", pid
,
272 if (info
.pl_flags
& PL_FLAG_FORKED
) {
274 MonitorClone(info
.pl_child_pid
, info
.pl_flags
& PL_FLAG_VFORKED
, *thread
);
278 if (info
.pl_flags
& PL_FLAG_VFORK_DONE
) {
280 if ((m_enabled_extensions
& Extension::vfork
) == Extension::vfork
) {
281 thread
->SetStoppedByVForkDone();
282 SetState(StateType::eStateStopped
, true);
285 PtraceWrapper(PT_CONTINUE
, pid
, reinterpret_cast<void *>(1), 0);
287 SetState(StateType::eStateInvalid
);
292 if (info
.pl_flags
& PL_FLAG_SI
) {
293 assert(info
.pl_siginfo
.si_signo
== SIGTRAP
);
294 LLDB_LOG(log
, "SIGTRAP siginfo: si_code = {0}, pid = {1}",
295 info
.pl_siginfo
.si_code
, info
.pl_siginfo
.si_pid
);
297 switch (info
.pl_siginfo
.si_code
) {
299 LLDB_LOG(log
, "SIGTRAP/TRAP_BRKPT: si_addr: {0}",
300 info
.pl_siginfo
.si_addr
);
304 m_threads_stepping_with_breakpoint
.find(thread
->GetID());
305 if (thread_info
!= m_threads_stepping_with_breakpoint
.end()) {
306 thread
->SetStoppedByTrace();
307 Status brkpt_error
= RemoveBreakpoint(thread_info
->second
);
308 if (brkpt_error
.Fail())
309 LLDB_LOG(log
, "pid = {0} remove stepping breakpoint: {1}",
310 thread_info
->first
, brkpt_error
);
311 m_threads_stepping_with_breakpoint
.erase(thread_info
);
313 thread
->SetStoppedByBreakpoint();
314 FixupBreakpointPCAsNeeded(*thread
);
315 SetCurrentThreadID(thread
->GetID());
317 SetState(StateType::eStateStopped
, true);
320 LLDB_LOG(log
, "SIGTRAP/TRAP_TRACE: si_addr: {0}",
321 info
.pl_siginfo
.si_addr
);
324 auto ®ctx
= static_cast<NativeRegisterContextFreeBSD
&>(
325 thread
->GetRegisterContext());
326 uint32_t wp_index
= LLDB_INVALID_INDEX32
;
327 Status error
= regctx
.GetWatchpointHitIndex(
328 wp_index
, reinterpret_cast<uintptr_t>(info
.pl_siginfo
.si_addr
));
331 "received error while checking for watchpoint hits, pid = "
332 "{0}, LWP = {1}, error = {2}",
333 pid
, info
.pl_lwpid
, error
);
334 if (wp_index
!= LLDB_INVALID_INDEX32
) {
335 regctx
.ClearWatchpointHit(wp_index
);
336 thread
->SetStoppedByWatchpoint(wp_index
);
337 SetCurrentThreadID(thread
->GetID());
338 SetState(StateType::eStateStopped
, true);
342 thread
->SetStoppedByTrace();
343 SetCurrentThreadID(thread
->GetID());
346 SetState(StateType::eStateStopped
, true);
351 // Either user-generated SIGTRAP or an unknown event that would
352 // otherwise leave the debugger hanging.
353 LLDB_LOG(log
, "unknown SIGTRAP, passing to generic handler");
354 MonitorSignal(pid
, SIGTRAP
);
357 void NativeProcessFreeBSD::MonitorSignal(lldb::pid_t pid
, int signal
) {
358 Log
*log
= GetLog(POSIXLog::Process
);
359 struct ptrace_lwpinfo info
;
361 const auto siginfo_err
= PtraceWrapper(PT_LWPINFO
, pid
, &info
, sizeof(info
));
362 if (siginfo_err
.Fail()) {
363 LLDB_LOG(log
, "PT_LWPINFO failed {0}", siginfo_err
);
366 assert(info
.pl_event
== PL_EVENT_SIGNAL
);
367 // TODO: do we need to handle !PL_FLAG_SI?
368 assert(info
.pl_flags
& PL_FLAG_SI
);
369 assert(info
.pl_siginfo
.si_signo
== signal
);
371 for (const auto &abs_thread
: m_threads
) {
372 NativeThreadFreeBSD
&thread
=
373 static_cast<NativeThreadFreeBSD
&>(*abs_thread
);
374 assert(info
.pl_lwpid
>= 0);
375 if (info
.pl_lwpid
== 0 ||
376 static_cast<lldb::tid_t
>(info
.pl_lwpid
) == thread
.GetID()) {
377 thread
.SetStoppedBySignal(info
.pl_siginfo
.si_signo
, &info
.pl_siginfo
);
378 SetCurrentThreadID(thread
.GetID());
380 thread
.SetStoppedWithNoReason();
382 SetState(StateType::eStateStopped
, true);
385 Status
NativeProcessFreeBSD::PtraceWrapper(int req
, lldb::pid_t pid
, void *addr
,
386 int data
, int *result
) {
387 Log
*log
= GetLog(POSIXLog::Ptrace
);
393 ptrace(req
, static_cast<::pid_t
>(pid
), static_cast<caddr_t
>(addr
), data
);
396 error
.SetErrorToErrno();
401 LLDB_LOG(log
, "ptrace({0}, {1}, {2}, {3})={4:x}", req
, pid
, addr
, data
, ret
);
404 LLDB_LOG(log
, "ptrace() failed: {0}", error
);
409 llvm::Expected
<llvm::ArrayRef
<uint8_t>>
410 NativeProcessFreeBSD::GetSoftwareBreakpointTrapOpcode(size_t size_hint
) {
411 static const uint8_t g_arm_opcode
[] = {0xfe, 0xde, 0xff, 0xe7};
412 static const uint8_t g_thumb_opcode
[] = {0x01, 0xde};
414 switch (GetArchitecture().GetMachine()) {
415 case llvm::Triple::arm
:
418 return llvm::ArrayRef(g_thumb_opcode
);
420 return llvm::ArrayRef(g_arm_opcode
);
422 return llvm::createStringError(llvm::inconvertibleErrorCode(),
423 "Unrecognised trap opcode size hint!");
426 return NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_hint
);
430 Status
NativeProcessFreeBSD::Resume(const ResumeActionList
&resume_actions
) {
431 Log
*log
= GetLog(POSIXLog::Process
);
432 LLDB_LOG(log
, "pid {0}", GetID());
437 for (const auto &abs_thread
: m_threads
) {
438 assert(abs_thread
&& "thread list should not contain NULL threads");
439 NativeThreadFreeBSD
&thread
=
440 static_cast<NativeThreadFreeBSD
&>(*abs_thread
);
442 const ResumeAction
*action
=
443 resume_actions
.GetActionForThread(thread
.GetID(), true);
444 // we need to explicit issue suspend requests, so it is simpler to map it
445 // into proper action
446 ResumeAction suspend_action
{thread
.GetID(), eStateSuspended
,
447 LLDB_INVALID_SIGNAL_NUMBER
};
449 if (action
== nullptr) {
450 LLDB_LOG(log
, "no action specified for pid {0} tid {1}", GetID(),
452 action
= &suspend_action
;
457 "processing resume action state {0} signal {1} for pid {2} tid {3}",
458 action
->state
, action
->signal
, GetID(), thread
.GetID());
460 switch (action
->state
) {
462 ret
= thread
.Resume();
465 ret
= thread
.SingleStep();
467 case eStateSuspended
:
469 if (action
->signal
!= LLDB_INVALID_SIGNAL_NUMBER
)
470 return Status("Passing signal to suspended thread unsupported");
472 ret
= thread
.Suspend();
477 "NativeProcessFreeBSD::%s (): unexpected state %s specified "
478 "for pid %" PRIu64
", tid %" PRIu64
,
479 __FUNCTION__
, StateAsCString(action
->state
), GetID(), thread
.GetID());
484 if (action
->signal
!= LLDB_INVALID_SIGNAL_NUMBER
)
485 signal
= action
->signal
;
489 PtraceWrapper(PT_CONTINUE
, GetID(), reinterpret_cast<void *>(1), signal
);
491 SetState(eStateRunning
, true);
495 Status
NativeProcessFreeBSD::Halt() {
498 // Do not try to stop a process that's already stopped, this may cause
499 // the SIGSTOP to get queued and stop the process again once resumed.
500 if (StateIsStoppedState(m_state
, false))
502 if (kill(GetID(), SIGSTOP
) != 0)
503 error
.SetErrorToErrno();
507 Status
NativeProcessFreeBSD::Detach() {
510 // Stop monitoring the inferior.
511 m_sigchld_handle
.reset();
513 // Tell ptrace to detach from the process.
514 if (GetID() == LLDB_INVALID_PROCESS_ID
)
517 return PtraceWrapper(PT_DETACH
, GetID());
520 Status
NativeProcessFreeBSD::Signal(int signo
) {
523 if (kill(GetID(), signo
))
524 error
.SetErrorToErrno();
529 Status
NativeProcessFreeBSD::Interrupt() { return Halt(); }
531 Status
NativeProcessFreeBSD::Kill() {
532 Log
*log
= GetLog(POSIXLog::Process
);
533 LLDB_LOG(log
, "pid {0}", GetID());
538 case StateType::eStateInvalid
:
539 case StateType::eStateExited
:
540 case StateType::eStateCrashed
:
541 case StateType::eStateDetached
:
542 case StateType::eStateUnloaded
:
543 // Nothing to do - the process is already dead.
544 LLDB_LOG(log
, "ignored for PID {0} due to current state: {1}", GetID(),
545 StateAsCString(m_state
));
548 case StateType::eStateConnected
:
549 case StateType::eStateAttaching
:
550 case StateType::eStateLaunching
:
551 case StateType::eStateStopped
:
552 case StateType::eStateRunning
:
553 case StateType::eStateStepping
:
554 case StateType::eStateSuspended
:
555 // We can try to kill a process in these states.
559 return PtraceWrapper(PT_KILL
, m_pid
);
562 Status
NativeProcessFreeBSD::GetMemoryRegionInfo(lldb::addr_t load_addr
,
563 MemoryRegionInfo
&range_info
) {
565 if (m_supports_mem_region
== LazyBool::eLazyBoolNo
) {
567 return Status("unsupported");
570 Status error
= PopulateMemoryRegionCache();
575 lldb::addr_t prev_base_address
= 0;
576 // FIXME start by finding the last region that is <= target address using
577 // binary search. Data is sorted.
578 // There can be a ton of regions on pthreads apps with lots of threads.
579 for (auto it
= m_mem_region_cache
.begin(); it
!= m_mem_region_cache
.end();
581 MemoryRegionInfo
&proc_entry_info
= it
->first
;
582 // Sanity check assumption that memory map entries are ascending.
583 assert((proc_entry_info
.GetRange().GetRangeBase() >= prev_base_address
) &&
584 "descending memory map entries detected, unexpected");
585 prev_base_address
= proc_entry_info
.GetRange().GetRangeBase();
586 UNUSED_IF_ASSERT_DISABLED(prev_base_address
);
587 // If the target address comes before this entry, indicate distance to next
589 if (load_addr
< proc_entry_info
.GetRange().GetRangeBase()) {
590 range_info
.GetRange().SetRangeBase(load_addr
);
591 range_info
.GetRange().SetByteSize(
592 proc_entry_info
.GetRange().GetRangeBase() - load_addr
);
593 range_info
.SetReadable(MemoryRegionInfo::OptionalBool::eNo
);
594 range_info
.SetWritable(MemoryRegionInfo::OptionalBool::eNo
);
595 range_info
.SetExecutable(MemoryRegionInfo::OptionalBool::eNo
);
596 range_info
.SetMapped(MemoryRegionInfo::OptionalBool::eNo
);
598 } else if (proc_entry_info
.GetRange().Contains(load_addr
)) {
599 // The target address is within the memory region we're processing here.
600 range_info
= proc_entry_info
;
603 // The target memory address comes somewhere after the region we just
606 // If we made it here, we didn't find an entry that contained the given
607 // address. Return the load_addr as start and the amount of bytes betwwen
608 // load address and the end of the memory as size.
609 range_info
.GetRange().SetRangeBase(load_addr
);
610 range_info
.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS
);
611 range_info
.SetReadable(MemoryRegionInfo::OptionalBool::eNo
);
612 range_info
.SetWritable(MemoryRegionInfo::OptionalBool::eNo
);
613 range_info
.SetExecutable(MemoryRegionInfo::OptionalBool::eNo
);
614 range_info
.SetMapped(MemoryRegionInfo::OptionalBool::eNo
);
618 Status
NativeProcessFreeBSD::PopulateMemoryRegionCache() {
619 Log
*log
= GetLog(POSIXLog::Process
);
620 // If our cache is empty, pull the latest. There should always be at least
621 // one memory region if memory region handling is supported.
622 if (!m_mem_region_cache
.empty()) {
623 LLDB_LOG(log
, "reusing {0} cached memory region entries",
624 m_mem_region_cache
.size());
628 int mib
[4] = {CTL_KERN
, KERN_PROC
, KERN_PROC_VMMAP
, static_cast<int>(m_pid
)};
632 ret
= ::sysctl(mib
, 4, nullptr, &len
, nullptr, 0);
634 m_supports_mem_region
= LazyBool::eLazyBoolNo
;
635 return Status("sysctl() for KERN_PROC_VMMAP failed");
638 std::unique_ptr
<WritableMemoryBuffer
> buf
=
639 llvm::WritableMemoryBuffer::getNewMemBuffer(len
);
640 ret
= ::sysctl(mib
, 4, buf
->getBufferStart(), &len
, nullptr, 0);
642 m_supports_mem_region
= LazyBool::eLazyBoolNo
;
643 return Status("sysctl() for KERN_PROC_VMMAP failed");
646 char *bp
= buf
->getBufferStart();
647 char *end
= bp
+ len
;
649 auto *kv
= reinterpret_cast<struct kinfo_vmentry
*>(bp
);
650 if (kv
->kve_structsize
== 0)
652 bp
+= kv
->kve_structsize
;
654 MemoryRegionInfo info
;
656 info
.GetRange().SetRangeBase(kv
->kve_start
);
657 info
.GetRange().SetRangeEnd(kv
->kve_end
);
658 info
.SetMapped(MemoryRegionInfo::OptionalBool::eYes
);
660 if (kv
->kve_protection
& VM_PROT_READ
)
661 info
.SetReadable(MemoryRegionInfo::OptionalBool::eYes
);
663 info
.SetReadable(MemoryRegionInfo::OptionalBool::eNo
);
665 if (kv
->kve_protection
& VM_PROT_WRITE
)
666 info
.SetWritable(MemoryRegionInfo::OptionalBool::eYes
);
668 info
.SetWritable(MemoryRegionInfo::OptionalBool::eNo
);
670 if (kv
->kve_protection
& VM_PROT_EXECUTE
)
671 info
.SetExecutable(MemoryRegionInfo::OptionalBool::eYes
);
673 info
.SetExecutable(MemoryRegionInfo::OptionalBool::eNo
);
676 info
.SetName(kv
->kve_path
);
678 m_mem_region_cache
.emplace_back(info
,
679 FileSpec(info
.GetName().GetCString()));
682 if (m_mem_region_cache
.empty()) {
683 // No entries after attempting to read them. This shouldn't happen. Assume
684 // we don't support map entries.
685 LLDB_LOG(log
, "failed to find any vmmap entries, assuming no support "
686 "for memory region metadata retrieval");
687 m_supports_mem_region
= LazyBool::eLazyBoolNo
;
688 return Status("not supported");
690 LLDB_LOG(log
, "read {0} memory region entries from process {1}",
691 m_mem_region_cache
.size(), GetID());
692 // We support memory retrieval, remember that.
693 m_supports_mem_region
= LazyBool::eLazyBoolYes
;
698 size_t NativeProcessFreeBSD::UpdateThreads() { return m_threads
.size(); }
700 Status
NativeProcessFreeBSD::SetBreakpoint(lldb::addr_t addr
, uint32_t size
,
703 return SetHardwareBreakpoint(addr
, size
);
704 return SetSoftwareBreakpoint(addr
, size
);
707 Status
NativeProcessFreeBSD::GetLoadedModuleFileSpec(const char *module_path
,
708 FileSpec
&file_spec
) {
709 Status error
= PopulateMemoryRegionCache();
713 FileSpec
module_file_spec(module_path
);
714 FileSystem::Instance().Resolve(module_file_spec
);
717 for (const auto &it
: m_mem_region_cache
) {
718 if (it
.second
.GetFilename() == module_file_spec
.GetFilename()) {
719 file_spec
= it
.second
;
723 return Status("Module file (%s) not found in process' memory map!",
724 module_file_spec
.GetFilename().AsCString());
728 NativeProcessFreeBSD::GetFileLoadAddress(const llvm::StringRef
&file_name
,
729 lldb::addr_t
&load_addr
) {
730 load_addr
= LLDB_INVALID_ADDRESS
;
731 Status error
= PopulateMemoryRegionCache();
735 FileSpec
file(file_name
);
736 for (const auto &it
: m_mem_region_cache
) {
737 if (it
.second
== file
) {
738 load_addr
= it
.first
.GetRange().GetRangeBase();
742 return Status("No load address found for file %s.", file_name
.str().c_str());
745 void NativeProcessFreeBSD::SigchldHandler() {
746 Log
*log
= GetLog(POSIXLog::Process
);
749 llvm::sys::RetryAfterSignal(-1, waitpid
, GetID(), &status
, WNOHANG
);
754 if (wait_pid
== -1) {
755 Status
error(errno
, eErrorTypePOSIX
);
756 LLDB_LOG(log
, "waitpid ({0}, &status, _) failed: {1}", GetID(), error
);
760 WaitStatus wait_status
= WaitStatus::Decode(status
);
761 bool exited
= wait_status
.type
== WaitStatus::Exit
||
762 (wait_status
.type
== WaitStatus::Signal
&&
763 wait_pid
== static_cast<::pid_t
>(GetID()));
766 "waitpid ({0}, &status, _) => pid = {1}, status = {2}, exited = {3}",
767 GetID(), wait_pid
, status
, exited
);
770 MonitorExited(wait_pid
, wait_status
);
772 assert(wait_status
.type
== WaitStatus::Stop
);
773 MonitorCallback(wait_pid
, wait_status
.status
);
777 bool NativeProcessFreeBSD::HasThreadNoLock(lldb::tid_t thread_id
) {
778 for (const auto &thread
: m_threads
) {
779 assert(thread
&& "thread list should not contain NULL threads");
780 if (thread
->GetID() == thread_id
) {
781 // We have this thread.
786 // We don't have this thread.
790 NativeThreadFreeBSD
&NativeProcessFreeBSD::AddThread(lldb::tid_t thread_id
) {
791 Log
*log
= GetLog(POSIXLog::Thread
);
792 LLDB_LOG(log
, "pid {0} adding thread with tid {1}", GetID(), thread_id
);
794 assert(thread_id
> 0);
795 assert(!HasThreadNoLock(thread_id
) &&
796 "attempted to add a thread by id that already exists");
798 // If this is the first thread, save it as the current thread
799 if (m_threads
.empty())
800 SetCurrentThreadID(thread_id
);
802 m_threads
.push_back(std::make_unique
<NativeThreadFreeBSD
>(*this, thread_id
));
803 return static_cast<NativeThreadFreeBSD
&>(*m_threads
.back());
806 void NativeProcessFreeBSD::RemoveThread(lldb::tid_t thread_id
) {
807 Log
*log
= GetLog(POSIXLog::Thread
);
808 LLDB_LOG(log
, "pid {0} removing thread with tid {1}", GetID(), thread_id
);
810 assert(thread_id
> 0);
811 assert(HasThreadNoLock(thread_id
) &&
812 "attempted to remove a thread that does not exist");
814 for (auto it
= m_threads
.begin(); it
!= m_threads
.end(); ++it
) {
815 if ((*it
)->GetID() == thread_id
) {
821 if (GetCurrentThreadID() == thread_id
)
822 SetCurrentThreadID(m_threads
.front()->GetID());
825 Status
NativeProcessFreeBSD::Attach() {
826 // Attach to the requested process.
827 // An attach will cause the thread to stop with a SIGSTOP.
828 Status status
= PtraceWrapper(PT_ATTACH
, m_pid
);
833 // Need to use WALLSIG otherwise we receive an error with errno=ECHLD At this
834 // point we should have a thread stopped if waitpid succeeds.
835 if ((wstatus
= llvm::sys::RetryAfterSignal(-1, waitpid
, m_pid
, nullptr, 0)) <
837 return Status(errno
, eErrorTypePOSIX
);
839 // Initialize threads and tracing status
840 // NB: this needs to be called before we set thread state
841 status
= SetupTrace();
845 for (const auto &thread
: m_threads
)
846 static_cast<NativeThreadFreeBSD
&>(*thread
).SetStoppedBySignal(SIGSTOP
);
848 // Let our process instance know the thread has stopped.
849 SetCurrentThreadID(m_threads
.front()->GetID());
850 SetState(StateType::eStateStopped
, false);
854 Status
NativeProcessFreeBSD::ReadMemory(lldb::addr_t addr
, void *buf
,
855 size_t size
, size_t &bytes_read
) {
856 unsigned char *dst
= static_cast<unsigned char *>(buf
);
857 struct ptrace_io_desc io
;
859 Log
*log
= GetLog(POSIXLog::Memory
);
860 LLDB_LOG(log
, "addr = {0}, buf = {1}, size = {2}", addr
, buf
, size
);
863 io
.piod_op
= PIOD_READ_D
;
867 io
.piod_offs
= (void *)(addr
+ bytes_read
);
868 io
.piod_addr
= dst
+ bytes_read
;
870 Status error
= NativeProcessFreeBSD::PtraceWrapper(PT_IO
, GetID(), &io
);
871 if (error
.Fail() || io
.piod_len
== 0)
874 bytes_read
+= io
.piod_len
;
875 io
.piod_len
= size
- bytes_read
;
876 } while (bytes_read
< size
);
881 Status
NativeProcessFreeBSD::WriteMemory(lldb::addr_t addr
, const void *buf
,
882 size_t size
, size_t &bytes_written
) {
883 const unsigned char *src
= static_cast<const unsigned char *>(buf
);
885 struct ptrace_io_desc io
;
887 Log
*log
= GetLog(POSIXLog::Memory
);
888 LLDB_LOG(log
, "addr = {0}, buf = {1}, size = {2}", addr
, buf
, size
);
891 io
.piod_op
= PIOD_WRITE_D
;
896 const_cast<void *>(static_cast<const void *>(src
+ bytes_written
));
897 io
.piod_offs
= (void *)(addr
+ bytes_written
);
899 Status error
= NativeProcessFreeBSD::PtraceWrapper(PT_IO
, GetID(), &io
);
900 if (error
.Fail() || io
.piod_len
== 0)
903 bytes_written
+= io
.piod_len
;
904 io
.piod_len
= size
- bytes_written
;
905 } while (bytes_written
< size
);
910 llvm::ErrorOr
<std::unique_ptr
<llvm::MemoryBuffer
>>
911 NativeProcessFreeBSD::GetAuxvData() const {
912 int mib
[4] = {CTL_KERN
, KERN_PROC
, KERN_PROC_AUXV
, static_cast<int>(GetID())};
913 size_t auxv_size
= AT_COUNT
* sizeof(Elf_Auxinfo
);
914 std::unique_ptr
<WritableMemoryBuffer
> buf
=
915 llvm::WritableMemoryBuffer::getNewMemBuffer(auxv_size
);
917 if (::sysctl(mib
, 4, buf
->getBufferStart(), &auxv_size
, nullptr, 0) != 0)
918 return std::error_code(errno
, std::generic_category());
923 Status
NativeProcessFreeBSD::SetupTrace() {
924 // Enable event reporting
927 PtraceWrapper(PT_GET_EVENT_MASK
, GetID(), &events
, sizeof(events
));
930 events
|= PTRACE_LWP
| PTRACE_FORK
| PTRACE_VFORK
;
931 status
= PtraceWrapper(PT_SET_EVENT_MASK
, GetID(), &events
, sizeof(events
));
935 return ReinitializeThreads();
938 Status
NativeProcessFreeBSD::ReinitializeThreads() {
943 Status error
= PtraceWrapper(PT_GETNUMLWPS
, GetID(), nullptr, 0, &num_lwps
);
947 std::vector
<lwpid_t
> lwp_ids
;
948 lwp_ids
.resize(num_lwps
);
949 error
= PtraceWrapper(PT_GETLWPLIST
, GetID(), lwp_ids
.data(),
950 lwp_ids
.size() * sizeof(lwpid_t
), &num_lwps
);
954 // Reinitialize from scratch threads and register them in process
955 for (lwpid_t lwp
: lwp_ids
)
961 bool NativeProcessFreeBSD::SupportHardwareSingleStepping() const {
962 return !m_arch
.IsMIPS();
965 void NativeProcessFreeBSD::MonitorClone(::pid_t child_pid
, bool is_vfork
,
966 NativeThreadFreeBSD
&parent_thread
) {
967 Log
*log
= GetLog(POSIXLog::Process
);
968 LLDB_LOG(log
, "fork, child_pid={0}", child_pid
);
972 llvm::sys::RetryAfterSignal(-1, ::waitpid
, child_pid
, &status
, 0);
973 if (wait_pid
!= child_pid
) {
975 "waiting for pid {0} failed. Assuming the pid has "
976 "disappeared in the meantime",
980 if (WIFEXITED(status
)) {
982 "waiting for pid {0} returned an 'exited' event. Not "
988 struct ptrace_lwpinfo info
;
989 const auto siginfo_err
= PtraceWrapper(PT_LWPINFO
, child_pid
, &info
, sizeof(info
));
990 if (siginfo_err
.Fail()) {
991 LLDB_LOG(log
, "PT_LWPINFO failed {0}", siginfo_err
);
994 assert(info
.pl_event
== PL_EVENT_SIGNAL
);
995 lldb::tid_t child_tid
= info
.pl_lwpid
;
997 std::unique_ptr
<NativeProcessFreeBSD
> child_process
{
998 new NativeProcessFreeBSD(static_cast<::pid_t
>(child_pid
), m_terminal_fd
,
999 m_delegate
, m_arch
, m_main_loop
)};
1001 child_process
->m_software_breakpoints
= m_software_breakpoints
;
1003 Extension expected_ext
= is_vfork
? Extension::vfork
: Extension::fork
;
1004 if ((m_enabled_extensions
& expected_ext
) == expected_ext
) {
1005 child_process
->SetupTrace();
1006 for (const auto &thread
: child_process
->m_threads
)
1007 static_cast<NativeThreadFreeBSD
&>(*thread
).SetStoppedBySignal(SIGSTOP
);
1008 child_process
->SetState(StateType::eStateStopped
, false);
1010 m_delegate
.NewSubprocess(this, std::move(child_process
));
1012 parent_thread
.SetStoppedByVFork(child_pid
, child_tid
);
1014 parent_thread
.SetStoppedByFork(child_pid
, child_tid
);
1015 SetState(StateType::eStateStopped
, true);
1017 child_process
->Detach();
1019 PtraceWrapper(PT_CONTINUE
, GetID(), reinterpret_cast<void *>(1), 0);
1020 if (pt_error
.Fail()) {
1021 LLDB_LOG_ERROR(log
, pt_error
.ToError(),
1022 "unable to resume parent process {1}: {0}", GetID());
1023 SetState(StateType::eStateInvalid
);
1028 llvm::Expected
<std::string
>
1029 NativeProcessFreeBSD::SaveCore(llvm::StringRef path_hint
) {
1030 #if defined(PT_COREDUMP)
1031 using namespace llvm::sys::fs
;
1033 llvm::SmallString
<128> path
{path_hint
};
1035 struct ptrace_coredump pc
= {};
1037 // Try with the suggested path first. If there is no suggested path or it
1038 // failed to open, use a temporary file.
1040 openFile(path
, pc
.pc_fd
, CD_CreateNew
, FA_Write
, OF_None
)) {
1041 if (std::error_code errc
=
1042 createTemporaryFile("lldb", "core", pc
.pc_fd
, path
))
1043 return llvm::createStringError(errc
, "Unable to create a temporary file");
1045 error
= PtraceWrapper(PT_COREDUMP
, GetID(), &pc
, sizeof(pc
));
1047 std::error_code close_err
= closeFile(pc
.pc_fd
);
1049 return error
.ToError();
1051 return llvm::createStringError(
1052 close_err
, "Unable to close the core dump after writing");
1053 return path
.str().str();
1054 #else // !defined(PT_COREDUMP)
1055 return llvm::createStringError(
1056 llvm::inconvertibleErrorCode(),
1057 "PT_COREDUMP not supported in the FreeBSD version used to build LLDB");