[lldb] Guarantee the lifetimes of all strings returned from SBAPI

LLDB should guarantee that the strings returned by SBAPI methods
live forever. I went through every method that returns a string and made
sure that it was added to the ConstString StringPool before returning if
it wasn't obvious that it was already doing so.
I've also updated the docs to document this behavior.

Differential Revision: https://reviews.llvm.org/D150804
This commit is contained in:
Alex Langford 2023-05-17 10:44:38 -07:00
parent 6abd8e30f4
commit 41714c959d
33 changed files with 303 additions and 306 deletions

View File

@ -72,6 +72,15 @@ building the LLDB framework for macOS, the headers are processed with
``unifdef`` prior to being copied into the framework bundle to remove macros
involving SWIG.
Lifetime
--------
Many SB API methods will return strings in the form of ``const char *`` values.
Once created, these strings are guaranteed to live until the end of the
debugging session. LLDB owns these strings, clients should not attempt to free
them. Doing so may cause LLDB to crash.
Note that this only affects the C++ API as scripting languages usually
will usually create native string types from the ``const char *`` value.
API Instrumentation
-------------------

View File

@ -94,7 +94,7 @@ void SBAttachInfo::SetResumeCount(uint32_t c) {
const char *SBAttachInfo::GetProcessPluginName() {
LLDB_INSTRUMENT_VA(this);
return m_opaque_sp->GetProcessPluginName();
return ConstString(m_opaque_sp->GetProcessPluginName()).GetCString();
}
void SBAttachInfo::SetProcessPluginName(const char *plugin_name) {

View File

@ -284,12 +284,12 @@ const char *SBBreakpoint::GetCondition() {
LLDB_INSTRUMENT_VA(this);
BreakpointSP bkpt_sp = GetSP();
if (bkpt_sp) {
std::lock_guard<std::recursive_mutex> guard(
bkpt_sp->GetTarget().GetAPIMutex());
return bkpt_sp->GetConditionText();
}
return nullptr;
if (!bkpt_sp)
return nullptr;
std::lock_guard<std::recursive_mutex> guard(
bkpt_sp->GetTarget().GetAPIMutex());
return ConstString(bkpt_sp->GetConditionText()).GetCString();
}
void SBBreakpoint::SetAutoContinue(bool auto_continue) {
@ -411,18 +411,17 @@ void SBBreakpoint::SetThreadName(const char *thread_name) {
const char *SBBreakpoint::GetThreadName() const {
LLDB_INSTRUMENT_VA(this);
const char *name = nullptr;
BreakpointSP bkpt_sp = GetSP();
if (bkpt_sp) {
std::lock_guard<std::recursive_mutex> guard(
bkpt_sp->GetTarget().GetAPIMutex());
const ThreadSpec *thread_spec =
bkpt_sp->GetOptions().GetThreadSpecNoCreate();
if (thread_spec != nullptr)
name = thread_spec->GetName();
}
if (!bkpt_sp)
return nullptr;
return name;
std::lock_guard<std::recursive_mutex> guard(
bkpt_sp->GetTarget().GetAPIMutex());
if (const ThreadSpec *thread_spec =
bkpt_sp->GetOptions().GetThreadSpecNoCreate())
return ConstString(thread_spec->GetName()).GetCString();
return nullptr;
}
void SBBreakpoint::SetQueueName(const char *queue_name) {
@ -439,18 +438,17 @@ void SBBreakpoint::SetQueueName(const char *queue_name) {
const char *SBBreakpoint::GetQueueName() const {
LLDB_INSTRUMENT_VA(this);
const char *name = nullptr;
BreakpointSP bkpt_sp = GetSP();
if (bkpt_sp) {
std::lock_guard<std::recursive_mutex> guard(
bkpt_sp->GetTarget().GetAPIMutex());
const ThreadSpec *thread_spec =
bkpt_sp->GetOptions().GetThreadSpecNoCreate();
if (thread_spec)
name = thread_spec->GetQueueName();
}
if (!bkpt_sp)
return nullptr;
return name;
std::lock_guard<std::recursive_mutex> guard(
bkpt_sp->GetTarget().GetAPIMutex());
if (const ThreadSpec *thread_spec =
bkpt_sp->GetOptions().GetThreadSpecNoCreate())
return ConstString(thread_spec->GetQueueName()).GetCString();
return nullptr;
}
size_t SBBreakpoint::GetNumResolvedLocations() const {

View File

@ -169,12 +169,12 @@ const char *SBBreakpointLocation::GetCondition() {
LLDB_INSTRUMENT_VA(this);
BreakpointLocationSP loc_sp = GetSP();
if (loc_sp) {
std::lock_guard<std::recursive_mutex> guard(
loc_sp->GetTarget().GetAPIMutex());
return loc_sp->GetConditionText();
}
return nullptr;
if (!loc_sp)
return nullptr;
std::lock_guard<std::recursive_mutex> guard(
loc_sp->GetTarget().GetAPIMutex());
return ConstString(loc_sp->GetConditionText()).GetCString();
}
void SBBreakpointLocation::SetAutoContinue(bool auto_continue) {
@ -366,12 +366,12 @@ const char *SBBreakpointLocation::GetThreadName() const {
LLDB_INSTRUMENT_VA(this);
BreakpointLocationSP loc_sp = GetSP();
if (loc_sp) {
std::lock_guard<std::recursive_mutex> guard(
loc_sp->GetTarget().GetAPIMutex());
return loc_sp->GetThreadName();
}
return nullptr;
if (!loc_sp)
return nullptr;
std::lock_guard<std::recursive_mutex> guard(
loc_sp->GetTarget().GetAPIMutex());
return ConstString(loc_sp->GetThreadName()).GetCString();
}
void SBBreakpointLocation::SetQueueName(const char *queue_name) {
@ -389,12 +389,12 @@ const char *SBBreakpointLocation::GetQueueName() const {
LLDB_INSTRUMENT_VA(this);
BreakpointLocationSP loc_sp = GetSP();
if (loc_sp) {
std::lock_guard<std::recursive_mutex> guard(
loc_sp->GetTarget().GetAPIMutex());
return loc_sp->GetQueueName();
}
return nullptr;
if (!loc_sp)
return nullptr;
std::lock_guard<std::recursive_mutex> guard(
loc_sp->GetTarget().GetAPIMutex());
return ConstString(loc_sp->GetQueueName()).GetCString();
}
bool SBBreakpointLocation::IsResolved() {

View File

@ -199,7 +199,7 @@ const char *SBBreakpointName::GetName() const {
if (!m_impl_up)
return "<Invalid Breakpoint Name Object>";
return m_impl_up->GetName();
return ConstString(m_impl_up->GetName()).GetCString();
}
void SBBreakpointName::SetEnabled(bool enable) {
@ -315,9 +315,9 @@ const char *SBBreakpointName::GetCondition() {
return nullptr;
std::lock_guard<std::recursive_mutex> guard(
m_impl_up->GetTarget()->GetAPIMutex());
m_impl_up->GetTarget()->GetAPIMutex());
return bp_name->GetOptions().GetConditionText();
return ConstString(bp_name->GetOptions().GetConditionText()).GetCString();
}
void SBBreakpointName::SetAutoContinue(bool auto_continue) {
@ -423,9 +423,10 @@ const char *SBBreakpointName::GetThreadName() const {
return nullptr;
std::lock_guard<std::recursive_mutex> guard(
m_impl_up->GetTarget()->GetAPIMutex());
m_impl_up->GetTarget()->GetAPIMutex());
return bp_name->GetOptions().GetThreadSpec()->GetName();
return ConstString(bp_name->GetOptions().GetThreadSpec()->GetName())
.GetCString();
}
void SBBreakpointName::SetQueueName(const char *queue_name) {
@ -450,9 +451,10 @@ const char *SBBreakpointName::GetQueueName() const {
return nullptr;
std::lock_guard<std::recursive_mutex> guard(
m_impl_up->GetTarget()->GetAPIMutex());
m_impl_up->GetTarget()->GetAPIMutex());
return bp_name->GetOptions().GetThreadSpec()->GetQueueName();
return ConstString(bp_name->GetOptions().GetThreadSpec()->GetQueueName())
.GetCString();
}
void SBBreakpointName::SetCommandLineCommands(SBStringList &commands) {
@ -496,7 +498,7 @@ const char *SBBreakpointName::GetHelpString() const {
if (!bp_name)
return "";
return bp_name->GetHelp();
return ConstString(bp_name->GetHelp()).GetCString();
}
void SBBreakpointName::SetHelpString(const char *help_string) {

View File

@ -516,14 +516,16 @@ const char *SBCommandInterpreter::GetArgumentTypeAsCString(
const lldb::CommandArgumentType arg_type) {
LLDB_INSTRUMENT_VA(arg_type);
return CommandObject::GetArgumentTypeAsCString(arg_type);
return ConstString(CommandObject::GetArgumentTypeAsCString(arg_type))
.GetCString();
}
const char *SBCommandInterpreter::GetArgumentDescriptionAsCString(
const lldb::CommandArgumentType arg_type) {
LLDB_INSTRUMENT_VA(arg_type);
return CommandObject::GetArgumentDescriptionAsCString(arg_type);
return ConstString(CommandObject::GetArgumentDescriptionAsCString(arg_type))
.GetCString();
}
bool SBCommandInterpreter::EventIsCommandInterpreterEvent(

View File

@ -297,16 +297,19 @@ int64_t SBData::GetSignedInt64(lldb::SBError &error, lldb::offset_t offset) {
const char *SBData::GetString(lldb::SBError &error, lldb::offset_t offset) {
LLDB_INSTRUMENT_VA(this, error, offset);
const char *value = nullptr;
if (!m_opaque_sp.get()) {
if (!m_opaque_sp) {
error.SetErrorString("no value to read from");
} else {
uint32_t old_offset = offset;
value = m_opaque_sp->GetCStr(&offset);
if (offset == old_offset || (value == nullptr))
error.SetErrorString("unable to read data");
return nullptr;
}
return value;
lldb::offset_t old_offset = offset;
const char *value = m_opaque_sp->GetCStr(&offset);
if (offset == old_offset || value == nullptr) {
error.SetErrorString("unable to read data");
return nullptr;
}
return ConstString(value).GetCString();
}
bool SBData::GetDescription(lldb::SBStream &description,

View File

@ -63,7 +63,7 @@ const char *SBEvent::GetDataFlavor() {
if (lldb_event) {
EventData *event_data = lldb_event->GetData();
if (event_data)
return lldb_event->GetData()->GetFlavor().data();
return ConstString(lldb_event->GetData()->GetFlavor()).GetCString();
}
return nullptr;
}
@ -166,8 +166,9 @@ SBEvent::operator bool() const {
const char *SBEvent::GetCStringFromEvent(const SBEvent &event) {
LLDB_INSTRUMENT_VA(event);
return static_cast<const char *>(
EventDataBytes::GetBytesFromEvent(event.get()));
return ConstString(static_cast<const char *>(
EventDataBytes::GetBytesFromEvent(event.get())))
.GetCString();
}
bool SBEvent::GetDescription(SBStream &description) {

View File

@ -190,7 +190,7 @@ void SBExpressionOptions::SetSuppressPersistentResult(bool b) {
const char *SBExpressionOptions::GetPrefix() const {
LLDB_INSTRUMENT_VA(this);
return m_opaque_up->GetPrefix();
return ConstString(m_opaque_up->GetPrefix()).GetCString();
}
void SBExpressionOptions::SetPrefix(const char *prefix) {

View File

@ -708,24 +708,20 @@ SBThread SBFrame::GetThread() const {
const char *SBFrame::Disassemble() const {
LLDB_INSTRUMENT_VA(this);
const char *disassembly = nullptr;
std::unique_lock<std::recursive_mutex> lock;
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
Process *process = exe_ctx.GetProcessPtr();
if (target && process) {
Process::StopLocker stop_locker;
if (stop_locker.TryLock(&process->GetRunLock())) {
frame = exe_ctx.GetFramePtr();
if (frame) {
disassembly = frame->Disassemble();
}
}
if (!target || !process)
return nullptr;
Process::StopLocker stop_locker;
if (stop_locker.TryLock(&process->GetRunLock())) {
if (auto *frame = exe_ctx.GetFramePtr())
return ConstString(frame->Disassemble()).GetCString();
}
return disassembly;
return nullptr;
}
SBValueList SBFrame::GetVariables(bool arguments, bool locals, bool statics,

View File

@ -54,30 +54,27 @@ SBFunction::operator bool() const {
const char *SBFunction::GetName() const {
LLDB_INSTRUMENT_VA(this);
const char *cstr = nullptr;
if (m_opaque_ptr)
cstr = m_opaque_ptr->GetName().AsCString();
return m_opaque_ptr->GetName().AsCString();
return cstr;
return nullptr;
}
const char *SBFunction::GetDisplayName() const {
LLDB_INSTRUMENT_VA(this);
const char *cstr = nullptr;
if (m_opaque_ptr)
cstr = m_opaque_ptr->GetMangled().GetDisplayDemangledName().AsCString();
return m_opaque_ptr->GetMangled().GetDisplayDemangledName().AsCString();
return cstr;
return nullptr;
}
const char *SBFunction::GetMangledName() const {
LLDB_INSTRUMENT_VA(this);
const char *cstr = nullptr;
if (m_opaque_ptr)
cstr = m_opaque_ptr->GetMangled().GetMangledName().AsCString();
return cstr;
return m_opaque_ptr->GetMangled().GetMangledName().AsCString();
return nullptr;
}
bool SBFunction::operator==(const SBFunction &rhs) const {
@ -166,19 +163,22 @@ SBAddress SBFunction::GetEndAddress() {
const char *SBFunction::GetArgumentName(uint32_t arg_idx) {
LLDB_INSTRUMENT_VA(this, arg_idx);
if (m_opaque_ptr) {
Block &block = m_opaque_ptr->GetBlock(true);
VariableListSP variable_list_sp = block.GetBlockVariableList(true);
if (variable_list_sp) {
VariableList arguments;
variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
arguments, true);
lldb::VariableSP variable_sp = arguments.GetVariableAtIndex(arg_idx);
if (variable_sp)
return variable_sp->GetName().GetCString();
}
}
return nullptr;
if (!m_opaque_ptr)
return nullptr;
Block &block = m_opaque_ptr->GetBlock(true);
VariableListSP variable_list_sp = block.GetBlockVariableList(true);
if (!variable_list_sp)
return nullptr;
VariableList arguments;
variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
arguments, true);
lldb::VariableSP variable_sp = arguments.GetVariableAtIndex(arg_idx);
if (!variable_sp)
return nullptr;
return variable_sp->GetName().GetCString();
}
uint32_t SBFunction::GetPrologueByteSize() {

View File

@ -111,57 +111,57 @@ const char *SBInstruction::GetMnemonic(SBTarget target) {
LLDB_INSTRUMENT_VA(this, target);
lldb::InstructionSP inst_sp(GetOpaque());
if (inst_sp) {
ExecutionContext exe_ctx;
TargetSP target_sp(target.GetSP());
std::unique_lock<std::recursive_mutex> lock;
if (target_sp) {
lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
if (!inst_sp)
return nullptr;
target_sp->CalculateExecutionContext(exe_ctx);
exe_ctx.SetProcessSP(target_sp->GetProcessSP());
}
return inst_sp->GetMnemonic(&exe_ctx);
ExecutionContext exe_ctx;
TargetSP target_sp(target.GetSP());
std::unique_lock<std::recursive_mutex> lock;
if (target_sp) {
lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
target_sp->CalculateExecutionContext(exe_ctx);
exe_ctx.SetProcessSP(target_sp->GetProcessSP());
}
return nullptr;
return ConstString(inst_sp->GetMnemonic(&exe_ctx)).GetCString();
}
const char *SBInstruction::GetOperands(SBTarget target) {
LLDB_INSTRUMENT_VA(this, target);
lldb::InstructionSP inst_sp(GetOpaque());
if (inst_sp) {
ExecutionContext exe_ctx;
TargetSP target_sp(target.GetSP());
std::unique_lock<std::recursive_mutex> lock;
if (target_sp) {
lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
if (!inst_sp)
return nullptr;
target_sp->CalculateExecutionContext(exe_ctx);
exe_ctx.SetProcessSP(target_sp->GetProcessSP());
}
return inst_sp->GetOperands(&exe_ctx);
ExecutionContext exe_ctx;
TargetSP target_sp(target.GetSP());
std::unique_lock<std::recursive_mutex> lock;
if (target_sp) {
lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
target_sp->CalculateExecutionContext(exe_ctx);
exe_ctx.SetProcessSP(target_sp->GetProcessSP());
}
return nullptr;
return ConstString(inst_sp->GetOperands(&exe_ctx)).GetCString();
}
const char *SBInstruction::GetComment(SBTarget target) {
LLDB_INSTRUMENT_VA(this, target);
lldb::InstructionSP inst_sp(GetOpaque());
if (inst_sp) {
ExecutionContext exe_ctx;
TargetSP target_sp(target.GetSP());
std::unique_lock<std::recursive_mutex> lock;
if (target_sp) {
lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
if (!inst_sp)
return nullptr;
target_sp->CalculateExecutionContext(exe_ctx);
exe_ctx.SetProcessSP(target_sp->GetProcessSP());
}
return inst_sp->GetComment(&exe_ctx);
ExecutionContext exe_ctx;
TargetSP target_sp(target.GetSP());
std::unique_lock<std::recursive_mutex> lock;
if (target_sp) {
lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
target_sp->CalculateExecutionContext(exe_ctx);
exe_ctx.SetProcessSP(target_sp->GetProcessSP());
}
return nullptr;
return ConstString(inst_sp->GetComment(&exe_ctx)).GetCString();
}
lldb::InstructionControlFlowKind SBInstruction::GetControlFlowKind(lldb::SBTarget target) {

View File

@ -148,7 +148,8 @@ uint32_t SBLaunchInfo::GetNumArguments() {
const char *SBLaunchInfo::GetArgumentAtIndex(uint32_t idx) {
LLDB_INSTRUMENT_VA(this, idx);
return m_opaque_sp->GetArguments().GetArgumentAtIndex(idx);
return ConstString(m_opaque_sp->GetArguments().GetArgumentAtIndex(idx))
.GetCString();
}
void SBLaunchInfo::SetArguments(const char **argv, bool append) {
@ -176,7 +177,7 @@ const char *SBLaunchInfo::GetEnvironmentEntryAtIndex(uint32_t idx) {
if (idx > GetNumEnvironmentEntries())
return nullptr;
return m_opaque_sp->GetEnvp()[idx];
return ConstString(m_opaque_sp->GetEnvp()[idx]).GetCString();
}
void SBLaunchInfo::SetEnvironmentEntries(const char **envp, bool append) {
@ -233,7 +234,7 @@ void SBLaunchInfo::SetLaunchFlags(uint32_t flags) {
const char *SBLaunchInfo::GetProcessPluginName() {
LLDB_INSTRUMENT_VA(this);
return m_opaque_sp->GetProcessPluginName();
return ConstString(m_opaque_sp->GetProcessPluginName()).GetCString();
}
void SBLaunchInfo::SetProcessPluginName(const char *plugin_name) {
@ -315,7 +316,7 @@ void SBLaunchInfo::SetLaunchEventData(const char *data) {
const char *SBLaunchInfo::GetLaunchEventData() const {
LLDB_INSTRUMENT_VA(this);
return m_opaque_sp->GetLaunchEventData();
return ConstString(m_opaque_sp->GetLaunchEventData()).GetCString();
}
void SBLaunchInfo::SetDetachOnError(bool enable) {

View File

@ -173,20 +173,20 @@ const uint8_t *SBModule::GetUUIDBytes() const {
const char *SBModule::GetUUIDString() const {
LLDB_INSTRUMENT_VA(this);
const char *uuid_cstr = nullptr;
ModuleSP module_sp(GetSP());
if (module_sp) {
// We are going to return a "const char *" value through the public API, so
// we need to constify it so it gets added permanently the string pool and
// then we don't need to worry about the lifetime of the string as it will
// never go away once it has been put into the ConstString string pool
uuid_cstr = ConstString(module_sp->GetUUID().GetAsString()).GetCString();
}
if (!module_sp)
return nullptr;
if (uuid_cstr && uuid_cstr[0]) {
// We are going to return a "const char *" value through the public API, so
// we need to constify it so it gets added permanently the string pool and
// then we don't need to worry about the lifetime of the string as it will
// never go away once it has been put into the ConstString string pool
const char *uuid_cstr =
ConstString(module_sp->GetUUID().GetAsString()).GetCString();
// Note: SBModule::GetUUIDString's expected behavior is to return nullptr if
// the string we get is empty, so we must perform this check before returning.
if (uuid_cstr && uuid_cstr[0])
return uuid_cstr;
}
return nullptr;
}
@ -579,15 +579,15 @@ const char *SBModule::GetTriple() {
LLDB_INSTRUMENT_VA(this);
ModuleSP module_sp(GetSP());
if (module_sp) {
std::string triple(module_sp->GetArchitecture().GetTriple().str());
// Unique the string so we don't run into ownership issues since the const
// strings put the string into the string pool once and the strings never
// comes out
ConstString const_triple(triple.c_str());
return const_triple.GetCString();
}
return nullptr;
if (!module_sp)
return nullptr;
std::string triple(module_sp->GetArchitecture().GetTriple().str());
// Unique the string so we don't run into ownership issues since the const
// strings put the string into the string pool once and the strings never
// comes out
ConstString const_triple(triple.c_str());
return const_triple.GetCString();
}
uint32_t SBModule::GetAddressByteSize() {

View File

@ -100,7 +100,7 @@ const char *SBPlatformConnectOptions::GetURL() {
if (m_opaque_ptr->m_url.empty())
return nullptr;
return m_opaque_ptr->m_url.c_str();
return ConstString(m_opaque_ptr->m_url.c_str()).GetCString();
}
void SBPlatformConnectOptions::SetURL(const char *url) {
@ -203,7 +203,7 @@ const char *SBPlatformShellCommand::GetShell() {
if (m_opaque_ptr->m_shell.empty())
return nullptr;
return m_opaque_ptr->m_shell.c_str();
return ConstString(m_opaque_ptr->m_shell.c_str()).GetCString();
}
void SBPlatformShellCommand::SetShell(const char *shell_interpreter) {
@ -220,7 +220,7 @@ const char *SBPlatformShellCommand::GetCommand() {
if (m_opaque_ptr->m_command.empty())
return nullptr;
return m_opaque_ptr->m_command.c_str();
return ConstString(m_opaque_ptr->m_command.c_str()).GetCString();
}
void SBPlatformShellCommand::SetCommand(const char *shell_command) {
@ -237,7 +237,7 @@ const char *SBPlatformShellCommand::GetWorkingDirectory() {
if (m_opaque_ptr->m_working_dir.empty())
return nullptr;
return m_opaque_ptr->m_working_dir.c_str();
return ConstString(m_opaque_ptr->m_working_dir.c_str()).GetCString();
}
void SBPlatformShellCommand::SetWorkingDirectory(const char *path) {
@ -283,7 +283,7 @@ const char *SBPlatformShellCommand::GetOutput() {
if (m_opaque_ptr->m_output.empty())
return nullptr;
return m_opaque_ptr->m_output.c_str();
return ConstString(m_opaque_ptr->m_output.c_str()).GetCString();
}
// SBPlatform
@ -454,7 +454,7 @@ const char *SBPlatform::GetHostname() {
PlatformSP platform_sp(GetSP());
if (platform_sp)
return platform_sp->GetHostname();
return ConstString(platform_sp->GetHostname()).GetCString();
return nullptr;
}

View File

@ -507,14 +507,13 @@ int SBProcess::GetExitStatus() {
const char *SBProcess::GetExitDescription() {
LLDB_INSTRUMENT_VA(this);
const char *exit_desc = nullptr;
ProcessSP process_sp(GetSP());
if (process_sp) {
std::lock_guard<std::recursive_mutex> guard(
process_sp->GetTarget().GetAPIMutex());
exit_desc = process_sp->GetExitDescription();
}
return exit_desc;
if (!process_sp)
return nullptr;
std::lock_guard<std::recursive_mutex> guard(
process_sp->GetTarget().GetAPIMutex());
return ConstString(process_sp->GetExitDescription()).GetCString();
}
lldb::pid_t SBProcess::GetProcessID() {
@ -747,7 +746,9 @@ SBProcess::GetRestartedReasonAtIndexFromEvent(const lldb::SBEvent &event,
size_t idx) {
LLDB_INSTRUMENT_VA(event, idx);
return Process::ProcessEventData::GetRestartedReasonAtIndex(event.get(), idx);
return ConstString(Process::ProcessEventData::GetRestartedReasonAtIndex(
event.get(), idx))
.GetCString();
}
SBProcess SBProcess::GetProcessFromEvent(const SBEvent &event) {

View File

@ -57,11 +57,10 @@ SBProcessInfo::operator bool() const {
const char *SBProcessInfo::GetName() {
LLDB_INSTRUMENT_VA(this);
const char *name = nullptr;
if (m_opaque_up) {
name = m_opaque_up->GetName();
}
return name;
if (!m_opaque_up)
return nullptr;
return ConstString(m_opaque_up->GetName()).GetCString();
}
SBFileSpec SBProcessInfo::GetExecutableFile() {
@ -177,14 +176,12 @@ lldb::pid_t SBProcessInfo::GetParentProcessID() {
const char *SBProcessInfo::GetTriple() {
LLDB_INSTRUMENT_VA(this);
const char *triple = nullptr;
if (m_opaque_up) {
const auto &arch = m_opaque_up->GetArchitecture();
if (arch.IsValid()) {
// Const-ify the string so we don't need to worry about the lifetime of
// the string
triple = ConstString(arch.GetTriple().getTriple().c_str()).GetCString();
}
}
return triple;
if (!m_opaque_up)
return nullptr;
const auto &arch = m_opaque_up->GetArchitecture();
if (!arch.IsValid())
return nullptr;
return ConstString(arch.GetTriple().getTriple().c_str()).GetCString();
}

View File

@ -77,12 +77,10 @@ public:
}
const char *GetName() const {
const char *name = nullptr;
lldb::QueueSP queue_sp = m_queue_wp.lock();
if (queue_sp.get()) {
name = queue_sp->GetName();
}
return name;
if (!queue_sp)
return nullptr;
return ConstString(queue_sp->GetName()).GetCString();
}
void FetchThreads() {

View File

@ -47,7 +47,8 @@ const char *SBStream::GetData() {
if (m_is_file || m_opaque_up == nullptr)
return nullptr;
return static_cast<StreamString *>(m_opaque_up.get())->GetData();
return ConstString(static_cast<StreamString *>(m_opaque_up.get())->GetData())
.GetCString();
}
// If this stream is not redirected to a file, it will maintain a local cache

View File

@ -106,7 +106,7 @@ const char *SBStringList::GetStringAtIndex(size_t idx) {
LLDB_INSTRUMENT_VA(this, idx);
if (IsValid()) {
return m_opaque_up->GetStringAtIndex(idx);
return ConstString(m_opaque_up->GetStringAtIndex(idx)).GetCString();
}
return nullptr;
}
@ -115,7 +115,7 @@ const char *SBStringList::GetStringAtIndex(size_t idx) const {
LLDB_INSTRUMENT_VA(this, idx);
if (IsValid()) {
return m_opaque_up->GetStringAtIndex(idx);
return ConstString(m_opaque_up->GetStringAtIndex(idx)).GetCString();
}
return nullptr;
}

View File

@ -1578,27 +1578,27 @@ const char *SBTarget::GetTriple() {
LLDB_INSTRUMENT_VA(this);
TargetSP target_sp(GetSP());
if (target_sp) {
std::string triple(target_sp->GetArchitecture().GetTriple().str());
// Unique the string so we don't run into ownership issues since the const
// strings put the string into the string pool once and the strings never
// comes out
ConstString const_triple(triple.c_str());
return const_triple.GetCString();
}
return nullptr;
if (!target_sp)
return nullptr;
std::string triple(target_sp->GetArchitecture().GetTriple().str());
// Unique the string so we don't run into ownership issues since the const
// strings put the string into the string pool once and the strings never
// comes out
ConstString const_triple(triple.c_str());
return const_triple.GetCString();
}
const char *SBTarget::GetABIName() {
LLDB_INSTRUMENT_VA(this);
TargetSP target_sp(GetSP());
if (target_sp) {
std::string abi_name(target_sp->GetABIName().str());
ConstString const_name(abi_name.c_str());
return const_name.GetCString();
}
return nullptr;
if (!target_sp)
return nullptr;
std::string abi_name(target_sp->GetABIName().str());
ConstString const_name(abi_name.c_str());
return const_name.GetCString();
}
uint32_t SBTarget::GetDataByteSize() {

View File

@ -394,35 +394,33 @@ uint32_t SBThread::GetIndexID() const {
const char *SBThread::GetName() const {
LLDB_INSTRUMENT_VA(this);
const char *name = nullptr;
std::unique_lock<std::recursive_mutex> lock;
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (exe_ctx.HasThreadScope()) {
Process::StopLocker stop_locker;
if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
name = exe_ctx.GetThreadPtr()->GetName();
}
}
if (!exe_ctx.HasThreadScope())
return nullptr;
return name;
Process::StopLocker stop_locker;
if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
return ConstString(exe_ctx.GetThreadPtr()->GetName()).GetCString();
return nullptr;
}
const char *SBThread::GetQueueName() const {
LLDB_INSTRUMENT_VA(this);
const char *name = nullptr;
std::unique_lock<std::recursive_mutex> lock;
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (exe_ctx.HasThreadScope()) {
Process::StopLocker stop_locker;
if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
name = exe_ctx.GetThreadPtr()->GetQueueName();
}
}
if (!exe_ctx.HasThreadScope())
return nullptr;
return name;
Process::StopLocker stop_locker;
if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
return ConstString(exe_ctx.GetThreadPtr()->GetQueueName()).GetCString();
return nullptr;
}
lldb::queue_id_t SBThread::GetQueueID() const {

View File

@ -84,7 +84,10 @@ SBFileSpec SBTrace::SaveToDisk(SBError &error, const SBFileSpec &bundle_dir,
const char *SBTrace::GetStartConfigurationHelp() {
LLDB_INSTRUMENT_VA(this);
return m_opaque_sp ? m_opaque_sp->GetStartConfigurationHelp() : nullptr;
if (!m_opaque_sp)
return nullptr;
return ConstString(m_opaque_sp->GetStartConfigurationHelp()).GetCString();
}
SBError SBTrace::Start(const SBStructuredData &configuration) {

View File

@ -85,7 +85,7 @@ bool SBTraceCursor::IsError() const {
const char *SBTraceCursor::GetError() const {
LLDB_INSTRUMENT_VA(this);
return m_opaque_sp->GetError();
return ConstString(m_opaque_sp->GetError()).GetCString();
}
bool SBTraceCursor::IsEvent() const {
@ -103,7 +103,7 @@ lldb::TraceEvent SBTraceCursor::GetEventType() const {
const char *SBTraceCursor::GetEventTypeAsString() const {
LLDB_INSTRUMENT_VA(this);
return m_opaque_sp->GetEventTypeAsString();
return ConstString(m_opaque_sp->GetEventTypeAsString()).GetCString();
}
bool SBTraceCursor::IsInstruction() const {

View File

@ -809,14 +809,15 @@ const char *SBTypeMemberFunction::GetName() {
const char *SBTypeMemberFunction::GetDemangledName() {
LLDB_INSTRUMENT_VA(this);
if (m_opaque_sp) {
ConstString mangled_str = m_opaque_sp->GetMangledName();
if (mangled_str) {
Mangled mangled(mangled_str);
return mangled.GetDemangledName().GetCString();
}
}
return nullptr;
if (!m_opaque_sp)
return nullptr;
ConstString mangled_str = m_opaque_sp->GetMangledName();
if (!mangled_str)
return nullptr;
Mangled mangled(mangled_str);
return mangled.GetDemangledName().GetCString();
}
const char *SBTypeMemberFunction::GetMangledName() {

View File

@ -73,7 +73,7 @@ const char *SBTypeCategory::GetName() {
if (!IsValid())
return nullptr;
return m_opaque_sp->GetName();
return ConstString(m_opaque_sp->GetName()).GetCString();
}
lldb::LanguageType SBTypeCategory::GetLanguageAtIndex(uint32_t idx) {

View File

@ -85,13 +85,13 @@ uint32_t SBTypeFilter::GetNumberOfExpressionPaths() {
const char *SBTypeFilter::GetExpressionPathAtIndex(uint32_t i) {
LLDB_INSTRUMENT_VA(this, i);
if (IsValid()) {
const char *item = m_opaque_sp->GetExpressionPathAtIndex(i);
if (item && *item == '.')
item++;
return item;
}
return nullptr;
if (!IsValid())
return nullptr;
const char *item = m_opaque_sp->GetExpressionPathAtIndex(i);
if (item && *item == '.')
item++;
return ConstString(item).GetCString();
}
bool SBTypeFilter::ReplaceExpressionPathAtIndex(uint32_t i, const char *item) {

View File

@ -65,7 +65,7 @@ const char *SBTypeNameSpecifier::GetName() {
if (!IsValid())
return nullptr;
return m_opaque_sp->GetName();
return ConstString(m_opaque_sp->GetName()).GetCString();
}
SBType SBTypeNameSpecifier::GetType() {

View File

@ -222,11 +222,11 @@ const char *SBTypeSummary::GetData() {
const char *fname = script_summary_ptr->GetFunctionName();
const char *ftext = script_summary_ptr->GetPythonScript();
if (ftext && *ftext)
return ftext;
return fname;
return ConstString(ftext).GetCString();
return ConstString(fname).GetCString();
} else if (StringSummaryFormat *string_summary_ptr =
llvm::dyn_cast<StringSummaryFormat>(m_opaque_sp.get()))
return string_summary_ptr->GetSummaryString();
return ConstString(string_summary_ptr->GetSummaryString()).GetCString();
return nullptr;
}

View File

@ -78,9 +78,9 @@ const char *SBTypeSynthetic::GetData() {
if (!IsValid())
return nullptr;
if (IsClassCode())
return m_opaque_sp->GetPythonCode();
else
return m_opaque_sp->GetPythonClassName();
return ConstString(m_opaque_sp->GetPythonCode()).GetCString();
return ConstString(m_opaque_sp->GetPythonClassName()).GetCString();
}
void SBTypeSynthetic::SetClassName(const char *data) {

View File

@ -66,7 +66,7 @@ const char *SBUnixSignals::GetSignalAsCString(int32_t signo) const {
LLDB_INSTRUMENT_VA(this, signo);
if (auto signals_sp = GetSP())
return signals_sp->GetSignalAsCString(signo);
return ConstString(signals_sp->GetSignalAsCString(signo)).GetCString();
return nullptr;
}

View File

@ -291,39 +291,34 @@ user_id_t SBValue::GetID() {
const char *SBValue::GetName() {
LLDB_INSTRUMENT_VA(this);
const char *name = nullptr;
ValueLocker locker;
lldb::ValueObjectSP value_sp(GetSP(locker));
if (value_sp)
name = value_sp->GetName().GetCString();
if (!value_sp)
return nullptr;
return name;
return value_sp->GetName().GetCString();
}
const char *SBValue::GetTypeName() {
LLDB_INSTRUMENT_VA(this);
const char *name = nullptr;
ValueLocker locker;
lldb::ValueObjectSP value_sp(GetSP(locker));
if (value_sp) {
name = value_sp->GetQualifiedTypeName().GetCString();
}
if (!value_sp)
return nullptr;
return name;
return value_sp->GetQualifiedTypeName().GetCString();
}
const char *SBValue::GetDisplayTypeName() {
LLDB_INSTRUMENT_VA(this);
const char *name = nullptr;
ValueLocker locker;
lldb::ValueObjectSP value_sp(GetSP(locker));
if (value_sp) {
name = value_sp->GetDisplayTypeName().GetCString();
}
if (!value_sp)
return nullptr;
return name;
return value_sp->GetDisplayTypeName().GetCString();
}
size_t SBValue::GetByteSize() {
@ -357,14 +352,11 @@ bool SBValue::IsInScope() {
const char *SBValue::GetValue() {
LLDB_INSTRUMENT_VA(this);
const char *cstr = nullptr;
ValueLocker locker;
lldb::ValueObjectSP value_sp(GetSP(locker));
if (value_sp) {
cstr = value_sp->GetValueAsCString();
}
return cstr;
if (!value_sp)
return nullptr;
return ConstString(value_sp->GetValueAsCString()).GetCString();
}
ValueType SBValue::GetValueType() {
@ -382,14 +374,12 @@ ValueType SBValue::GetValueType() {
const char *SBValue::GetObjectDescription() {
LLDB_INSTRUMENT_VA(this);
const char *cstr = nullptr;
ValueLocker locker;
lldb::ValueObjectSP value_sp(GetSP(locker));
if (value_sp) {
cstr = value_sp->GetObjectDescription();
}
if (!value_sp)
return nullptr;
return cstr;
return ConstString(value_sp->GetObjectDescription()).GetCString();
}
SBType SBValue::GetType() {
@ -424,14 +414,12 @@ bool SBValue::GetValueDidChange() {
const char *SBValue::GetSummary() {
LLDB_INSTRUMENT_VA(this);
const char *cstr = nullptr;
ValueLocker locker;
lldb::ValueObjectSP value_sp(GetSP(locker));
if (value_sp) {
cstr = value_sp->GetSummaryAsCString();
}
if (!value_sp)
return nullptr;
return cstr;
return ConstString(value_sp->GetSummaryAsCString()).GetCString();
}
const char *SBValue::GetSummary(lldb::SBStream &stream,
@ -445,20 +433,18 @@ const char *SBValue::GetSummary(lldb::SBStream &stream,
if (value_sp->GetSummaryAsCString(buffer, options.ref()) && !buffer.empty())
stream.Printf("%s", buffer.c_str());
}
const char *cstr = stream.GetData();
return cstr;
return ConstString(stream.GetData()).GetCString();
}
const char *SBValue::GetLocation() {
LLDB_INSTRUMENT_VA(this);
const char *cstr = nullptr;
ValueLocker locker;
lldb::ValueObjectSP value_sp(GetSP(locker));
if (value_sp) {
cstr = value_sp->GetLocationAsCString();
}
return cstr;
if (!value_sp)
return nullptr;
return ConstString(value_sp->GetLocationAsCString()).GetCString();
}
// Deprecated - use the one that takes an lldb::SBError

View File

@ -210,12 +210,12 @@ const char *SBWatchpoint::GetCondition() {
LLDB_INSTRUMENT_VA(this);
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp) {
std::lock_guard<std::recursive_mutex> guard(
watchpoint_sp->GetTarget().GetAPIMutex());
return watchpoint_sp->GetConditionText();
}
return nullptr;
if (!watchpoint_sp)
return nullptr;
std::lock_guard<std::recursive_mutex> guard(
watchpoint_sp->GetTarget().GetAPIMutex());
return ConstString(watchpoint_sp->GetConditionText()).GetCString();
}
void SBWatchpoint::SetCondition(const char *condition) {
@ -323,16 +323,16 @@ const char *SBWatchpoint::GetWatchSpec() {
LLDB_INSTRUMENT_VA(this);
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp) {
std::lock_guard<std::recursive_mutex> guard(
watchpoint_sp->GetTarget().GetAPIMutex());
// Store the result of `GetWatchSpec()` as a ConstString
// so that the C string we return has a sufficiently long
// lifetime. Note this a memory leak but should be fairly
// low impact.
return ConstString(watchpoint_sp->GetWatchSpec()).AsCString();
}
return nullptr;
if (!watchpoint_sp)
return nullptr;
std::lock_guard<std::recursive_mutex> guard(
watchpoint_sp->GetTarget().GetAPIMutex());
// Store the result of `GetWatchSpec()` as a ConstString
// so that the C string we return has a sufficiently long
// lifetime. Note this a memory leak but should be fairly
// low impact.
return ConstString(watchpoint_sp->GetWatchSpec()).AsCString();
}
bool SBWatchpoint::IsWatchingReads() {