LLDB  mainline
ProcessDebugger.cpp
Go to the documentation of this file.
1 //===-- ProcessDebugger.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 "ProcessDebugger.h"
10 
11 // Windows includes
13 #include <psapi.h>
14 
15 #include "lldb/Host/FileSystem.h"
17 #include "lldb/Host/HostProcess.h"
18 #include "lldb/Host/HostThread.h"
21 #include "lldb/Target/Process.h"
22 #include "llvm/Support/ConvertUTF.h"
23 #include "llvm/Support/Error.h"
24 
25 #include "DebuggerThread.h"
26 #include "ExceptionRecord.h"
27 #include "ProcessWindowsLog.h"
28 
29 using namespace lldb;
30 using namespace lldb_private;
31 
32 static DWORD ConvertLldbToWinApiProtect(uint32_t protect) {
33  // We also can process a read / write permissions here, but if the debugger
34  // will make later a write into the allocated memory, it will fail. To get
35  // around it is possible inside DoWriteMemory to remember memory permissions,
36  // allow write, write and restore permissions, but for now we process only
37  // the executable permission.
38  //
39  // TODO: Process permissions other than executable
40  if (protect & ePermissionsExecutable)
41  return PAGE_EXECUTE_READWRITE;
42 
43  return PAGE_READWRITE;
44 }
45 
46 // The Windows page protection bits are NOT independent masks that can be
47 // bitwise-ORed together. For example, PAGE_EXECUTE_READ is not (PAGE_EXECUTE
48 // | PAGE_READ). To test for an access type, it's necessary to test for any of
49 // the bits that provide that access type.
50 static bool IsPageReadable(uint32_t protect) {
51  return (protect & PAGE_NOACCESS) == 0;
52 }
53 
54 static bool IsPageWritable(uint32_t protect) {
55  return (protect & (PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY |
56  PAGE_READWRITE | PAGE_WRITECOPY)) != 0;
57 }
58 
59 static bool IsPageExecutable(uint32_t protect) {
60  return (protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE |
61  PAGE_EXECUTE_WRITECOPY)) != 0;
62 }
63 
64 namespace lldb_private {
65 
66 ProcessDebugger::~ProcessDebugger() {}
67 
68 lldb::pid_t ProcessDebugger::GetDebuggedProcessId() const {
69  if (m_session_data)
70  return m_session_data->m_debugger->GetProcess().GetProcessId();
72 }
73 
74 Status ProcessDebugger::DetachProcess() {
75  Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
76  DebuggerThreadSP debugger_thread;
77  {
78  // Acquire the lock only long enough to get the DebuggerThread.
79  // StopDebugging() will trigger a call back into ProcessDebugger which will
80  // also acquire the lock. Thus we have to release the lock before calling
81  // StopDebugging().
82  llvm::sys::ScopedLock lock(m_mutex);
83 
84  if (!m_session_data) {
85  LLDB_LOG(log, "there is no active session.");
86  return Status();
87  }
88 
89  debugger_thread = m_session_data->m_debugger;
90  }
91 
92  Status error;
93 
94  LLDB_LOG(log, "detaching from process {0}.",
95  debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle());
96  error = debugger_thread->StopDebugging(false);
97 
98  // By the time StopDebugging returns, there is no more debugger thread, so
99  // we can be assured that no other thread will race for the session data.
100  m_session_data.reset();
101 
102  return error;
103 }
104 
105 Status ProcessDebugger::LaunchProcess(ProcessLaunchInfo &launch_info,
106  DebugDelegateSP delegate) {
107  // Even though m_session_data is accessed here, it is before a debugger
108  // thread has been kicked off. So there's no race conditions, and it
109  // shouldn't be necessary to acquire the mutex.
110 
111  Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
112  Status result;
113 
114  FileSpec working_dir = launch_info.GetWorkingDirectory();
115  namespace fs = llvm::sys::fs;
116  if (working_dir) {
117  FileSystem::Instance().Resolve(working_dir);
118  if (!FileSystem::Instance().IsDirectory(working_dir)) {
119  result.SetErrorStringWithFormat("No such file or directory: %s",
120  working_dir.GetCString());
121  return result;
122  }
123  }
124 
125  if (!launch_info.GetFlags().Test(eLaunchFlagDebug)) {
126  StreamString stream;
127  stream.Printf("ProcessDebugger unable to launch '%s'. ProcessDebugger can "
128  "only be used for debug launches.",
129  launch_info.GetExecutableFile().GetPath().c_str());
130  std::string message = stream.GetString().str();
131  result.SetErrorString(message.c_str());
132 
133  LLDB_LOG(log, "error: {0}", message);
134  return result;
135  }
136 
137  bool stop_at_entry = launch_info.GetFlags().Test(eLaunchFlagStopAtEntry);
138  m_session_data.reset(new ProcessWindowsData(stop_at_entry));
139  m_session_data->m_debugger.reset(new DebuggerThread(delegate));
140  DebuggerThreadSP debugger = m_session_data->m_debugger;
141 
142  // Kick off the DebugLaunch asynchronously and wait for it to complete.
143  result = debugger->DebugLaunch(launch_info);
144  if (result.Fail()) {
145  LLDB_LOG(log, "failed launching '{0}'. {1}",
146  launch_info.GetExecutableFile().GetPath(), result);
147  return result;
148  }
149 
150  HostProcess process;
151  Status error = WaitForDebuggerConnection(debugger, process);
152  if (error.Fail()) {
153  LLDB_LOG(log, "failed launching '{0}'. {1}",
154  launch_info.GetExecutableFile().GetPath(), error);
155  return error;
156  }
157 
158  LLDB_LOG(log, "successfully launched '{0}'",
159  launch_info.GetExecutableFile().GetPath());
160 
161  // We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the
162  // private state should already be set to eStateStopped as a result of
163  // hitting the initial breakpoint. If it was not set, the breakpoint should
164  // have already been resumed from and the private state should already be
165  // eStateRunning.
166  launch_info.SetProcessID(process.GetProcessId());
167 
168  return result;
169 }
170 
171 Status ProcessDebugger::AttachProcess(lldb::pid_t pid,
172  const ProcessAttachInfo &attach_info,
173  DebugDelegateSP delegate) {
174  Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
175  m_session_data.reset(
176  new ProcessWindowsData(!attach_info.GetContinueOnceAttached()));
177  DebuggerThreadSP debugger(new DebuggerThread(delegate));
178 
179  m_session_data->m_debugger = debugger;
180 
181  DWORD process_id = static_cast<DWORD>(pid);
182  Status error = debugger->DebugAttach(process_id, attach_info);
183  if (error.Fail()) {
184  LLDB_LOG(
185  log,
186  "encountered an error occurred initiating the asynchronous attach. {0}",
187  error);
188  return error;
189  }
190 
191  HostProcess process;
192  error = WaitForDebuggerConnection(debugger, process);
193  if (error.Fail()) {
194  LLDB_LOG(log,
195  "encountered an error waiting for the debugger to connect. {0}",
196  error);
197  return error;
198  }
199 
200  LLDB_LOG(log, "successfully attached to process with pid={0}", process_id);
201 
202  // We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the
203  // private state should already be set to eStateStopped as a result of
204  // hitting the initial breakpoint. If it was not set, the breakpoint should
205  // have already been resumed from and the private state should already be
206  // eStateRunning.
207 
208  return error;
209 }
210 
211 Status ProcessDebugger::DestroyProcess(const lldb::StateType state) {
212  Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
213  DebuggerThreadSP debugger_thread;
214  {
215  // Acquire this lock inside an inner scope, only long enough to get the
216  // DebuggerThread. StopDebugging() will trigger a call back into
217  // ProcessDebugger which will acquire the lock again, so we need to not
218  // deadlock.
219  llvm::sys::ScopedLock lock(m_mutex);
220 
221  if (!m_session_data) {
222  LLDB_LOG(log, "warning: state = {0}, but there is no active session.",
223  state);
224  return Status();
225  }
226 
227  debugger_thread = m_session_data->m_debugger;
228  }
229 
230  Status error;
231  if (state != eStateExited && state != eStateDetached) {
232  LLDB_LOG(
233  log, "Shutting down process {0}.",
234  debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle());
235  error = debugger_thread->StopDebugging(true);
236 
237  // By the time StopDebugging returns, there is no more debugger thread, so
238  // we can be assured that no other thread will race for the session data.
239  m_session_data.reset();
240  } else {
241  error.SetErrorStringWithFormat("cannot destroy process %" PRIx64
242  " while state = %d",
243  GetDebuggedProcessId(), state);
244  LLDB_LOG(log, "error: {0}", error);
245  }
246  return error;
247 }
248 
249 Status ProcessDebugger::HaltProcess(bool &caused_stop) {
250  Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
251  Status error;
252  llvm::sys::ScopedLock lock(m_mutex);
253  caused_stop = ::DebugBreakProcess(m_session_data->m_debugger->GetProcess()
254  .GetNativeProcess()
255  .GetSystemHandle());
256  if (!caused_stop) {
257  error.SetError(::GetLastError(), eErrorTypeWin32);
258  LLDB_LOG(log, "DebugBreakProcess failed with error {0}", error);
259  }
260 
261  return error;
262 }
263 
264 Status ProcessDebugger::ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
265  size_t &bytes_read) {
266  Status error;
267  bytes_read = 0;
268  Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
269  llvm::sys::ScopedLock lock(m_mutex);
270 
271  if (!m_session_data) {
272  error.SetErrorString(
273  "cannot read, there is no active debugger connection.");
274  LLDB_LOG(log, "error: {0}", error);
275  return error;
276  }
277 
278  LLDB_LOG(log, "attempting to read {0} bytes from address {1:x}", size,
279  vm_addr);
280 
281  HostProcess process = m_session_data->m_debugger->GetProcess();
282  void *addr = reinterpret_cast<void *>(vm_addr);
283  SIZE_T num_of_bytes_read = 0;
284  if (!::ReadProcessMemory(process.GetNativeProcess().GetSystemHandle(), addr,
285  buf, size, &num_of_bytes_read)) {
286  // Reading from the process can fail for a number of reasons - set the
287  // error code and make sure that the number of bytes read is set back to 0
288  // because in some scenarios the value of bytes_read returned from the API
289  // is garbage.
290  error.SetError(GetLastError(), eErrorTypeWin32);
291  LLDB_LOG(log, "reading failed with error: {0}", error);
292  } else {
293  bytes_read = num_of_bytes_read;
294  }
295  return error;
296 }
297 
298 Status ProcessDebugger::WriteMemory(lldb::addr_t vm_addr, const void *buf,
299  size_t size, size_t &bytes_written) {
300  Status error;
301  bytes_written = 0;
302  Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
303  llvm::sys::ScopedLock lock(m_mutex);
304  LLDB_LOG(log, "attempting to write {0} bytes into address {1:x}", size,
305  vm_addr);
306 
307  if (!m_session_data) {
308  error.SetErrorString(
309  "cannot write, there is no active debugger connection.");
310  LLDB_LOG(log, "error: {0}", error);
311  return error;
312  }
313 
314  HostProcess process = m_session_data->m_debugger->GetProcess();
315  void *addr = reinterpret_cast<void *>(vm_addr);
316  SIZE_T num_of_bytes_written = 0;
317  lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
318  if (::WriteProcessMemory(handle, addr, buf, size, &num_of_bytes_written)) {
319  FlushInstructionCache(handle, addr, num_of_bytes_written);
320  bytes_written = num_of_bytes_written;
321  } else {
322  error.SetError(GetLastError(), eErrorTypeWin32);
323  LLDB_LOG(log, "writing failed with error: {0}", error);
324  }
325  return error;
326 }
327 
328 Status ProcessDebugger::AllocateMemory(size_t size, uint32_t permissions,
329  lldb::addr_t &addr) {
330  Status error;
331  addr = LLDB_INVALID_ADDRESS;
332  Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
333  llvm::sys::ScopedLock lock(m_mutex);
334  LLDB_LOG(log, "attempting to allocate {0} bytes with permissions {1}", size,
335  permissions);
336 
337  if (!m_session_data) {
338  error.SetErrorString(
339  "cannot allocate, there is no active debugger connection");
340  LLDB_LOG(log, "error: {0}", error);
341  return error;
342  }
343 
344  HostProcess process = m_session_data->m_debugger->GetProcess();
345  lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
346  auto protect = ConvertLldbToWinApiProtect(permissions);
347  auto result = ::VirtualAllocEx(handle, nullptr, size, MEM_COMMIT, protect);
348  if (!result) {
349  error.SetError(GetLastError(), eErrorTypeWin32);
350  LLDB_LOG(log, "allocating failed with error: {0}", error);
351  } else {
352  addr = reinterpret_cast<addr_t>(result);
353  }
354  return error;
355 }
356 
357 Status ProcessDebugger::DeallocateMemory(lldb::addr_t vm_addr) {
358  Status result;
359 
360  Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
361  llvm::sys::ScopedLock lock(m_mutex);
362  LLDB_LOG(log, "attempting to deallocate bytes at address {0}", vm_addr);
363 
364  if (!m_session_data) {
365  result.SetErrorString(
366  "cannot deallocate, there is no active debugger connection");
367  LLDB_LOG(log, "error: {0}", result);
368  return result;
369  }
370 
371  HostProcess process = m_session_data->m_debugger->GetProcess();
372  lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
373  if (!::VirtualFreeEx(handle, reinterpret_cast<LPVOID>(vm_addr), 0,
374  MEM_RELEASE)) {
375  result.SetError(GetLastError(), eErrorTypeWin32);
376  LLDB_LOG(log, "deallocating failed with error: {0}", result);
377  }
378 
379  return result;
380 }
381 
383  MemoryRegionInfo &info) {
384  Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
385  Status error;
386  llvm::sys::ScopedLock lock(m_mutex);
387  info.Clear();
388 
389  if (!m_session_data) {
390  error.SetErrorString(
391  "GetMemoryRegionInfo called with no debugging session.");
392  LLDB_LOG(log, "error: {0}", error);
393  return error;
394  }
395  HostProcess process = m_session_data->m_debugger->GetProcess();
396  lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
397  if (handle == nullptr || handle == LLDB_INVALID_PROCESS) {
398  error.SetErrorString(
399  "GetMemoryRegionInfo called with an invalid target process.");
400  LLDB_LOG(log, "error: {0}", error);
401  return error;
402  }
403 
404  LLDB_LOG(log, "getting info for address {0:x}", vm_addr);
405 
406  void *addr = reinterpret_cast<void *>(vm_addr);
407  MEMORY_BASIC_INFORMATION mem_info = {};
408  SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info, sizeof(mem_info));
409  if (result == 0) {
410  if (::GetLastError() == ERROR_INVALID_PARAMETER) {
411  // ERROR_INVALID_PARAMETER is returned if VirtualQueryEx is called with
412  // an address past the highest accessible address. We should return a
413  // range from the vm_addr to LLDB_INVALID_ADDRESS
414  info.GetRange().SetRangeBase(vm_addr);
416  info.SetReadable(MemoryRegionInfo::eNo);
417  info.SetExecutable(MemoryRegionInfo::eNo);
418  info.SetWritable(MemoryRegionInfo::eNo);
419  info.SetMapped(MemoryRegionInfo::eNo);
420  return error;
421  } else {
422  error.SetError(::GetLastError(), eErrorTypeWin32);
423  LLDB_LOG(log,
424  "VirtualQueryEx returned error {0} while getting memory "
425  "region info for address {1:x}",
426  error, vm_addr);
427  return error;
428  }
429  }
430 
431  // Protect bits are only valid for MEM_COMMIT regions.
432  if (mem_info.State == MEM_COMMIT) {
433  const bool readable = IsPageReadable(mem_info.Protect);
434  const bool executable = IsPageExecutable(mem_info.Protect);
435  const bool writable = IsPageWritable(mem_info.Protect);
436  info.SetReadable(readable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
437  info.SetExecutable(executable ? MemoryRegionInfo::eYes
438  : MemoryRegionInfo::eNo);
439  info.SetWritable(writable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
440  } else {
441  info.SetReadable(MemoryRegionInfo::eNo);
442  info.SetExecutable(MemoryRegionInfo::eNo);
443  info.SetWritable(MemoryRegionInfo::eNo);
444  }
445 
446  // AllocationBase is defined for MEM_COMMIT and MEM_RESERVE but not MEM_FREE.
447  if (mem_info.State != MEM_FREE) {
448  info.GetRange().SetRangeBase(
449  reinterpret_cast<addr_t>(mem_info.AllocationBase));
450  info.GetRange().SetRangeEnd(reinterpret_cast<addr_t>(mem_info.BaseAddress) +
451  mem_info.RegionSize);
452  info.SetMapped(MemoryRegionInfo::eYes);
453  } else {
454  // In the unmapped case we need to return the distance to the next block of
455  // memory. VirtualQueryEx nearly does that except that it gives the
456  // distance from the start of the page containing vm_addr.
457  SYSTEM_INFO data;
458  ::GetSystemInfo(&data);
459  DWORD page_offset = vm_addr % data.dwPageSize;
460  info.GetRange().SetRangeBase(vm_addr);
461  info.GetRange().SetByteSize(mem_info.RegionSize - page_offset);
462  info.SetMapped(MemoryRegionInfo::eNo);
463  }
464 
465  error.SetError(::GetLastError(), eErrorTypeWin32);
466  LLDB_LOGV(log,
467  "Memory region info for address {0}: readable={1}, "
468  "executable={2}, writable={3}",
469  vm_addr, info.GetReadable(), info.GetExecutable(),
470  info.GetWritable());
471  return error;
472 }
473 
474 void ProcessDebugger::OnExitProcess(uint32_t exit_code) {
475  // If the process exits before any initial stop then notify the debugger
476  // of the error otherwise WaitForDebuggerConnection() will be blocked.
477  // An example of this issue is when a process fails to load a dependent DLL.
478  if (m_session_data && !m_session_data->m_initial_stop_received) {
479  Status error(exit_code, eErrorTypeWin32);
480  OnDebuggerError(error, 0);
481  }
482 }
483 
484 void ProcessDebugger::OnDebuggerConnected(lldb::addr_t image_base) {}
485 
487 ProcessDebugger::OnDebugException(bool first_chance,
488  const ExceptionRecord &record) {
489  Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EXCEPTION);
490  llvm::sys::ScopedLock lock(m_mutex);
491  // FIXME: Without this check, occasionally when running the test suite
492  // there is an issue where m_session_data can be null. It's not clear how
493  // this could happen but it only surfaces while running the test suite. In
494  // order to properly diagnose this, we probably need to first figure allow the
495  // test suite to print out full lldb logs, and then add logging to the process
496  // plugin.
497  if (!m_session_data) {
498  LLDB_LOG(log,
499  "Debugger thread reported exception {0:x} at address {1:x}, but "
500  "there is no session.",
501  record.GetExceptionCode(), record.GetExceptionAddress());
503  }
504 
506  if ((record.GetExceptionCode() == EXCEPTION_BREAKPOINT ||
507  record.GetExceptionCode() ==
508  0x4000001FL /*WOW64 STATUS_WX86_BREAKPOINT*/) &&
509  !m_session_data->m_initial_stop_received) {
510  // Handle breakpoints at the first chance.
512  LLDB_LOG(
513  log,
514  "Hit loader breakpoint at address {0:x}, setting initial stop event.",
515  record.GetExceptionAddress());
516  m_session_data->m_initial_stop_received = true;
517  ::SetEvent(m_session_data->m_initial_stop_event);
518  }
519  return result;
520 }
521 
522 void ProcessDebugger::OnCreateThread(const HostThread &thread) {
523  // Do nothing by default
524 }
525 
526 void ProcessDebugger::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) {
527  // Do nothing by default
528 }
529 
530 void ProcessDebugger::OnLoadDll(const ModuleSpec &module_spec,
531  lldb::addr_t module_addr) {
532  // Do nothing by default
533 }
534 
535 void ProcessDebugger::OnUnloadDll(lldb::addr_t module_addr) {
536  // Do nothing by default
537 }
538 
539 void ProcessDebugger::OnDebugString(const std::string &string) {}
540 
541 void ProcessDebugger::OnDebuggerError(const Status &error, uint32_t type) {
542  llvm::sys::ScopedLock lock(m_mutex);
543  Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
544 
545  if (m_session_data->m_initial_stop_received) {
546  // This happened while debugging. Do we shutdown the debugging session,
547  // try to continue, or do something else?
548  LLDB_LOG(log,
549  "Error {0} occurred during debugging. Unexpected behavior "
550  "may result. {1}",
551  error.GetError(), error);
552  } else {
553  // If we haven't actually launched the process yet, this was an error
554  // launching the process. Set the internal error and signal the initial
555  // stop event so that the DoLaunch method wakes up and returns a failure.
556  m_session_data->m_launch_error = error;
557  ::SetEvent(m_session_data->m_initial_stop_event);
558  LLDB_LOG(log,
559  "Error {0} occurred launching the process before the initial "
560  "stop. {1}",
561  error.GetError(), error);
562  return;
563  }
564 }
565 
566 Status ProcessDebugger::WaitForDebuggerConnection(DebuggerThreadSP debugger,
567  HostProcess &process) {
568  Status result;
569  Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS |
571  LLDB_LOG(log, "Waiting for loader breakpoint.");
572 
573  // Block this function until we receive the initial stop from the process.
574  if (::WaitForSingleObject(m_session_data->m_initial_stop_event, INFINITE) ==
575  WAIT_OBJECT_0) {
576  LLDB_LOG(log, "hit loader breakpoint, returning.");
577 
578  process = debugger->GetProcess();
579  return m_session_data->m_launch_error;
580  } else
581  return Status(::GetLastError(), eErrorTypeWin32);
582 }
583 
584 } // namespace lldb_private
static bool IsPageReadable(uint32_t protect)
A class that represents a running process on the host machine.
void SetExecutable(OptionalBool val)
lldb::addr_t GetExceptionAddress() const
#define LLDB_INVALID_PROCESS_ID
Definition: lldb-defines.h:92
uint64_t process_t
Definition: lldb-types.h:57
static bool IsPageExecutable(uint32_t protect)
OptionalBool GetReadable() const
static DWORD ConvertLldbToWinApiProtect(uint32_t protect)
void SetProcessID(lldb::pid_t pid)
Definition: ProcessInfo.h:70
A file utility class.
Definition: FileSpec.h:56
bool GetContinueOnceAttached() const
Definition: Process.h:139
#define WINDOWS_LOG_EXCEPTION
void SetMapped(OptionalBool val)
void SetRangeEnd(BaseType end)
Definition: RangeMap.h:64
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition: Log.h:242
#define LLDB_INVALID_PROCESS
Definition: lldb-types.h:78
std::shared_ptr< DebuggerThread > DebuggerThreadSP
Definition: ForwardDecl.h:36
Standard Win32 error codes.
#define WINDOWS_LOG_MEMORY
Process has exited and can&#39;t be examined.
static MemoryRegionInfo GetMemoryRegionInfo(const MemoryRegionInfos &regions, lldb::addr_t load_addr)
OptionalBool GetWritable() const
std::shared_ptr< IDebugDelegate > DebugDelegateSP
Definition: ForwardDecl.h:33
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
bool Test(ValueType bit) const
Test a single flag bit.
Definition: Flags.h:96
static llvm::raw_ostream & error(Stream &strm)
Process has been detached and can&#39;t be examined.
StateType
Process and Thread States.
uint64_t tid_t
Definition: lldb-types.h:86
llvm::StringRef GetString() const
ExceptionResult
Definition: ForwardDecl.h:16
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
Definition: Status.cpp:242
FileSpec & GetExecutableFile()
Definition: ProcessInfo.h:43
#define WINDOWS_LOG_PROCESS
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
static bool IsPageWritable(uint32_t protect)
const char * GetCString(bool denormalize=true) const
Definition: FileSpec.cpp:364
void SetByteSize(SizeType s)
Definition: RangeMap.h:73
uint64_t addr_t
Definition: lldb-types.h:83
void SetReadable(OptionalBool val)
bool Fail() const
Test for error condition.
Definition: Status.cpp:182
const FileSpec & GetWorkingDirectory() const
int void SetError(ValueType err, lldb::ErrorType type)
Set accessor with an error value and type.
Definition: Status.cpp:217
Definition: SBAddress.h:15
uint64_t pid_t
Definition: lldb-types.h:85
void SetRangeBase(BaseType b)
Definition: RangeMap.h:48
void SetWritable(OptionalBool val)
#define WINDOWS_LOG_BREAKPOINTS
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:256
ValueType GetError() const
Access the error value.
Definition: Status.cpp:175
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:348
lldb::pid_t GetProcessId() const
Definition: HostProcess.cpp:29
#define LLDB_LOGV(log,...)
Definition: Log.h:256
HostNativeProcessBase & GetNativeProcess()
Definition: HostProcess.cpp:41
An error handling class.
Definition: Status.h:44
OptionalBool GetExecutable() const