diff --git a/lldb/docs/design/sbapi.rst b/lldb/docs/design/sbapi.rst --- a/lldb/docs/design/sbapi.rst +++ b/lldb/docs/design/sbapi.rst @@ -72,6 +72,15 @@ ``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 ------------------- diff --git a/lldb/source/API/SBAttachInfo.cpp b/lldb/source/API/SBAttachInfo.cpp --- a/lldb/source/API/SBAttachInfo.cpp +++ b/lldb/source/API/SBAttachInfo.cpp @@ -94,7 +94,7 @@ 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) { diff --git a/lldb/source/API/SBBreakpoint.cpp b/lldb/source/API/SBBreakpoint.cpp --- a/lldb/source/API/SBBreakpoint.cpp +++ b/lldb/source/API/SBBreakpoint.cpp @@ -284,12 +284,12 @@ LLDB_INSTRUMENT_VA(this); BreakpointSP bkpt_sp = GetSP(); - if (bkpt_sp) { - std::lock_guard guard( - bkpt_sp->GetTarget().GetAPIMutex()); - return bkpt_sp->GetConditionText(); - } - return nullptr; + if (!bkpt_sp) + return nullptr; + + std::lock_guard guard( + bkpt_sp->GetTarget().GetAPIMutex()); + return ConstString(bkpt_sp->GetConditionText()).GetCString(); } void SBBreakpoint::SetAutoContinue(bool auto_continue) { @@ -411,18 +411,17 @@ const char *SBBreakpoint::GetThreadName() const { LLDB_INSTRUMENT_VA(this); - const char *name = nullptr; BreakpointSP bkpt_sp = GetSP(); - if (bkpt_sp) { - std::lock_guard 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; + + std::lock_guard guard( + bkpt_sp->GetTarget().GetAPIMutex()); + if (const ThreadSpec *thread_spec = + bkpt_sp->GetOptions().GetThreadSpecNoCreate()) + return ConstString(thread_spec->GetName()).GetCString(); - return name; + return nullptr; } void SBBreakpoint::SetQueueName(const char *queue_name) { @@ -439,18 +438,17 @@ const char *SBBreakpoint::GetQueueName() const { LLDB_INSTRUMENT_VA(this); - const char *name = nullptr; BreakpointSP bkpt_sp = GetSP(); - if (bkpt_sp) { - std::lock_guard 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 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 { diff --git a/lldb/source/API/SBBreakpointLocation.cpp b/lldb/source/API/SBBreakpointLocation.cpp --- a/lldb/source/API/SBBreakpointLocation.cpp +++ b/lldb/source/API/SBBreakpointLocation.cpp @@ -169,12 +169,12 @@ LLDB_INSTRUMENT_VA(this); BreakpointLocationSP loc_sp = GetSP(); - if (loc_sp) { - std::lock_guard guard( - loc_sp->GetTarget().GetAPIMutex()); - return loc_sp->GetConditionText(); - } - return nullptr; + if (!loc_sp) + return nullptr; + + std::lock_guard guard( + loc_sp->GetTarget().GetAPIMutex()); + return ConstString(loc_sp->GetConditionText()).GetCString(); } void SBBreakpointLocation::SetAutoContinue(bool auto_continue) { @@ -366,12 +366,12 @@ LLDB_INSTRUMENT_VA(this); BreakpointLocationSP loc_sp = GetSP(); - if (loc_sp) { - std::lock_guard guard( - loc_sp->GetTarget().GetAPIMutex()); - return loc_sp->GetThreadName(); - } - return nullptr; + if (!loc_sp) + return nullptr; + + std::lock_guard guard( + loc_sp->GetTarget().GetAPIMutex()); + return ConstString(loc_sp->GetThreadName()).GetCString(); } void SBBreakpointLocation::SetQueueName(const char *queue_name) { @@ -389,12 +389,12 @@ LLDB_INSTRUMENT_VA(this); BreakpointLocationSP loc_sp = GetSP(); - if (loc_sp) { - std::lock_guard guard( - loc_sp->GetTarget().GetAPIMutex()); - return loc_sp->GetQueueName(); - } - return nullptr; + if (!loc_sp) + return nullptr; + + std::lock_guard guard( + loc_sp->GetTarget().GetAPIMutex()); + return ConstString(loc_sp->GetQueueName()).GetCString(); } bool SBBreakpointLocation::IsResolved() { diff --git a/lldb/source/API/SBBreakpointName.cpp b/lldb/source/API/SBBreakpointName.cpp --- a/lldb/source/API/SBBreakpointName.cpp +++ b/lldb/source/API/SBBreakpointName.cpp @@ -199,7 +199,7 @@ if (!m_impl_up) return ""; - return m_impl_up->GetName(); + return ConstString(m_impl_up->GetName()).GetCString(); } void SBBreakpointName::SetEnabled(bool enable) { @@ -315,9 +315,9 @@ return nullptr; std::lock_guard 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 @@ return nullptr; std::lock_guard 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 @@ return nullptr; std::lock_guard 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 @@ if (!bp_name) return ""; - return bp_name->GetHelp(); + return ConstString(bp_name->GetHelp()).GetCString(); } void SBBreakpointName::SetHelpString(const char *help_string) { diff --git a/lldb/source/API/SBCommandInterpreter.cpp b/lldb/source/API/SBCommandInterpreter.cpp --- a/lldb/source/API/SBCommandInterpreter.cpp +++ b/lldb/source/API/SBCommandInterpreter.cpp @@ -516,14 +516,16 @@ 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( diff --git a/lldb/source/API/SBData.cpp b/lldb/source/API/SBData.cpp --- a/lldb/source/API/SBData.cpp +++ b/lldb/source/API/SBData.cpp @@ -297,16 +297,19 @@ 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, diff --git a/lldb/source/API/SBEvent.cpp b/lldb/source/API/SBEvent.cpp --- a/lldb/source/API/SBEvent.cpp +++ b/lldb/source/API/SBEvent.cpp @@ -63,7 +63,7 @@ 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 @@ const char *SBEvent::GetCStringFromEvent(const SBEvent &event) { LLDB_INSTRUMENT_VA(event); - return static_cast( - EventDataBytes::GetBytesFromEvent(event.get())); + return ConstString(static_cast( + EventDataBytes::GetBytesFromEvent(event.get()))) + .GetCString(); } bool SBEvent::GetDescription(SBStream &description) { diff --git a/lldb/source/API/SBExpressionOptions.cpp b/lldb/source/API/SBExpressionOptions.cpp --- a/lldb/source/API/SBExpressionOptions.cpp +++ b/lldb/source/API/SBExpressionOptions.cpp @@ -190,7 +190,7 @@ 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) { diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp --- a/lldb/source/API/SBFrame.cpp +++ b/lldb/source/API/SBFrame.cpp @@ -708,24 +708,20 @@ const char *SBFrame::Disassemble() const { LLDB_INSTRUMENT_VA(this); - const char *disassembly = nullptr; std::unique_lock 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, diff --git a/lldb/source/API/SBFunction.cpp b/lldb/source/API/SBFunction.cpp --- a/lldb/source/API/SBFunction.cpp +++ b/lldb/source/API/SBFunction.cpp @@ -54,30 +54,27 @@ 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 @@ 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() { diff --git a/lldb/source/API/SBInstruction.cpp b/lldb/source/API/SBInstruction.cpp --- a/lldb/source/API/SBInstruction.cpp +++ b/lldb/source/API/SBInstruction.cpp @@ -111,57 +111,57 @@ LLDB_INSTRUMENT_VA(this, target); lldb::InstructionSP inst_sp(GetOpaque()); - if (inst_sp) { - ExecutionContext exe_ctx; - TargetSP target_sp(target.GetSP()); - std::unique_lock lock; - if (target_sp) { - lock = std::unique_lock(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 lock; + if (target_sp) { + lock = std::unique_lock(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 lock; - if (target_sp) { - lock = std::unique_lock(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 lock; + if (target_sp) { + lock = std::unique_lock(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 lock; - if (target_sp) { - lock = std::unique_lock(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 lock; + if (target_sp) { + lock = std::unique_lock(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) { diff --git a/lldb/source/API/SBLaunchInfo.cpp b/lldb/source/API/SBLaunchInfo.cpp --- a/lldb/source/API/SBLaunchInfo.cpp +++ b/lldb/source/API/SBLaunchInfo.cpp @@ -148,7 +148,8 @@ 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 @@ 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 @@ 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 @@ 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) { diff --git a/lldb/source/API/SBModule.cpp b/lldb/source/API/SBModule.cpp --- a/lldb/source/API/SBModule.cpp +++ b/lldb/source/API/SBModule.cpp @@ -173,20 +173,20 @@ 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 (uuid_cstr && uuid_cstr[0]) { + if (!module_sp) + return nullptr; + + // 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 @@ 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() { diff --git a/lldb/source/API/SBPlatform.cpp b/lldb/source/API/SBPlatform.cpp --- a/lldb/source/API/SBPlatform.cpp +++ b/lldb/source/API/SBPlatform.cpp @@ -100,7 +100,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ PlatformSP platform_sp(GetSP()); if (platform_sp) - return platform_sp->GetHostname(); + return ConstString(platform_sp->GetHostname()).GetCString(); return nullptr; } diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp --- a/lldb/source/API/SBProcess.cpp +++ b/lldb/source/API/SBProcess.cpp @@ -507,14 +507,13 @@ const char *SBProcess::GetExitDescription() { LLDB_INSTRUMENT_VA(this); - const char *exit_desc = nullptr; ProcessSP process_sp(GetSP()); - if (process_sp) { - std::lock_guard guard( - process_sp->GetTarget().GetAPIMutex()); - exit_desc = process_sp->GetExitDescription(); - } - return exit_desc; + if (!process_sp) + return nullptr; + + std::lock_guard guard( + process_sp->GetTarget().GetAPIMutex()); + return ConstString(process_sp->GetExitDescription()).GetCString(); } lldb::pid_t SBProcess::GetProcessID() { @@ -747,7 +746,9 @@ 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) { diff --git a/lldb/source/API/SBProcessInfo.cpp b/lldb/source/API/SBProcessInfo.cpp --- a/lldb/source/API/SBProcessInfo.cpp +++ b/lldb/source/API/SBProcessInfo.cpp @@ -57,11 +57,10 @@ 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 @@ 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(); } diff --git a/lldb/source/API/SBQueue.cpp b/lldb/source/API/SBQueue.cpp --- a/lldb/source/API/SBQueue.cpp +++ b/lldb/source/API/SBQueue.cpp @@ -77,12 +77,10 @@ } 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() { diff --git a/lldb/source/API/SBStream.cpp b/lldb/source/API/SBStream.cpp --- a/lldb/source/API/SBStream.cpp +++ b/lldb/source/API/SBStream.cpp @@ -47,7 +47,8 @@ if (m_is_file || m_opaque_up == nullptr) return nullptr; - return static_cast(m_opaque_up.get())->GetData(); + return ConstString(static_cast(m_opaque_up.get())->GetData()) + .GetCString(); } // If this stream is not redirected to a file, it will maintain a local cache diff --git a/lldb/source/API/SBStringList.cpp b/lldb/source/API/SBStringList.cpp --- a/lldb/source/API/SBStringList.cpp +++ b/lldb/source/API/SBStringList.cpp @@ -106,7 +106,7 @@ 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 @@ LLDB_INSTRUMENT_VA(this, idx); if (IsValid()) { - return m_opaque_up->GetStringAtIndex(idx); + return ConstString(m_opaque_up->GetStringAtIndex(idx)).GetCString(); } return nullptr; } diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -1578,27 +1578,27 @@ 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() { diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp --- a/lldb/source/API/SBThread.cpp +++ b/lldb/source/API/SBThread.cpp @@ -394,35 +394,33 @@ const char *SBThread::GetName() const { LLDB_INSTRUMENT_VA(this); - const char *name = nullptr; std::unique_lock 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; + + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + return ConstString(exe_ctx.GetThreadPtr()->GetName()).GetCString(); - return name; + return nullptr; } const char *SBThread::GetQueueName() const { LLDB_INSTRUMENT_VA(this); - const char *name = nullptr; std::unique_lock 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; + + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + return ConstString(exe_ctx.GetThreadPtr()->GetQueueName()).GetCString(); - return name; + return nullptr; } lldb::queue_id_t SBThread::GetQueueID() const { diff --git a/lldb/source/API/SBTrace.cpp b/lldb/source/API/SBTrace.cpp --- a/lldb/source/API/SBTrace.cpp +++ b/lldb/source/API/SBTrace.cpp @@ -84,7 +84,10 @@ 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) { diff --git a/lldb/source/API/SBTraceCursor.cpp b/lldb/source/API/SBTraceCursor.cpp --- a/lldb/source/API/SBTraceCursor.cpp +++ b/lldb/source/API/SBTraceCursor.cpp @@ -85,7 +85,7 @@ 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 @@ 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 { diff --git a/lldb/source/API/SBType.cpp b/lldb/source/API/SBType.cpp --- a/lldb/source/API/SBType.cpp +++ b/lldb/source/API/SBType.cpp @@ -809,14 +809,15 @@ 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() { diff --git a/lldb/source/API/SBTypeCategory.cpp b/lldb/source/API/SBTypeCategory.cpp --- a/lldb/source/API/SBTypeCategory.cpp +++ b/lldb/source/API/SBTypeCategory.cpp @@ -73,7 +73,7 @@ if (!IsValid()) return nullptr; - return m_opaque_sp->GetName(); + return ConstString(m_opaque_sp->GetName()).GetCString(); } lldb::LanguageType SBTypeCategory::GetLanguageAtIndex(uint32_t idx) { diff --git a/lldb/source/API/SBTypeFilter.cpp b/lldb/source/API/SBTypeFilter.cpp --- a/lldb/source/API/SBTypeFilter.cpp +++ b/lldb/source/API/SBTypeFilter.cpp @@ -85,13 +85,13 @@ 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) { diff --git a/lldb/source/API/SBTypeNameSpecifier.cpp b/lldb/source/API/SBTypeNameSpecifier.cpp --- a/lldb/source/API/SBTypeNameSpecifier.cpp +++ b/lldb/source/API/SBTypeNameSpecifier.cpp @@ -65,7 +65,7 @@ if (!IsValid()) return nullptr; - return m_opaque_sp->GetName(); + return ConstString(m_opaque_sp->GetName()).GetCString(); } SBType SBTypeNameSpecifier::GetType() { diff --git a/lldb/source/API/SBTypeSummary.cpp b/lldb/source/API/SBTypeSummary.cpp --- a/lldb/source/API/SBTypeSummary.cpp +++ b/lldb/source/API/SBTypeSummary.cpp @@ -222,11 +222,11 @@ 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(m_opaque_sp.get())) - return string_summary_ptr->GetSummaryString(); + return ConstString(string_summary_ptr->GetSummaryString()).GetCString(); return nullptr; } diff --git a/lldb/source/API/SBTypeSynthetic.cpp b/lldb/source/API/SBTypeSynthetic.cpp --- a/lldb/source/API/SBTypeSynthetic.cpp +++ b/lldb/source/API/SBTypeSynthetic.cpp @@ -78,9 +78,9 @@ 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) { diff --git a/lldb/source/API/SBUnixSignals.cpp b/lldb/source/API/SBUnixSignals.cpp --- a/lldb/source/API/SBUnixSignals.cpp +++ b/lldb/source/API/SBUnixSignals.cpp @@ -66,7 +66,7 @@ LLDB_INSTRUMENT_VA(this, signo); if (auto signals_sp = GetSP()) - return signals_sp->GetSignalAsCString(signo); + return ConstString(signals_sp->GetSignalAsCString(signo)).GetCString(); return nullptr; } diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp --- a/lldb/source/API/SBValue.cpp +++ b/lldb/source/API/SBValue.cpp @@ -291,39 +291,34 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 diff --git a/lldb/source/API/SBWatchpoint.cpp b/lldb/source/API/SBWatchpoint.cpp --- a/lldb/source/API/SBWatchpoint.cpp +++ b/lldb/source/API/SBWatchpoint.cpp @@ -210,12 +210,12 @@ LLDB_INSTRUMENT_VA(this); lldb::WatchpointSP watchpoint_sp(GetSP()); - if (watchpoint_sp) { - std::lock_guard guard( - watchpoint_sp->GetTarget().GetAPIMutex()); - return watchpoint_sp->GetConditionText(); - } - return nullptr; + if (!watchpoint_sp) + return nullptr; + + std::lock_guard guard( + watchpoint_sp->GetTarget().GetAPIMutex()); + return ConstString(watchpoint_sp->GetConditionText()).GetCString(); } void SBWatchpoint::SetCondition(const char *condition) { @@ -323,16 +323,16 @@ LLDB_INSTRUMENT_VA(this); lldb::WatchpointSP watchpoint_sp(GetSP()); - if (watchpoint_sp) { - std::lock_guard 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 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() {