aboutsummaryrefslogtreecommitdiff
path: root/lldb/source
diff options
context:
space:
mode:
authorTatyana Krasnukha <21970096+tkrasnukha@users.noreply.github.com>2020-12-11 11:09:39 +0300
committerTatyana Krasnukha <tatyana@synopsys.com>2020-12-12 16:40:58 +0300
commit2634ec6ce9007f2406545ca28b4c72961f1e8f67 (patch)
tree1e274bba3a2afe5416300e0b2b5212d1075bb46f /lldb/source
parente52bc1d2bba794bfb004d35a395a2e3a8e69f9cb (diff)
downloadllvm-2634ec6ce9007f2406545ca28b4c72961f1e8f67.zip
llvm-2634ec6ce9007f2406545ca28b4c72961f1e8f67.tar.gz
llvm-2634ec6ce9007f2406545ca28b4c72961f1e8f67.tar.bz2
[lldb] "target create" shouldn't save target if the command failed
TargetList::CreateTarget automatically adds created target to the list, however, CommandObjectTargetCreate does some additional preparation after creating a target and which can fail. The command should remove created target if it failed. Since the function has many ways to return, scope guard does this work safely. Changes to the TargetList make target adding and selection more transparent. Other changes remove unnecessary SetSelectedTarget after CreateTarget. Differential Revision: https://reviews.llvm.org/D93052
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/API/SBDebugger.cpp10
-rw-r--r--lldb/source/Commands/CommandObjectProcess.cpp1
-rw-r--r--lldb/source/Commands/CommandObjectTarget.cpp210
-rw-r--r--lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp4
-rw-r--r--lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp2
-rw-r--r--lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp4
-rw-r--r--lldb/source/Target/Platform.cpp2
-rw-r--r--lldb/source/Target/TargetList.cpp55
-rw-r--r--lldb/source/Target/TraceSessionFileParser.cpp2
9 files changed, 142 insertions, 148 deletions
diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp
index a5bf457..dc1cc91 100644
--- a/lldb/source/API/SBDebugger.cpp
+++ b/lldb/source/API/SBDebugger.cpp
@@ -811,10 +811,8 @@ SBTarget SBDebugger::CreateTargetWithFileAndArch(const char *filename,
add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, nullptr,
target_sp);
- if (error.Success()) {
- m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp.get());
+ if (error.Success())
sb_target.SetSP(target_sp);
- }
}
LLDB_LOGF(log,
@@ -840,10 +838,8 @@ SBTarget SBDebugger::CreateTarget(const char *filename) {
add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, nullptr,
target_sp);
- if (error.Success()) {
- m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp.get());
+ if (error.Success())
sb_target.SetSP(target_sp);
- }
}
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
LLDB_LOGF(log,
@@ -998,7 +994,7 @@ void SBDebugger::SetSelectedTarget(SBTarget &sb_target) {
TargetSP target_sp(sb_target.GetSP());
if (m_opaque_sp) {
- m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp.get());
+ m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp);
}
if (log) {
SBStream sstr;
diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp
index 5ef0b87..1eef280 100644
--- a/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/lldb/source/Commands/CommandObjectProcess.cpp
@@ -364,7 +364,6 @@ protected:
result.AppendError(error.AsCString("Error creating target"));
return false;
}
- GetDebugger().GetTargetList().SetSelectedTarget(target);
}
// Record the old executable module, we want to issue a warning if the
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index eba129c..c033493 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -50,6 +50,7 @@
#include "lldb/Utility/State.h"
#include "lldb/Utility/Timer.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormatAdapters.h"
@@ -318,123 +319,124 @@ protected:
m_add_dependents.m_load_dependent_files, &m_platform_options,
target_sp));
- if (target_sp) {
- // Only get the platform after we create the target because we might
- // have switched platforms depending on what the arguments were to
- // CreateTarget() we can't rely on the selected platform.
-
- PlatformSP platform_sp = target_sp->GetPlatform();
-
- if (remote_file) {
- if (platform_sp) {
- // I have a remote file.. two possible cases
- if (file_spec && FileSystem::Instance().Exists(file_spec)) {
- // if the remote file does not exist, push it there
- if (!platform_sp->GetFileExists(remote_file)) {
- Status err = platform_sp->PutFile(file_spec, remote_file);
- if (err.Fail()) {
- result.AppendError(err.AsCString());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
- } else {
- // there is no local file and we need one
- // in order to make the remote ---> local transfer we need a
- // platform
- // TODO: if the user has passed in a --platform argument, use it
- // to fetch the right platform
- if (!platform_sp) {
- result.AppendError(
- "unable to perform remote debugging without a platform");
+ if (!target_sp) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ auto on_error = llvm::make_scope_exit(
+ [&target_list = debugger.GetTargetList(), &target_sp]() {
+ target_list.DeleteTarget(target_sp);
+ });
+
+ // Only get the platform after we create the target because we might
+ // have switched platforms depending on what the arguments were to
+ // CreateTarget() we can't rely on the selected platform.
+
+ PlatformSP platform_sp = target_sp->GetPlatform();
+
+ if (remote_file) {
+ if (platform_sp) {
+ // I have a remote file.. two possible cases
+ if (file_spec && FileSystem::Instance().Exists(file_spec)) {
+ // if the remote file does not exist, push it there
+ if (!platform_sp->GetFileExists(remote_file)) {
+ Status err = platform_sp->PutFile(file_spec, remote_file);
+ if (err.Fail()) {
+ result.AppendError(err.AsCString());
result.SetStatus(eReturnStatusFailed);
return false;
}
- if (file_path) {
- // copy the remote file to the local file
- Status err = platform_sp->GetFile(remote_file, file_spec);
- if (err.Fail()) {
- result.AppendError(err.AsCString());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- } else {
- // make up a local file
- result.AppendError("remote --> local transfer without local "
- "path is not implemented yet");
+ }
+ } else {
+ // there is no local file and we need one
+ // in order to make the remote ---> local transfer we need a
+ // platform
+ // TODO: if the user has passed in a --platform argument, use it
+ // to fetch the right platform
+ if (file_path) {
+ // copy the remote file to the local file
+ Status err = platform_sp->GetFile(remote_file, file_spec);
+ if (err.Fail()) {
+ result.AppendError(err.AsCString());
result.SetStatus(eReturnStatusFailed);
return false;
}
+ } else {
+ // make up a local file
+ result.AppendError("remote --> local transfer without local "
+ "path is not implemented yet");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- } else {
- result.AppendError("no platform found for target");
- result.SetStatus(eReturnStatusFailed);
- return false;
}
+ } else {
+ result.AppendError("no platform found for target");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+ }
- if (symfile || remote_file) {
- ModuleSP module_sp(target_sp->GetExecutableModule());
- if (module_sp) {
- if (symfile)
- module_sp->SetSymbolFileFileSpec(symfile);
- if (remote_file) {
- std::string remote_path = remote_file.GetPath();
- target_sp->SetArg0(remote_path.c_str());
- module_sp->SetPlatformFileSpec(remote_file);
- }
+ if (symfile || remote_file) {
+ ModuleSP module_sp(target_sp->GetExecutableModule());
+ if (module_sp) {
+ if (symfile)
+ module_sp->SetSymbolFileFileSpec(symfile);
+ if (remote_file) {
+ std::string remote_path = remote_file.GetPath();
+ target_sp->SetArg0(remote_path.c_str());
+ module_sp->SetPlatformFileSpec(remote_file);
}
}
+ }
- debugger.GetTargetList().SetSelectedTarget(target_sp.get());
- if (must_set_platform_path) {
- ModuleSpec main_module_spec(file_spec);
- ModuleSP module_sp =
- target_sp->GetOrCreateModule(main_module_spec, true /* notify */);
- if (module_sp)
- module_sp->SetPlatformFileSpec(remote_file);
- }
+ if (must_set_platform_path) {
+ ModuleSpec main_module_spec(file_spec);
+ ModuleSP module_sp =
+ target_sp->GetOrCreateModule(main_module_spec, true /* notify */);
+ if (module_sp)
+ module_sp->SetPlatformFileSpec(remote_file);
+ }
- if (core_file) {
- FileSpec core_file_dir;
- core_file_dir.GetDirectory() = core_file.GetDirectory();
- target_sp->AppendExecutableSearchPaths(core_file_dir);
+ if (core_file) {
+ FileSpec core_file_dir;
+ core_file_dir.GetDirectory() = core_file.GetDirectory();
+ target_sp->AppendExecutableSearchPaths(core_file_dir);
- ProcessSP process_sp(target_sp->CreateProcess(
- GetDebugger().GetListener(), llvm::StringRef(), &core_file,
- false));
+ ProcessSP process_sp(target_sp->CreateProcess(
+ GetDebugger().GetListener(), llvm::StringRef(), &core_file, false));
- if (process_sp) {
- // Seems weird that we Launch a core file, but that is what we
- // do!
- error = process_sp->LoadCore();
+ if (process_sp) {
+ // Seems weird that we Launch a core file, but that is what we
+ // do!
+ error = process_sp->LoadCore();
- if (error.Fail()) {
- result.AppendError(
- error.AsCString("can't find plug-in for core file"));
- result.SetStatus(eReturnStatusFailed);
- return false;
- } else {
- result.AppendMessageWithFormatv("Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),
- target_sp->GetArchitecture().GetArchitectureName());
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- }
- } else {
- result.AppendErrorWithFormatv(
- "Unable to find process plug-in for core file '{0}'\n",
- core_file.GetPath());
+ if (error.Fail()) {
+ result.AppendError(
+ error.AsCString("can't find plug-in for core file"));
result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ result.AppendMessageWithFormatv(
+ "Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),
+ target_sp->GetArchitecture().GetArchitectureName());
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ on_error.release();
}
} else {
- result.AppendMessageWithFormat(
- "Current executable set to '%s' (%s).\n",
- file_spec.GetPath().c_str(),
- target_sp->GetArchitecture().GetArchitectureName());
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ result.AppendErrorWithFormatv(
+ "Unable to find process plug-in for core file '{0}'\n",
+ core_file.GetPath());
+ result.SetStatus(eReturnStatusFailed);
}
} else {
- result.AppendError(error.AsCString());
- result.SetStatus(eReturnStatusFailed);
+ result.AppendMessageWithFormat(
+ "Current executable set to '%s' (%s).\n",
+ file_spec.GetPath().c_str(),
+ target_sp->GetArchitecture().GetArchitectureName());
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ on_error.release();
}
} else {
result.AppendErrorWithFormat("'%s' takes exactly one executable path "
@@ -442,6 +444,7 @@ protected:
m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
}
+
return result.Succeeded();
}
@@ -507,18 +510,11 @@ protected:
TargetList &target_list = GetDebugger().GetTargetList();
const uint32_t num_targets = target_list.GetNumTargets();
if (target_idx < num_targets) {
- TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
- if (target_sp) {
- Stream &strm = result.GetOutputStream();
- target_list.SetSelectedTarget(target_sp.get());
- bool show_stopped_process_status = false;
- DumpTargetList(target_list, show_stopped_process_status, strm);
- result.SetStatus(eReturnStatusSuccessFinishResult);
- } else {
- result.AppendErrorWithFormat("target #%u is NULL in target list\n",
- target_idx);
- result.SetStatus(eReturnStatusFailed);
- }
+ target_list.SetSelectedTarget(target_idx);
+ Stream &strm = result.GetOutputStream();
+ bool show_stopped_process_status = false;
+ DumpTargetList(target_list, show_stopped_process_status, strm);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
} else {
if (num_targets > 0) {
result.AppendErrorWithFormat(
diff --git a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index cad5a80..3628b0a 100644
--- a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -377,7 +377,6 @@ lldb::ProcessSP PlatformPOSIX::Attach(ProcessAttachInfo &attach_info,
}
if (target && error.Success()) {
- debugger.GetTargetList().SetSelectedTarget(target);
if (log) {
ModuleSP exe_module_sp = target->GetExecutableModule();
LLDB_LOGF(log, "PlatformPOSIX::%s set selected target to %p %s",
@@ -462,9 +461,6 @@ PlatformPOSIX::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
}
}
- // Mark target as currently selected target.
- debugger.GetTargetList().SetSelectedTarget(target);
-
// Now create the gdb-remote process.
LLDB_LOG(log, "having target create process with gdb-remote plugin");
process_sp =
diff --git a/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp b/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
index 0ef4dcb..3527fb1 100644
--- a/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
+++ b/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
@@ -272,8 +272,6 @@ lldb::ProcessSP PlatformWindows::Attach(ProcessAttachInfo &attach_info,
if (!target || error.Fail())
return process_sp;
- debugger.GetTargetList().SetSelectedTarget(target);
-
const char *plugin_name = attach_info.GetProcessPluginName();
process_sp = target->CreateProcess(
attach_info.GetListenerForProcess(debugger), plugin_name, nullptr, false);
diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index b3774b9..a64ee26 100644
--- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -495,8 +495,6 @@ lldb::ProcessSP PlatformRemoteGDBServer::DebugProcess(
error.Clear();
if (target && error.Success()) {
- debugger.GetTargetList().SetSelectedTarget(target);
-
// The darwin always currently uses the GDB remote debugger plug-in
// so even when debugging locally we are debugging remotely!
process_sp = target->CreateProcess(launch_info.GetListener(),
@@ -581,8 +579,6 @@ lldb::ProcessSP PlatformRemoteGDBServer::Attach(
error.Clear();
if (target && error.Success()) {
- debugger.GetTargetList().SetSelectedTarget(target);
-
// The darwin always currently uses the GDB remote debugger plug-in
// so even when debugging locally we are debugging remotely!
process_sp =
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index b5b673a..a77ecdd 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -1831,8 +1831,6 @@ lldb::ProcessSP Platform::DoConnectProcess(llvm::StringRef connect_url,
if (!target || error.Fail())
return nullptr;
- debugger.GetTargetList().SetSelectedTarget(target);
-
lldb::ProcessSP process_sp =
target->CreateProcess(debugger.GetListener(), plugin_name, nullptr, true);
diff --git a/lldb/source/Target/TargetList.cpp b/lldb/source/Target/TargetList.cpp
index 2be32c5..bbef3b6 100644
--- a/lldb/source/Target/TargetList.cpp
+++ b/lldb/source/Target/TargetList.cpp
@@ -48,9 +48,13 @@ Status TargetList::CreateTarget(Debugger &debugger,
LoadDependentFiles load_dependent_files,
const OptionGroupPlatform *platform_options,
TargetSP &target_sp) {
- return CreateTargetInternal(debugger, user_exe_path, triple_str,
- load_dependent_files, platform_options,
- target_sp);
+ auto result = TargetList::CreateTargetInternal(
+ debugger, user_exe_path, triple_str, load_dependent_files,
+ platform_options, target_sp);
+
+ if (target_sp && result.Success())
+ AddTargetInternal(target_sp, /*do_select*/ true);
+ return result;
}
Status TargetList::CreateTarget(Debugger &debugger,
@@ -58,8 +62,13 @@ Status TargetList::CreateTarget(Debugger &debugger,
const ArchSpec &specified_arch,
LoadDependentFiles load_dependent_files,
PlatformSP &platform_sp, TargetSP &target_sp) {
- return CreateTargetInternal(debugger, user_exe_path, specified_arch,
- load_dependent_files, platform_sp, target_sp);
+ auto result = TargetList::CreateTargetInternal(
+ debugger, user_exe_path, specified_arch, load_dependent_files,
+ platform_sp, target_sp);
+
+ if (target_sp && result.Success())
+ AddTargetInternal(target_sp, /*do_select*/ true);
+ return result;
}
Status TargetList::CreateTargetInternal(
@@ -388,9 +397,6 @@ Status TargetList::CreateTargetInternal(Debugger &debugger,
target_sp->AppendExecutableSearchPaths(file_dir);
}
- std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
- m_selected_target_idx = m_target_list.size();
- m_target_list.push_back(target_sp);
// Now prime this from the dummy target:
target_sp->PrimeFromDummyTarget(debugger.GetDummyTarget());
@@ -552,18 +558,29 @@ uint32_t TargetList::GetIndexOfTarget(lldb::TargetSP target_sp) const {
return UINT32_MAX;
}
-uint32_t TargetList::SetSelectedTarget(Target *target) {
+void TargetList::AddTargetInternal(TargetSP target_sp, bool do_select) {
+ lldbassert(std::find(m_target_list.begin(), m_target_list.end(), target_sp) ==
+ m_target_list.end() &&
+ "target already exists it the list");
+ m_target_list.push_back(std::move(target_sp));
+ if (do_select)
+ SetSelectedTargetInternal(m_target_list.size() - 1);
+}
+
+void TargetList::SetSelectedTargetInternal(uint32_t index) {
+ lldbassert(!m_target_list.empty());
+ m_selected_target_idx = index < m_target_list.size() ? index : 0;
+}
+
+void TargetList::SetSelectedTarget(uint32_t index) {
std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
- collection::const_iterator pos, begin = m_target_list.begin(),
- end = m_target_list.end();
- for (pos = begin; pos != end; ++pos) {
- if (pos->get() == target) {
- m_selected_target_idx = std::distance(begin, pos);
- return m_selected_target_idx;
- }
- }
- m_selected_target_idx = 0;
- return m_selected_target_idx;
+ SetSelectedTargetInternal(index);
+}
+
+void TargetList::SetSelectedTarget(const TargetSP &target_sp) {
+ std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
+ auto it = std::find(m_target_list.begin(), m_target_list.end(), target_sp);
+ SetSelectedTargetInternal(std::distance(m_target_list.begin(), it));
}
lldb::TargetSP TargetList::GetSelectedTarget() {
diff --git a/lldb/source/Target/TraceSessionFileParser.cpp b/lldb/source/Target/TraceSessionFileParser.cpp
index 1cef818..713fadc 100644
--- a/lldb/source/Target/TraceSessionFileParser.cpp
+++ b/lldb/source/Target/TraceSessionFileParser.cpp
@@ -123,8 +123,6 @@ TraceSessionFileParser::ParseProcess(const JSONProcess &process) {
ParsedProcess parsed_process;
parsed_process.target_sp = target_sp;
- m_debugger.GetTargetList().SetSelectedTarget(target_sp.get());
-
ProcessSP process_sp = target_sp->CreateProcess(
/*listener*/ nullptr, "trace",
/*crash_file*/ nullptr,