Bug Summary

File:src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp
Warning:line 473, column 8
Although the value stored to 'wstatus' is used in the enclosing expression, the value is never actually read from 'wstatus'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name NativeProcessOpenBSD.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/llvm/include -I /usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../include -I /usr/src/gnu/usr.bin/clang/liblldbPluginProcess/obj -I /usr/src/gnu/usr.bin/clang/liblldbPluginProcess/obj/../include -D NDEBUG -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D LLVM_PREFIX="/usr" -I /usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/include -I /usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source -I /usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/clang/include -I /usr/src/gnu/usr.bin/clang/liblldbPluginProcess/obj/../include/lldb/Plugins -internal-isystem /usr/include/c++/v1 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/obj -ferror-limit 19 -fvisibility-inlines-hidden -fwrapv -stack-protector 2 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c++ /usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp
1//===-- NativeProcessOpenBSD.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 "NativeProcessOpenBSD.h"
11
12// C Includes
13#include <errno(*__errno()).h>
14#define _DYN_LOADER
15#include <elf.h>
16#include <util.h>
17
18// C++ Includes
19
20#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
21#include "lldb/Host/HostProcess.h"
22#include "lldb/Host/common/NativeRegisterContext.h"
23#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
24#include "llvm/Support/Errno.h"
25#include "lldb/Target/Process.h"
26#include "lldb/Utility/State.h"
27
28// System includes - They have to be included after framework includes because
29// they define some macros which collide with variable names in other modules
30// clang-format off
31#include <sys/types.h>
32#include <sys/ptrace.h>
33#include <sys/sysctl.h>
34#include <sys/wait.h>
35// clang-format on
36
37using namespace lldb;
38using namespace lldb_private;
39using namespace lldb_private::process_openbsd;
40using namespace llvm;
41
42// Simple helper function to ensure flags are enabled on the given file
43// descriptor.
44static Status EnsureFDFlags(int fd, int flags) {
45 Status error;
46
47 int status = fcntl(fd, F_GETFL3);
48 if (status == -1) {
49 error.SetErrorToErrno();
50 return error;
51 }
52
53 if (fcntl(fd, F_SETFL4, status | flags) == -1) {
54 error.SetErrorToErrno();
55 return error;
56 }
57
58 return error;
59}
60
61// -----------------------------------------------------------------------------
62// Public Static Methods
63// -----------------------------------------------------------------------------
64
65llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
66NativeProcessOpenBSD::Factory::Launch(ProcessLaunchInfo &launch_info,
67 NativeDelegate &native_delegate,
68 MainLoop &mainloop) const {
69 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS(1u << 1)));
70
71 Status status;
72 ::pid_t pid = ProcessLauncherPosixFork()
73 .LaunchProcess(launch_info, status)
74 .GetProcessId();
75 LLDB_LOG(log, "pid = {0:x}", pid)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "pid = {0:x}", pid); } while (0)
;
76 if (status.Fail()) {
77 LLDB_LOG(log, "failed to launch process: {0}", status)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "failed to launch process: {0}", status); } while
(0)
;
78 return status.ToError();
79 }
80
81 // Wait for the child process to trap on its call to execve.
82 int wstatus;
83 ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
84 assert(wpid == pid)((void)0);
85 (void)wpid;
86 if (!WIFSTOPPED(wstatus)(((wstatus) & 0xff) == 0177)) {
87 LLDB_LOG(log, "Could not sync with inferior process: wstatus={1}",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "Could not sync with inferior process: wstatus={1}"
, WaitStatus::Decode(wstatus)); } while (0)
88 WaitStatus::Decode(wstatus))do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "Could not sync with inferior process: wstatus={1}"
, WaitStatus::Decode(wstatus)); } while (0)
;
89 return llvm::make_error<StringError>("Could not sync with inferior process",
90 llvm::inconvertibleErrorCode());
91 }
92 LLDB_LOG(log, "inferior started, now in stopped state")do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "inferior started, now in stopped state"); } while
(0)
;
93
94 ProcessInstanceInfo Info;
95 if (!Host::GetProcessInfo(pid, Info)) {
96 return llvm::make_error<StringError>("Cannot get process architecture",
97 llvm::inconvertibleErrorCode());
98 }
99
100 // Set the architecture to the exe architecture.
101 LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "pid = {0:x}, detected architecture {1}", pid, Info
.GetArchitecture().GetArchitectureName()); } while (0)
102 Info.GetArchitecture().GetArchitectureName())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "pid = {0:x}, detected architecture {1}", pid, Info
.GetArchitecture().GetArchitectureName()); } while (0)
;
103
104 std::unique_ptr<NativeProcessOpenBSD> process_up(new NativeProcessOpenBSD(
105 pid, launch_info.GetPTY().ReleasePrimaryFileDescriptor(), native_delegate,
106 Info.GetArchitecture(), mainloop));
107
108 status = process_up->ReinitializeThreads();
109 if (status.Fail())
110 return status.ToError();
111
112 for (const auto &thread : process_up->m_threads)
113 static_cast<NativeThreadOpenBSD &>(*thread).SetStoppedBySignal(SIGSTOP17);
114 process_up->SetState(StateType::eStateStopped, false);
115
116 return std::move(process_up);
117}
118
119llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
120NativeProcessOpenBSD::Factory::Attach(
121 lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
122 MainLoop &mainloop) const {
123
124 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS(1u << 1)));
125 LLDB_LOG(log, "pid = {0:x}", pid)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "pid = {0:x}", pid); } while (0)
;
126
127 // Retrieve the architecture for the running process.
128 ProcessInstanceInfo Info;
129 if (!Host::GetProcessInfo(pid, Info)) {
130 return llvm::make_error<StringError>("Cannot get process architecture",
131 llvm::inconvertibleErrorCode());
132 }
133
134 std::unique_ptr<NativeProcessOpenBSD> process_up(new NativeProcessOpenBSD(
135 pid, -1, native_delegate, Info.GetArchitecture(), mainloop));
136
137 Status status = process_up->Attach();
138 if (!status.Success())
139 return status.ToError();
140
141 return std::move(process_up);
142}
143
144NativeProcessOpenBSD::Extension
145NativeProcessOpenBSD::Factory::GetSupportedExtensions() const {
146 return Extension::multiprocess | Extension::fork | Extension::vfork |
147 Extension::pass_signals | Extension::auxv | Extension::libraries_svr4;
148}
149
150
151// -----------------------------------------------------------------------------
152// Public Instance Methods
153// -----------------------------------------------------------------------------
154
155NativeProcessOpenBSD::NativeProcessOpenBSD(::pid_t pid, int terminal_fd,
156 NativeDelegate &delegate,
157 const ArchSpec &arch,
158 MainLoop &mainloop)
159 : NativeProcessProtocol(pid, terminal_fd, delegate), m_arch(arch) {
160 if (m_terminal_fd != -1) {
161 Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK0x0004);
162 assert(status.Success())((void)0);
163 }
164
165 Status status;
166 m_sigchld_handle = mainloop.RegisterSignal(
167 SIGCHLD20, [this](MainLoopBase &) { SigchldHandler(); }, status);
168 assert(m_sigchld_handle && status.Success())((void)0);
169}
170
171// Handles all waitpid events from the inferior process.
172void NativeProcessOpenBSD::MonitorCallback(lldb::pid_t pid, int signal) {
173 switch (signal) {
174 case SIGTRAP5:
175 return MonitorSIGTRAP(pid);
176 default:
177 return MonitorSignal(pid, signal);
178 }
179}
180
181void NativeProcessOpenBSD::MonitorExited(lldb::pid_t pid, WaitStatus status) {
182 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS(1u << 1)));
183
184 LLDB_LOG(log, "got exit signal({0}) , pid = {1}", status, pid)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "got exit signal({0}) , pid = {1}", status, pid);
} while (0)
;
185
186 /* Stop Tracking All Threads attached to Process */
187 m_threads.clear();
188
189 SetExitStatus(status, true);
190
191 // Notify delegate that our process has exited.
192 SetState(StateType::eStateExited, true);
193}
194
195void NativeProcessOpenBSD::MonitorSIGTRAP(lldb::pid_t pid) {
196 for (const auto &thread : m_threads) {
197 static_cast<NativeThreadOpenBSD &>(*thread).SetStoppedByBreakpoint();
198 FixupBreakpointPCAsNeeded(static_cast<NativeThreadOpenBSD &>(*thread));
199 }
200 SetState(StateType::eStateStopped, true);
201}
202
203
204void NativeProcessOpenBSD::MonitorSignal(lldb::pid_t pid, int signal) {
205 for (const auto &thread : m_threads) {
206 static_cast<NativeThreadOpenBSD &>(*thread).SetStoppedBySignal(signal);
207 }
208 SetState(StateType::eStateStopped, true);
209}
210
211Status NativeProcessOpenBSD::PtraceWrapper(int req, lldb::pid_t pid, void *addr,
212 int data, int *result) {
213 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE(1u << 5)));
214 Status error;
215 int ret;
216
217 errno(*__errno()) = 0;
218 ret = ptrace(req, static_cast<::pid_t>(pid), (caddr_t)addr, data);
219
220 if (ret == -1)
221 error.SetErrorToErrno();
222
223 if (result)
224 *result = ret;
225
226 LLDB_LOG(log, "ptrace({0}, {1}, {2}, {3})={4:x}", req, pid, addr, data, ret)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "ptrace({0}, {1}, {2}, {3})={4:x}", req, pid, addr
, data, ret); } while (0)
;
227
228 if (error.Fail())
229 LLDB_LOG(log, "ptrace() failed: {0}", error)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "ptrace() failed: {0}", error); } while (0)
;
230
231 return error;
232}
233
234Status NativeProcessOpenBSD::Resume(const ResumeActionList &resume_actions) {
235 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS(1u << 1)));
236 LLDB_LOG(log, "pid {0}", GetID())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "pid {0}", GetID()); } while (0)
;
237
238 const auto &thread = m_threads[0];
239 const ResumeAction *const action =
240 resume_actions.GetActionForThread(thread->GetID(), true);
241
242 if (action == nullptr) {
243 LLDB_LOG(log, "no action specified for pid {0} tid {1}", GetID(),do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "no action specified for pid {0} tid {1}", GetID(
), thread->GetID()); } while (0)
244 thread->GetID())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "no action specified for pid {0} tid {1}", GetID(
), thread->GetID()); } while (0)
;
245 return Status();
246 }
247
248 Status error;
249 int signal = action->signal != LLDB_INVALID_SIGNAL_NUMBER0x7fffffff ? action->signal : 0;
250
251 switch (action->state) {
252 case eStateRunning: {
253 // Run the thread, possibly feeding it the signal.
254 error = NativeProcessOpenBSD::PtraceWrapper(PT_CONTINUE7, GetID(), (void *)1,
255 signal);
256 if (!error.Success())
257 return error;
258 for (const auto &thread : m_threads)
259 static_cast<NativeThreadOpenBSD &>(*thread).SetRunning();
260 SetState(eStateRunning, true);
261 break;
262 }
263 case eStateStepping:
264#ifdef PT_STEP(32 + 0)
265 // Run the thread, possibly feeding it the signal.
266 error = NativeProcessOpenBSD::PtraceWrapper(PT_STEP(32 + 0), GetID(), (void *)1,
267 signal);
268 if (!error.Success())
269 return error;
270 for (const auto &thread : m_threads)
271 static_cast<NativeThreadOpenBSD &>(*thread).SetStepping();
272 SetState(eStateStepping, true);
273 break;
274#else
275 return Status("NativeProcessOpenBSD stepping not supported on this platform");
276#endif
277
278 case eStateSuspended:
279 case eStateStopped:
280 llvm_unreachable("Unexpected state")__builtin_unreachable();
281
282 default:
283 return Status("NativeProcessOpenBSD::%s (): unexpected state %s specified "
284 "for pid %" PRIu64"llu" ", tid %" PRIu64"llu",
285 __FUNCTION__, StateAsCString(action->state), GetID(),
286 thread->GetID());
287 }
288
289 return Status();
290}
291
292Status NativeProcessOpenBSD::Halt() {
293 Status error;
294
295 if (kill(GetID(), SIGSTOP17) != 0)
296 error.SetErrorToErrno();
297
298 return error;
299}
300
301Status NativeProcessOpenBSD::Detach() {
302 Status error;
303
304 // Stop monitoring the inferior.
305 m_sigchld_handle.reset();
306
307 // Tell ptrace to detach from the process.
308 if (GetID() == LLDB_INVALID_PROCESS_ID0)
309 return error;
310
311 return PtraceWrapper(PT_DETACH10, GetID());
312}
313
314Status NativeProcessOpenBSD::Signal(int signo) {
315 Status error;
316
317 if (kill(GetID(), signo))
318 error.SetErrorToErrno();
319
320 return error;
321}
322
323Status NativeProcessOpenBSD::Kill() {
324 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS(1u << 1)));
325 LLDB_LOG(log, "pid {0}", GetID())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "pid {0}", GetID()); } while (0)
;
326
327 Status error;
328
329 switch (m_state) {
330 case StateType::eStateInvalid:
331 case StateType::eStateExited:
332 case StateType::eStateCrashed:
333 case StateType::eStateDetached:
334 case StateType::eStateUnloaded:
335 // Nothing to do - the process is already dead.
336 LLDB_LOG(log, "ignored for PID {0} due to current state: {1}", GetID(),do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "ignored for PID {0} due to current state: {1}", GetID
(), StateAsCString(m_state)); } while (0)
337 StateAsCString(m_state))do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "ignored for PID {0} due to current state: {1}", GetID
(), StateAsCString(m_state)); } while (0)
;
338 return error;
339
340 case StateType::eStateConnected:
341 case StateType::eStateAttaching:
342 case StateType::eStateLaunching:
343 case StateType::eStateStopped:
344 case StateType::eStateRunning:
345 case StateType::eStateStepping:
346 case StateType::eStateSuspended:
347 // We can try to kill a process in these states.
348 break;
349 }
350
351 if (kill(GetID(), SIGKILL9) != 0) {
352 error.SetErrorToErrno();
353 return error;
354 }
355
356 return error;
357}
358
359Status NativeProcessOpenBSD::GetMemoryRegionInfo(lldb::addr_t load_addr,
360 MemoryRegionInfo &range_info) {
361 return Status("Unimplemented");
362}
363
364Status NativeProcessOpenBSD::PopulateMemoryRegionCache() {
365 return Status("Unimplemented");
366}
367
368llvm::Expected<lldb::addr_t> NativeProcessOpenBSD::AllocateMemory(size_t size,
369 uint32_t permissions) {
370 return llvm::make_error<UnimplementedError>();
371}
372
373llvm::Error NativeProcessOpenBSD::DeallocateMemory(lldb::addr_t addr) {
374 return llvm::make_error<UnimplementedError>();
375}
376
377lldb::addr_t NativeProcessOpenBSD::GetSharedLibraryInfoAddress() {
378 // punt on this for now
379 return LLDB_INVALID_ADDRESS0xffffffffffffffffULL;
380}
381
382size_t NativeProcessOpenBSD::UpdateThreads() { return m_threads.size(); }
383
384Status NativeProcessOpenBSD::SetBreakpoint(lldb::addr_t addr, uint32_t size,
385 bool hardware) {
386 if (hardware)
387 return Status("NativeProcessOpenBSD does not support hardware breakpoints");
388 else
389 return SetSoftwareBreakpoint(addr, size);
390}
391
392Status NativeProcessOpenBSD::GetLoadedModuleFileSpec(const char *module_path,
393 FileSpec &file_spec) {
394 return Status("Unimplemented");
395}
396
397Status NativeProcessOpenBSD::GetFileLoadAddress(const llvm::StringRef &file_name,
398 lldb::addr_t &load_addr) {
399 load_addr = LLDB_INVALID_ADDRESS0xffffffffffffffffULL;
400 return Status();
401}
402
403void NativeProcessOpenBSD::SigchldHandler() {
404 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS(1u << 1)));
405 // Process all pending waitpid notifications.
406 int status;
407 ::pid_t wait_pid =
408 llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status, WNOHANG1);
409
410 if (wait_pid == 0)
411 return; // We are done.
412
413 if (wait_pid == -1) {
414 Status error(errno(*__errno()), eErrorTypePOSIX);
415 LLDB_LOG(log, "waitpid ({0}, &status, _) failed: {1}", GetID(), error)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "waitpid ({0}, &status, _) failed: {1}", GetID
(), error); } while (0)
;
416 }
417
418 WaitStatus wait_status = WaitStatus::Decode(status);
419 bool exited = wait_status.type == WaitStatus::Exit ||
420 (wait_status.type == WaitStatus::Signal &&
421 wait_pid == static_cast<::pid_t>(GetID()));
422
423 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "waitpid ({0}, &status, _) => pid = {1}, status = {2}, exited = {3}"
, GetID(), wait_pid, status, exited); } while (0)
424 "waitpid ({0}, &status, _) => pid = {1}, status = {2}, exited = {3}",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "waitpid ({0}, &status, _) => pid = {1}, status = {2}, exited = {3}"
, GetID(), wait_pid, status, exited); } while (0)
425 GetID(), wait_pid, status, exited)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "waitpid ({0}, &status, _) => pid = {1}, status = {2}, exited = {3}"
, GetID(), wait_pid, status, exited); } while (0)
;
426
427 if (exited)
428 MonitorExited(wait_pid, wait_status);
429 else {
430 assert(wait_status.type == WaitStatus::Stop)((void)0);
431 MonitorCallback(wait_pid, wait_status.status);
432 }
433}
434
435bool NativeProcessOpenBSD::HasThreadNoLock(lldb::tid_t thread_id) {
436 for (const auto &thread : m_threads) {
437 assert(thread && "thread list should not contain NULL threads")((void)0);
438 if (thread->GetID() == thread_id) {
439 // We have this thread.
440 return true;
441 }
442 }
443
444 // We don't have this thread.
445 return false;
446}
447
448NativeThreadOpenBSD &NativeProcessOpenBSD::AddThread(lldb::tid_t thread_id) {
449
450 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD(1u << 2)));
451 LLDB_LOG(log, "pid {0} adding thread with tid {1}", GetID(), thread_id)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "pid {0} adding thread with tid {1}", GetID(), thread_id
); } while (0)
;
452
453 assert(!HasThreadNoLock(thread_id) &&((void)0)
454 "attempted to add a thread by id that already exists")((void)0);
455
456 // If this is the first thread, save it as the current thread
457 if (m_threads.empty())
458 SetCurrentThreadID(thread_id);
459
460 m_threads.push_back(std::make_unique<NativeThreadOpenBSD>(*this, thread_id));
461 return static_cast<NativeThreadOpenBSD &>(*m_threads.back());
462}
463
464Status NativeProcessOpenBSD::Attach() {
465 // Attach to the requested process.
466 // An attach will cause the thread to stop with a SIGSTOP.
467 Status status = PtraceWrapper(PT_ATTACH9, m_pid);
468 if (status.Fail())
469 return status;
470
471 int wstatus;
472 // At this point we should have a thread stopped if waitpid succeeds.
473 if ((wstatus = waitpid(m_pid, NULL__null, 0)) < 0)
Although the value stored to 'wstatus' is used in the enclosing expression, the value is never actually read from 'wstatus'
474 return Status(errno(*__errno()), eErrorTypePOSIX);
475
476 /* Initialize threads */
477 status = ReinitializeThreads();
478 if (status.Fail())
479 return status;
480
481 for (const auto &thread : m_threads)
482 static_cast<NativeThreadOpenBSD &>(*thread).SetStoppedBySignal(SIGSTOP17);
483
484 // Let our process instance know the thread has stopped.
485 SetState(StateType::eStateStopped);
486 return Status();
487}
488
489Status NativeProcessOpenBSD::ReadMemory(lldb::addr_t addr, void *buf,
490 size_t size, size_t &bytes_read) {
491 unsigned char *dst = static_cast<unsigned char *>(buf);
492 struct ptrace_io_desc io;
493
494 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY(1u << 4)));
495 LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "addr = {0}, buf = {1}, size = {2}", addr, buf, size
); } while (0)
;
496
497 bytes_read = 0;
498 io.piod_op = PIOD_READ_D1;
499 io.piod_len = size;
500
501 do {
502 io.piod_offs = (void *)(addr + bytes_read);
503 io.piod_addr = dst + bytes_read;
504
505 Status error = NativeProcessOpenBSD::PtraceWrapper(PT_IO11, GetID(), &io);
506 if (error.Fail())
507 return error;
508
509 bytes_read = io.piod_len;
510 io.piod_len = size - bytes_read;
511 } while (bytes_read < size);
512
513 return Status();
514}
515
516Status NativeProcessOpenBSD::WriteMemory(lldb::addr_t addr, const void *buf,
517 size_t size, size_t &bytes_written) {
518 const unsigned char *src = static_cast<const unsigned char *>(buf);
519 Status error;
520 struct ptrace_io_desc io;
521
522 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY(1u << 4)));
523 LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp"
, __func__, "addr = {0}, buf = {1}, size = {2}", addr, buf, size
); } while (0)
;
524
525 bytes_written = 0;
526 io.piod_op = PIOD_WRITE_D2;
527 io.piod_len = size;
528
529 do {
530 io.piod_addr = const_cast<void *>(static_cast<const void *>(src + bytes_written));
531 io.piod_offs = (void *)(addr + bytes_written);
532
533 Status error = NativeProcessOpenBSD::PtraceWrapper(PT_IO11, GetID(), &io);
534 if (error.Fail())
535 return error;
536
537 bytes_written = io.piod_len;
538 io.piod_len = size - bytes_written;
539 } while (bytes_written < size);
540
541 return error;
542}
543
544llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
545NativeProcessOpenBSD::GetAuxvData() const {
546 size_t auxv_size = 100 * sizeof(AuxInfoAux64Info);
547
548 ErrorOr<std::unique_ptr<WritableMemoryBuffer>> buf =
549 llvm::WritableMemoryBuffer::getNewMemBuffer(auxv_size);
550
551 struct ptrace_io_desc io;
552 io.piod_op = PIOD_READ_AUXV5;
553 io.piod_offs = 0;
554 io.piod_addr = static_cast<void *>(buf.get()->getBufferStart());
555 io.piod_len = auxv_size;
556
557 Status error = NativeProcessOpenBSD::PtraceWrapper(PT_IO11, GetID(), &io);
558
559 if (error.Fail())
560 return std::error_code(error.GetError(), std::generic_category());
561
562 if (io.piod_len < 1)
563 return std::error_code(ECANCELED88, std::generic_category());
564
565 return std::move(buf);
566}
567
568Status NativeProcessOpenBSD::ReinitializeThreads() {
569 // Clear old threads
570 m_threads.clear();
571
572 // Initialize new thread
573 struct ptrace_thread_state info = {};
574 Status error = PtraceWrapper(PT_GET_THREAD_FIRST15, GetID(), &info, sizeof(info));
575 if (error.Fail()) {
576 return error;
577 }
578 // Reinitialize from scratch threads and register them in process
579 while (info.pts_tid > 0) {
580 AddThread(info.pts_tid);
581 error = PtraceWrapper(PT_GET_THREAD_NEXT16, GetID(), &info, sizeof(info));
582 if (error.Fail() && errno(*__errno()) != 0) {
583 return error;
584 }
585 }
586
587 return error;
588}