LLDB mainline
ScriptedProcess.cpp
Go to the documentation of this file.
1//===-- ScriptedProcess.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 "ScriptedProcess.h"
10
11#include "lldb/Core/Debugger.h"
12#include "lldb/Core/Module.h"
14
22#include "lldb/Target/Queue.h"
26#include "lldb/Utility/State.h"
27
28#include <mutex>
29
31
32using namespace lldb;
33using namespace lldb_private;
34
36 return "Scripted Process plug-in.";
37}
38
40 ScriptLanguage::eScriptLanguagePython,
41};
42
44 llvm::ArrayRef<lldb::ScriptLanguage> supported_languages =
45 llvm::ArrayRef(g_supported_script_languages);
46
47 return llvm::is_contained(supported_languages, language);
48}
49
50lldb::ProcessSP ScriptedProcess::CreateInstance(lldb::TargetSP target_sp,
51 lldb::ListenerSP listener_sp,
52 const FileSpec *file,
53 bool can_connect) {
54 if (!target_sp ||
55 !IsScriptLanguageSupported(target_sp->GetDebugger().GetScriptLanguage()))
56 return nullptr;
57
58 ScriptedMetadata scripted_metadata(target_sp->GetProcessLaunchInfo());
59
61 auto process_sp = std::shared_ptr<ScriptedProcess>(
62 new ScriptedProcess(target_sp, listener_sp, scripted_metadata, error));
63
64 if (error.Fail() || !process_sp || !process_sp->m_interface_up) {
65 LLDB_LOGF(GetLog(LLDBLog::Process), "%s", error.AsCString());
66 return nullptr;
67 }
68
69 return process_sp;
70}
71
72bool ScriptedProcess::CanDebug(lldb::TargetSP target_sp,
73 bool plugin_specified_by_name) {
74 return true;
75}
76
77ScriptedProcess::ScriptedProcess(lldb::TargetSP target_sp,
78 lldb::ListenerSP listener_sp,
79 const ScriptedMetadata &scripted_metadata,
81 : Process(target_sp, listener_sp), m_scripted_metadata(scripted_metadata) {
82
83 if (!target_sp) {
84 error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s",
85 __FUNCTION__, "Invalid target");
86 return;
87 }
88
89 ScriptInterpreter *interpreter =
90 target_sp->GetDebugger().GetScriptInterpreter();
91
92 if (!interpreter) {
93 error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s",
94 __FUNCTION__,
95 "Debugger has no Script Interpreter");
96 return;
97 }
98
99 // Create process instance interface
101 if (!m_interface_up) {
102 error.SetErrorStringWithFormat(
103 "ScriptedProcess::%s () - ERROR: %s", __FUNCTION__,
104 "Script interpreter couldn't create Scripted Process Interface");
105 return;
106 }
107
108 ExecutionContext exe_ctx(target_sp, /*get_process=*/false);
109
110 // Create process script object
114
115 if (!object_sp || !object_sp->IsValid()) {
116 error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s",
117 __FUNCTION__,
118 "Failed to create valid script object");
119 return;
120 }
121}
122
124 Clear();
125 // We need to call finalize on the process before destroying ourselves to
126 // make sure all of the broadcaster cleanup goes as planned. If we destruct
127 // this class, then Process::~Process() might have problems trying to fully
128 // destroy the broadcaster.
129 Finalize();
130}
131
133 static llvm::once_flag g_once_flag;
134
135 llvm::call_once(g_once_flag, []() {
138 });
139}
140
143}
144
147
148 return DoLaunch(nullptr, launch_info);
149}
150
152 ProcessLaunchInfo &launch_info) {
153 /* FIXME: This doesn't reflect how lldb actually launches a process.
154 In reality, it attaches to debugserver, then resume the process. */
157
158 if (error.Fail())
159 return error;
160
161 // TODO: Fetch next state from stopped event queue then send stop event
162 // const StateType state = SetThreadStopInfo(response);
163 // if (state != eStateInvalid) {
164 // SetPrivateState(state);
165
167
168 return {};
169}
170
174}
175
178 // FIXME: Fetch data from thread.
179 const StateType thread_resume_state = eStateRunning;
180 LLDB_LOGF(log, "ScriptedProcess::%s thread_resume_state = %s", __FUNCTION__,
181 StateAsCString(thread_resume_state));
182
183 bool resume = (thread_resume_state == eStateRunning);
184 assert(thread_resume_state == eStateRunning && "invalid thread resume state");
185
187 if (resume) {
188 LLDB_LOGF(log, "ScriptedProcess::%s sending resume", __FUNCTION__);
189
193 }
194
195 return error;
196}
197
199 Status error = GetInterface().Attach(attach_info);
202 if (error.Fail())
203 return error;
204 // NOTE: We need to set the PID before finishing to attach otherwise we will
205 // hit an assert when calling the attach completion handler.
206 DidLaunch();
207
208 return {};
209}
210
211Status
213 const ProcessAttachInfo &attach_info) {
214 return DoAttach(attach_info);
215}
216
218 const char *process_name, const ProcessAttachInfo &attach_info) {
219 return DoAttach(attach_info);
220}
221
223 process_arch = GetArchitecture();
224}
225
228
229 if (GetInterface().ShouldStop()) {
231 LLDB_LOGF(log, "ScriptedProcess::%s Immediate stop", __FUNCTION__);
232 return {};
233 }
234
235 LLDB_LOGF(log, "ScriptedProcess::%s Delayed stop", __FUNCTION__);
236 return GetInterface().Stop();
237}
238
240
242
243size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
244 Status &error) {
245 lldb::DataExtractorSP data_extractor_sp =
247
248 if (!data_extractor_sp || !data_extractor_sp->GetByteSize() || error.Fail())
249 return 0;
250
251 offset_t bytes_copied = data_extractor_sp->CopyByteOrderedData(
252 0, data_extractor_sp->GetByteSize(), buf, size, GetByteOrder());
253
254 if (!bytes_copied || bytes_copied == LLDB_INVALID_OFFSET)
255 return ScriptedInterface::ErrorWithMessage<size_t>(
256 LLVM_PRETTY_FUNCTION, "Failed to copy read memory to buffer.", error);
257
258 // FIXME: We should use the diagnostic system to report a warning if the
259 // `bytes_copied` is different from `size`.
260
261 return bytes_copied;
262}
263
264size_t ScriptedProcess::DoWriteMemory(lldb::addr_t vm_addr, const void *buf,
265 size_t size, Status &error) {
266 lldb::DataExtractorSP data_extractor_sp = std::make_shared<DataExtractor>(
267 buf, size, GetByteOrder(), GetAddressByteSize());
268
269 if (!data_extractor_sp || !data_extractor_sp->GetByteSize())
270 return 0;
271
272 lldb::offset_t bytes_written =
273 GetInterface().WriteMemoryAtAddress(vm_addr, data_extractor_sp, error);
274
275 if (!bytes_written || bytes_written == LLDB_INVALID_OFFSET)
276 return ScriptedInterface::ErrorWithMessage<size_t>(
277 LLVM_PRETTY_FUNCTION, "Failed to copy write buffer to memory.", error);
278
279 // FIXME: We should use the diagnostic system to report a warning if the
280 // `bytes_written` is different from `size`.
281
282 return bytes_written;
283}
284
286 return GetTarget().GetArchitecture();
287}
288
290 MemoryRegionInfo &region) {
292 if (auto region_or_err =
293 GetInterface().GetMemoryRegionContainingAddress(load_addr, error))
294 region = *region_or_err;
295
296 return error;
297}
298
301 lldb::addr_t address = 0;
302
303 while (auto region_or_err =
304 GetInterface().GetMemoryRegionContainingAddress(address, error)) {
305 if (error.Fail())
306 break;
307
308 MemoryRegionInfo &mem_region = *region_or_err;
309 auto range = mem_region.GetRange();
310 address += range.GetRangeBase() + range.GetByteSize();
311 region_list.push_back(mem_region);
312 }
313
314 return error;
315}
316
318
320 ThreadList &new_thread_list) {
321 // TODO: Implement
322 // This is supposed to get the current set of threads, if any of them are in
323 // old_thread_list then they get copied to new_thread_list, and then any
324 // actually new threads will get added to new_thread_list.
326
329
330 if (!thread_info_sp)
331 return ScriptedInterface::ErrorWithMessage<bool>(
332 LLVM_PRETTY_FUNCTION,
333 "Couldn't fetch thread list from Scripted Process.", error);
334
335 // Because `StructuredData::Dictionary` uses a `std::map<ConstString,
336 // ObjectSP>` for storage, each item is sorted based on the key alphabetical
337 // order. Since `GetThreadsInfo` provides thread indices as the key element,
338 // thread info comes ordered alphabetically, instead of numerically, so we
339 // need to sort the thread indices before creating thread.
340
341 StructuredData::ArraySP keys = thread_info_sp->GetKeys();
342
343 std::map<size_t, StructuredData::ObjectSP> sorted_threads;
344 auto sort_keys = [&sorted_threads,
345 &thread_info_sp](StructuredData::Object *item) -> bool {
346 if (!item)
347 return false;
348
349 llvm::StringRef key = item->GetStringValue();
350 size_t idx = 0;
351
352 // Make sure the provided index is actually an integer
353 if (!llvm::to_integer(key, idx))
354 return false;
355
356 sorted_threads[idx] = thread_info_sp->GetValueForKey(key);
357 return true;
358 };
359
360 size_t thread_count = thread_info_sp->GetSize();
361
362 if (!keys->ForEach(sort_keys) || sorted_threads.size() != thread_count)
363 // Might be worth showing the unsorted thread list instead of return early.
364 return ScriptedInterface::ErrorWithMessage<bool>(
365 LLVM_PRETTY_FUNCTION, "Couldn't sort thread list.", error);
366
367 auto create_scripted_thread =
368 [this, &error, &new_thread_list](
369 const std::pair<size_t, StructuredData::ObjectSP> pair) -> bool {
370 size_t idx = pair.first;
371 StructuredData::ObjectSP object_sp = pair.second;
372
373 if (!object_sp)
374 return ScriptedInterface::ErrorWithMessage<bool>(
375 LLVM_PRETTY_FUNCTION, "Invalid thread info object", error);
376
377 auto thread_or_error =
378 ScriptedThread::Create(*this, object_sp->GetAsGeneric());
379
380 if (!thread_or_error)
381 return ScriptedInterface::ErrorWithMessage<bool>(
382 LLVM_PRETTY_FUNCTION, toString(thread_or_error.takeError()), error);
383
384 ThreadSP thread_sp = thread_or_error.get();
385 lldbassert(thread_sp && "Couldn't initialize scripted thread.");
386
387 RegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext();
388 if (!reg_ctx_sp)
389 return ScriptedInterface::ErrorWithMessage<bool>(
390 LLVM_PRETTY_FUNCTION,
391 llvm::Twine("Invalid Register Context for thread " + llvm::Twine(idx))
392 .str(),
393 error);
394
395 new_thread_list.AddThread(thread_sp);
396
397 return true;
398 };
399
400 llvm::for_each(sorted_threads, create_scripted_thread);
401
402 return new_thread_list.GetSize(false) > 0;
403}
404
406 // Let all threads recover from stopping and do any clean up based on the
407 // previous thread state (if any).
409}
410
412 info.Clear();
413 info.SetProcessID(GetID());
415 lldb::ModuleSP module_sp = GetTarget().GetExecutableModule();
416 if (module_sp) {
417 const bool add_exe_file_as_first_arg = false;
418 info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
419 add_exe_file_as_first_arg);
420 }
421 return true;
422}
423
427 auto error_with_message = [&error](llvm::StringRef message) {
428 return ScriptedInterface::ErrorWithMessage<bool>(LLVM_PRETTY_FUNCTION,
429 message.data(), error);
430 };
431
433
434 if (!loaded_images_sp || !loaded_images_sp->GetSize())
435 return ScriptedInterface::ErrorWithMessage<StructuredData::ObjectSP>(
436 LLVM_PRETTY_FUNCTION, "No loaded images.", error);
437
438 ModuleList module_list;
439 Target &target = GetTarget();
440
441 auto reload_image = [&target, &module_list, &error_with_message](
442 StructuredData::Object *obj) -> bool {
444
445 if (!dict)
446 return error_with_message("Couldn't cast image object into dictionary.");
447
448 ModuleSpec module_spec;
449 llvm::StringRef value;
450
451 bool has_path = dict->HasKey("path");
452 bool has_uuid = dict->HasKey("uuid");
453 if (!has_path && !has_uuid)
454 return error_with_message("Dictionary should have key 'path' or 'uuid'");
455 if (!dict->HasKey("load_addr"))
456 return error_with_message("Dictionary is missing key 'load_addr'");
457
458 if (has_path) {
459 dict->GetValueForKeyAsString("path", value);
460 module_spec.GetFileSpec().SetPath(value);
461 }
462
463 if (has_uuid) {
464 dict->GetValueForKeyAsString("uuid", value);
465 module_spec.GetUUID().SetFromStringRef(value);
466 }
467 module_spec.GetArchitecture() = target.GetArchitecture();
468
469 ModuleSP module_sp =
470 target.GetOrCreateModule(module_spec, true /* notify */);
471
472 if (!module_sp)
473 return error_with_message("Couldn't create or get module.");
474
477 dict->GetValueForKeyAsInteger("load_addr", load_addr);
478 dict->GetValueForKeyAsInteger("slide", slide);
479 if (load_addr == LLDB_INVALID_ADDRESS)
480 return error_with_message(
481 "Couldn't get valid load address or slide offset.");
482
483 if (slide != LLDB_INVALID_OFFSET)
484 load_addr += slide;
485
486 bool changed = false;
487 module_sp->SetLoadAddress(target, load_addr, false /*=value_is_offset*/,
488 changed);
489
490 if (!changed && !module_sp->GetObjectFile())
491 return error_with_message("Couldn't set the load address for module.");
492
493 dict->GetValueForKeyAsString("path", value);
494 FileSpec objfile(value);
495 module_sp->SetFileSpecAndObjectName(objfile, objfile.GetFilename());
496
497 return module_list.AppendIfNeeded(module_sp);
498 };
499
500 if (!loaded_images_sp->ForEach(reload_image))
501 return ScriptedInterface::ErrorWithMessage<StructuredData::ObjectSP>(
502 LLVM_PRETTY_FUNCTION, "Couldn't reload all images.", error);
503
504 target.ModulesDidLoad(module_list);
505
506 return loaded_images_sp;
507}
508
511
513 if (!metadata_sp || !metadata_sp->GetSize())
514 return ScriptedInterface::ErrorWithMessage<StructuredData::DictionarySP>(
515 LLVM_PRETTY_FUNCTION, "No metadata.", error);
516
517 return metadata_sp;
518}
519
522 for (ThreadSP thread_sp : Threads()) {
523 if (const char *queue_name = thread_sp->GetQueueName()) {
524 QueueSP queue_sp = std::make_shared<Queue>(
525 m_process->shared_from_this(), thread_sp->GetQueueID(), queue_name);
526 m_queue_list.AddQueue(queue_sp);
527 }
528 }
529}
530
533 return *m_interface_up;
534}
535
537 StructuredData::GenericSP object_instance_sp =
539 if (object_instance_sp &&
540 object_instance_sp->GetType() == eStructuredDataTypeGeneric)
541 return object_instance_sp->GetAsGeneric()->GetValue();
542 return nullptr;
543}
static llvm::raw_ostream & error(Stream &strm)
#define lldbassert(x)
Definition: LLDBAssert.h:15
#define LLDB_LOGF(log,...)
Definition: Log.h:344
#define LLDB_PLUGIN_DEFINE(PluginName)
Definition: PluginManager.h:31
static constexpr lldb::ScriptLanguage g_supported_script_languages[]
An architecture specification class.
Definition: ArchSpec.h:32
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
A file utility class.
Definition: FileSpec.h:56
const ConstString & GetFilename() const
Filename string const get accessor.
Definition: FileSpec.h:240
void SetPath(llvm::StringRef p)
Temporary helper for FileSystem change.
Definition: FileSpec.h:279
A collection class for Module objects.
Definition: ModuleList.h:82
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
FileSpec & GetFileSpec()
Definition: ModuleSpec.h:53
ArchSpec & GetArchitecture()
Definition: ModuleSpec.h:89
A class that describes an executable image and its associated object and symbol files.
Definition: Module.h:88
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
void SetExecutableFile(const FileSpec &exe_file, bool add_exe_file_as_first_arg)
Definition: ProcessInfo.cpp:63
void SetArchitecture(const ArchSpec &arch)
Definition: ProcessInfo.h:65
void SetProcessID(lldb::pid_t pid)
Definition: ProcessInfo.h:69
A plug-in interface definition class for debugging a process.
Definition: Process.h:343
virtual void Finalize()
This object is about to be destroyed, do any necessary cleanup.
Definition: Process.cpp:512
lldb::pid_t GetID() const
Returns the pid of the process or LLDB_INVALID_PROCESS_ID if there is no known pid.
Definition: Process.h:527
QueueList m_queue_list
The list of libdispatch queues at a given stop point.
Definition: Process.h:2936
lldb::ByteOrder GetByteOrder() const
Definition: Process.cpp:3379
ThreadList::ThreadIterable Threads()
Definition: Process.h:2119
ThreadPlanStackMap m_thread_plans
This is the list of thread plans for threads in m_thread_list, as well as threads we knew existed,...
Definition: Process.h:2927
uint32_t GetAddressByteSize() const
Definition: Process.cpp:3383
void SetPrivateState(lldb::StateType state)
Definition: Process.cpp:1416
ThreadList m_thread_list
The threads for this process as the user will see them.
Definition: Process.h:2923
lldb::pid_t m_pid
Definition: Process.h:2893
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1220
void AddQueue(lldb::QueueSP queue)
Add a Queue to the QueueList.
Definition: QueueList.cpp:40
virtual lldb::ScriptedProcessInterfaceUP CreateScriptedProcessInterface()
StructuredData::GenericSP GetScriptObjectInstance()
llvm::StringRef GetClassName() const
StructuredData::DictionarySP GetArgsSP() const
virtual lldb::DataExtractorSP ReadMemoryAtAddress(lldb::addr_t address, size_t size, Status &error)
virtual StructuredData::DictionarySP GetThreadsInfo()
virtual Status Attach(const ProcessAttachInfo &attach_info)
virtual StructuredData::DictionarySP GetMetadata()
virtual StructuredData::ArraySP GetLoadedImages()
virtual lldb::offset_t WriteMemoryAtAddress(lldb::addr_t addr, lldb::DataExtractorSP data_sp, Status &error)
StructuredData::GenericSP CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx, StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj=nullptr) override
Status DoResume() override
Resumes all of a process's threads as configured using the Thread run control functions.
Status DoAttachToProcessWithID(lldb::pid_t pid, const ProcessAttachInfo &attach_info) override
Attach to an existing process using a process ID.
bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override
Check if a plug-in instance can debug the file in module.
bool DoUpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) override
Update the thread list following process plug-in's specific logic.
size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Status &error) override
Actually do the reading of memory from a process.
lldb_private::StructuredData::ObjectSP GetLoadedDynamicLibrariesInfos() override
const ScriptedMetadata m_scripted_metadata
void DidAttach(ArchSpec &process_arch) override
Called after attaching a process.
static llvm::StringRef GetPluginNameStatic()
Status GetMemoryRegions(lldb_private::MemoryRegionInfos &region_list) override
Obtain all the mapped memory regions within this process.
static bool IsScriptLanguageSupported(lldb::ScriptLanguage language)
bool IsAlive() override
Check if a process is still alive.
Status DoAttach(const ProcessAttachInfo &attach_info)
bool GetProcessInfo(ProcessInstanceInfo &info) override
Status DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override
Launch a new process.
size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Status &error) override
Actually do the writing of memory to a process.
ScriptedProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const ScriptedMetadata &scripted_metadata, Status &error)
lldb::ScriptedProcessInterfaceUP m_interface_up
lldb_private::StructuredData::DictionarySP GetMetadata() override
Fetch process defined metadata.
Status DoAttachToProcessWithName(const char *process_name, const ProcessAttachInfo &attach_info) override
Attach to an existing process using a partial process name.
void RefreshStateAfterStop() override
Currently called as part of ShouldStop.
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *crash_file_path, bool can_connect)
static llvm::StringRef GetPluginDescriptionStatic()
ScriptedProcessInterface & GetInterface() const
void DidLaunch() override
Called after launching a process.
Status DoGetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info) override
DoGetMemoryRegionInfo is called by GetMemoryRegionInfo after it has removed non address bits from loa...
static llvm::Expected< std::shared_ptr< ScriptedThread > > Create(ScriptedProcess &process, StructuredData::Generic *script_object=nullptr)
An error handling class.
Definition: Status.h:44
bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result) const
bool HasKey(llvm::StringRef key) const
std::shared_ptr< Generic > GenericSP
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
std::shared_ptr< Array > ArraySP
const ProcessLaunchInfo & GetProcessLaunchInfo() const
Definition: Target.cpp:4661
void ModulesDidLoad(ModuleList &module_list)
Definition: Target.cpp:1645
lldb::ModuleSP GetOrCreateModule(const ModuleSpec &module_spec, bool notify, Status *error_ptr=nullptr)
Find a binary on the system and return its Module, or return an existing Module that is already in th...
Definition: Target.cpp:2110
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
Definition: Target.cpp:1371
const ArchSpec & GetArchitecture() const
Definition: Target.h:990
void AddThread(const lldb::ThreadSP &thread_sp)
uint32_t GetSize(bool can_update=true)
Definition: ThreadList.cpp:83
void ClearThreadCache()
Clear the Thread* cache that each ThreadPlan contains.
bool SetFromStringRef(llvm::StringRef str)
Definition: UUID.cpp:97
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:74
#define LLDB_INVALID_OFFSET
Definition: lldb-defines.h:85
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:309
const char * StateAsCString(lldb::StateType state)
Converts a StateType to a C string.
Definition: State.cpp:14
const char * toString(AppleArm64ExceptionClass EC)
Definition: SBAddress.h:15
ScriptLanguage
Script interpreter types.
uint64_t offset_t
Definition: lldb-types.h:83
StateType
Process and Thread States.
@ eStateStopped
Process or thread is stopped and can be examined.
@ eStateRunning
Process or thread is running and can't be examined.
uint64_t pid_t
Definition: lldb-types.h:81
uint64_t addr_t
Definition: lldb-types.h:79
@ eStructuredDataTypeGeneric
BaseType GetRangeBase() const
Definition: RangeMap.h:46