summaryrefslogtreecommitdiffstats
path: root/source/Target
diff options
context:
space:
mode:
Diffstat (limited to 'source/Target')
-rw-r--r--source/Target/Platform.cpp368
-rw-r--r--source/Target/Process.cpp106
-rw-r--r--source/Target/RegisterContext.cpp12
-rw-r--r--source/Target/StackFrameList.cpp19
-rw-r--r--source/Target/SystemRuntime.cpp10
-rw-r--r--source/Target/Target.cpp106
-rw-r--r--source/Target/Thread.cpp105
-rw-r--r--source/Target/ThreadPlanCallFunction.cpp167
-rw-r--r--source/Target/ThreadPlanCallUserExpression.cpp10
-rw-r--r--source/Target/ThreadPlanStepInRange.cpp4
10 files changed, 646 insertions, 261 deletions
diff --git a/source/Target/Platform.cpp b/source/Target/Platform.cpp
index 75d94bd..66f9c0e 100644
--- a/source/Target/Platform.cpp
+++ b/source/Target/Platform.cpp
@@ -237,6 +237,7 @@ Platform::Platform (bool is_host) :
m_system_arch_set_while_connected (false),
m_sdk_sysroot (),
m_sdk_build (),
+ m_working_dir (),
m_remote_url (),
m_name (),
m_major_os_version (UINT32_MAX),
@@ -319,6 +320,10 @@ Platform::GetStatus (Stream &strm)
strm.Printf(" Connected: %s\n", is_connected ? "yes" : "no");
}
+ if (GetWorkingDirectory())
+ {
+ strm.Printf("WorkingDir: %s\n", GetWorkingDirectory().GetCString());
+ }
if (!IsConnected())
return;
@@ -405,12 +410,332 @@ Platform::GetOSKernelDescription (std::string &s)
}
ConstString
+Platform::GetWorkingDirectory ()
+{
+ if (IsHost())
+ {
+ char cwd[PATH_MAX];
+ if (getcwd(cwd, sizeof(cwd)))
+ return ConstString(cwd);
+ else
+ return ConstString();
+ }
+ else
+ {
+ if (!m_working_dir)
+ m_working_dir = GetRemoteWorkingDirectory();
+ return m_working_dir;
+ }
+}
+
+
+struct RecurseCopyBaton
+{
+ const FileSpec& dst;
+ Platform *platform_ptr;
+ Error error;
+};
+
+
+static FileSpec::EnumerateDirectoryResult
+RecurseCopy_Callback (void *baton,
+ FileSpec::FileType file_type,
+ const FileSpec &src)
+{
+ RecurseCopyBaton* rc_baton = (RecurseCopyBaton*)baton;
+ switch (file_type)
+ {
+ case FileSpec::eFileTypePipe:
+ case FileSpec::eFileTypeSocket:
+ // we have no way to copy pipes and sockets - ignore them and continue
+ return FileSpec::eEnumerateDirectoryResultNext;
+ break;
+
+ case FileSpec::eFileTypeDirectory:
+ {
+ // make the new directory and get in there
+ FileSpec dst_dir = rc_baton->dst;
+ if (!dst_dir.GetFilename())
+ dst_dir.GetFilename() = src.GetLastPathComponent();
+ std::string dst_dir_path (dst_dir.GetPath());
+ Error error = rc_baton->platform_ptr->MakeDirectory(dst_dir_path.c_str(), lldb::eFilePermissionsDirectoryDefault);
+ if (error.Fail())
+ {
+ rc_baton->error.SetErrorStringWithFormat("unable to setup directory %s on remote end", dst_dir_path.c_str());
+ return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
+ }
+
+ // now recurse
+ std::string src_dir_path (src.GetPath());
+
+ // Make a filespec that only fills in the directory of a FileSpec so
+ // when we enumerate we can quickly fill in the filename for dst copies
+ FileSpec recurse_dst;
+ recurse_dst.GetDirectory().SetCString(dst_dir.GetPath().c_str());
+ RecurseCopyBaton rc_baton2 = { recurse_dst, rc_baton->platform_ptr, Error() };
+ FileSpec::EnumerateDirectory(src_dir_path.c_str(), true, true, true, RecurseCopy_Callback, &rc_baton2);
+ if (rc_baton2.error.Fail())
+ {
+ rc_baton->error.SetErrorString(rc_baton2.error.AsCString());
+ return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
+ }
+ return FileSpec::eEnumerateDirectoryResultNext;
+ }
+ break;
+
+ case FileSpec::eFileTypeSymbolicLink:
+ {
+ // copy the file and keep going
+ FileSpec dst_file = rc_baton->dst;
+ if (!dst_file.GetFilename())
+ dst_file.GetFilename() = src.GetFilename();
+
+ char buf[PATH_MAX];
+
+ rc_baton->error = Host::Readlink (src.GetPath().c_str(), buf, sizeof(buf));
+
+ if (rc_baton->error.Fail())
+ return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
+
+ rc_baton->error = rc_baton->platform_ptr->CreateSymlink(dst_file.GetPath().c_str(), buf);
+
+ if (rc_baton->error.Fail())
+ return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
+
+ return FileSpec::eEnumerateDirectoryResultNext;
+ }
+ break;
+ case FileSpec::eFileTypeRegular:
+ {
+ // copy the file and keep going
+ FileSpec dst_file = rc_baton->dst;
+ if (!dst_file.GetFilename())
+ dst_file.GetFilename() = src.GetFilename();
+ Error err = rc_baton->platform_ptr->PutFile(src, dst_file);
+ if (err.Fail())
+ {
+ rc_baton->error.SetErrorString(err.AsCString());
+ return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
+ }
+ return FileSpec::eEnumerateDirectoryResultNext;
+ }
+ break;
+
+ case FileSpec::eFileTypeInvalid:
+ case FileSpec::eFileTypeOther:
+ case FileSpec::eFileTypeUnknown:
+ rc_baton->error.SetErrorStringWithFormat("invalid file detected during copy: %s", src.GetPath().c_str());
+ return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
+ break;
+ }
+}
+
+Error
+Platform::Install (const FileSpec& src, const FileSpec& dst)
+{
+ Error error;
+
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+ if (log)
+ log->Printf ("Platform::Install (src='%s', dst='%s')", src.GetPath().c_str(), dst.GetPath().c_str());
+ FileSpec fixed_dst(dst);
+
+ if (!fixed_dst.GetFilename())
+ fixed_dst.GetFilename() = src.GetFilename();
+
+ ConstString working_dir = GetWorkingDirectory();
+
+ if (dst)
+ {
+ if (dst.GetDirectory())
+ {
+ const char first_dst_dir_char = dst.GetDirectory().GetCString()[0];
+ if (first_dst_dir_char == '/' || first_dst_dir_char == '\\')
+ {
+ fixed_dst.GetDirectory() = dst.GetDirectory();
+ }
+ // If the fixed destination file doesn't have a directory yet,
+ // then we must have a relative path. We will resolve this relative
+ // path against the platform's working directory
+ if (!fixed_dst.GetDirectory())
+ {
+ FileSpec relative_spec;
+ std::string path;
+ if (working_dir)
+ {
+ relative_spec.SetFile(working_dir.GetCString(), false);
+ relative_spec.AppendPathComponent(dst.GetPath().c_str());
+ fixed_dst.GetDirectory() = relative_spec.GetDirectory();
+ }
+ else
+ {
+ error.SetErrorStringWithFormat("platform working directory must be valid for relative path '%s'", dst.GetPath().c_str());
+ return error;
+ }
+ }
+ }
+ else
+ {
+ if (working_dir)
+ {
+ fixed_dst.GetDirectory() = working_dir;
+ }
+ else
+ {
+ error.SetErrorStringWithFormat("platform working directory must be valid for relative path '%s'", dst.GetPath().c_str());
+ return error;
+ }
+ }
+ }
+ else
+ {
+ if (working_dir)
+ {
+ fixed_dst.GetDirectory() = working_dir;
+ }
+ else
+ {
+ error.SetErrorStringWithFormat("platform working directory must be valid when destination directory is empty");
+ return error;
+ }
+ }
+
+ if (log)
+ log->Printf ("Platform::Install (src='%s', dst='%s') fixed_dst='%s'", src.GetPath().c_str(), dst.GetPath().c_str(), fixed_dst.GetPath().c_str());
+
+ if (GetSupportsRSync())
+ {
+ error = PutFile(src, dst);
+ }
+ else
+ {
+ switch (src.GetFileType())
+ {
+ case FileSpec::eFileTypeDirectory:
+ {
+ if (GetFileExists (fixed_dst))
+ Unlink (fixed_dst.GetPath().c_str());
+ uint32_t permissions = src.GetPermissions();
+ if (permissions == 0)
+ permissions = eFilePermissionsDirectoryDefault;
+ std::string dst_dir_path(fixed_dst.GetPath());
+ error = MakeDirectory(dst_dir_path.c_str(), permissions);
+ if (error.Success())
+ {
+ // Make a filespec that only fills in the directory of a FileSpec so
+ // when we enumerate we can quickly fill in the filename for dst copies
+ FileSpec recurse_dst;
+ recurse_dst.GetDirectory().SetCString(dst_dir_path.c_str());
+ std::string src_dir_path (src.GetPath());
+ RecurseCopyBaton baton = { recurse_dst, this, Error() };
+ FileSpec::EnumerateDirectory(src_dir_path.c_str(), true, true, true, RecurseCopy_Callback, &baton);
+ return baton.error;
+ }
+ }
+ break;
+
+ case FileSpec::eFileTypeRegular:
+ if (GetFileExists (fixed_dst))
+ Unlink (fixed_dst.GetPath().c_str());
+ error = PutFile(src, fixed_dst);
+ break;
+
+ case FileSpec::eFileTypeSymbolicLink:
+ {
+ if (GetFileExists (fixed_dst))
+ Unlink (fixed_dst.GetPath().c_str());
+ char buf[PATH_MAX];
+ error = Host::Readlink(src.GetPath().c_str(), buf, sizeof(buf));
+ if (error.Success())
+ error = CreateSymlink(dst.GetPath().c_str(), buf);
+ }
+ break;
+ case FileSpec::eFileTypePipe:
+ error.SetErrorString("platform install doesn't handle pipes");
+ break;
+ case FileSpec::eFileTypeSocket:
+ error.SetErrorString("platform install doesn't handle sockets");
+ break;
+ case FileSpec::eFileTypeInvalid:
+ case FileSpec::eFileTypeUnknown:
+ case FileSpec::eFileTypeOther:
+ error.SetErrorString("platform install doesn't handle non file or directory items");
+ break;
+ }
+ }
+ return error;
+}
+
+bool
+Platform::SetWorkingDirectory (const ConstString &path)
+{
+ if (IsHost())
+ {
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+ if (log)
+ log->Printf("Platform::SetWorkingDirectory('%s')", path.GetCString());
+#ifdef _WIN32
+ // Not implemented on Windows
+ return false;
+#else
+ if (path)
+ {
+ if (chdir(path.GetCString()) == 0)
+ return true;
+ }
+ return false;
+#endif
+ }
+ else
+ {
+ m_working_dir.Clear();
+ return SetRemoteWorkingDirectory(path);
+ }
+}
+
+Error
+Platform::MakeDirectory (const char *path, uint32_t permissions)
+{
+ if (IsHost())
+ return Host::MakeDirectory (path, permissions);
+ else
+ {
+ Error error;
+ error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), __PRETTY_FUNCTION__);
+ return error;
+ }
+}
+
+Error
+Platform::GetFilePermissions (const char *path, uint32_t &file_permissions)
+{
+ if (IsHost())
+ return Host::GetFilePermissions(path, file_permissions);
+ else
+ {
+ Error error;
+ error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), __PRETTY_FUNCTION__);
+ return error;
+ }
+}
+
+Error
+Platform::SetFilePermissions (const char *path, uint32_t file_permissions)
+{
+ if (IsHost())
+ return Host::SetFilePermissions(path, file_permissions);
+ else
+ {
+ Error error;
+ error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), __PRETTY_FUNCTION__);
+ return error;
+ }
+}
+
+ConstString
Platform::GetName ()
{
- const char *name = GetHostname();
- if (name == NULL || name[0] == '\0')
- return GetPluginName();
- return ConstString (name);
+ return GetPluginName();
}
const char *
@@ -424,6 +749,16 @@ Platform::GetHostname ()
return m_name.c_str();
}
+bool
+Platform::SetRemoteWorkingDirectory(const ConstString &path)
+{
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+ if (log)
+ log->Printf("Platform::SetRemoteWorkingDirectory('%s')", path.GetCString());
+ m_working_dir = path;
+ return true;
+}
+
const char *
Platform::GetUserName (uint32_t uid)
{
@@ -779,14 +1114,6 @@ Platform::IsCompatibleArchitecture (const ArchSpec &arch, bool exact_arch_match,
return false;
}
-uint32_t
-Platform::MakeDirectory (const FileSpec &spec,
- mode_t mode)
-{
- std::string path(spec.GetPath());
- return this->MakeDirectory(path,mode);
-}
-
Error
Platform::PutFile (const FileSpec& source,
const FileSpec& destination,
@@ -805,12 +1132,29 @@ Platform::GetFile (const FileSpec& source,
return error;
}
+Error
+Platform::CreateSymlink (const char *src, // The name of the link is in src
+ const char *dst)// The symlink points to dst
+{
+ Error error("unimplemented");
+ return error;
+}
+
bool
Platform::GetFileExists (const lldb_private::FileSpec& file_spec)
{
return false;
}
+Error
+Platform::Unlink (const char *path)
+{
+ Error error("unimplemented");
+ return error;
+}
+
+
+
lldb_private::Error
Platform::RunShellCommand (const char *command, // Shouldn't be NULL
const char *working_dir, // Pass NULL to use the current working directory
diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp
index 700afdb..1de322a 100644
--- a/source/Target/Process.cpp
+++ b/source/Target/Process.cpp
@@ -1023,6 +1023,8 @@ Process::Process(Target &target, Listener &listener) :
m_thread_mutex (Mutex::eMutexTypeRecursive),
m_thread_list_real (this),
m_thread_list (this),
+ m_extended_thread_list (this),
+ m_extended_thread_stop_id (0),
m_notifications (),
m_image_tokens (),
m_listener (listener),
@@ -1148,6 +1150,7 @@ Process::Finalize()
m_dyld_ap.reset();
m_thread_list_real.Destroy();
m_thread_list.Destroy();
+ m_extended_thread_list.Destroy();
std::vector<Notifications> empty_notifications;
m_notifications.swap(empty_notifications);
m_image_tokens.clear();
@@ -1591,6 +1594,13 @@ Process::UpdateThreadListIfNeeded ()
m_thread_list_real.Update(real_thread_list);
m_thread_list.Update (new_thread_list);
m_thread_list.SetStopID (stop_id);
+
+ if (GetLastNaturalStopID () != m_extended_thread_stop_id)
+ {
+ // Clear any extended threads that we may have accumulated previously
+ m_extended_thread_list.Clear();
+ m_extended_thread_stop_id = GetLastNaturalStopID ();
+ }
}
}
}
@@ -2103,12 +2113,37 @@ Process::CreateBreakpointSite (const BreakpointLocationSP &owner, bool use_hardw
}
else
{
- // Report error for setting breakpoint...
- m_target.GetDebugger().GetErrorFile().Printf ("warning: failed to set breakpoint site at 0x%" PRIx64 " for breakpoint %i.%i: %s\n",
- load_addr,
- owner->GetBreakpoint().GetID(),
- owner->GetID(),
- error.AsCString() ? error.AsCString() : "unkown error");
+ bool show_error = true;
+ switch (GetState())
+ {
+ case eStateInvalid:
+ case eStateUnloaded:
+ case eStateConnected:
+ case eStateAttaching:
+ case eStateLaunching:
+ case eStateDetached:
+ case eStateExited:
+ show_error = false;
+ break;
+
+ case eStateStopped:
+ case eStateRunning:
+ case eStateStepping:
+ case eStateCrashed:
+ case eStateSuspended:
+ show_error = IsAlive();
+ break;
+ }
+
+ if (show_error)
+ {
+ // Report error for setting breakpoint...
+ m_target.GetDebugger().GetErrorFile().Printf ("warning: failed to set breakpoint site at 0x%" PRIx64 " for breakpoint %i.%i: %s\n",
+ load_addr,
+ owner->GetBreakpoint().GetID(),
+ owner->GetID(),
+ error.AsCString() ? error.AsCString() : "unkown error");
+ }
}
}
}
@@ -2350,6 +2385,7 @@ Process::DisableSoftwareBreakpoint (BreakpointSite *bp_site)
size_t
Process::ReadMemory (addr_t addr, void *buf, size_t size, Error &error)
{
+ error.Clear();
if (!GetDisableMemoryCache())
{
#if defined (VERIFY_MEMORY_READS)
@@ -2873,7 +2909,7 @@ Process::WaitForProcessStopPrivate (const TimeValue *timeout, EventSP &event_sp)
}
Error
-Process::Launch (const ProcessLaunchInfo &launch_info)
+Process::Launch (ProcessLaunchInfo &launch_info)
{
Error error;
m_abi_sp.reset();
@@ -2891,6 +2927,13 @@ Process::Launch (const ProcessLaunchInfo &launch_info)
exe_module->GetPlatformFileSpec().GetPath(platform_exec_file_path, sizeof(platform_exec_file_path));
if (exe_module->GetFileSpec().Exists())
{
+ // Install anything that might need to be installed prior to launching.
+ // For host systems, this will do nothing, but if we are connected to a
+ // remote platform it will install any needed binaries
+ error = GetTarget().Install(&launch_info);
+ if (error.Fail())
+ return error;
+
if (PrivateStateThreadIsValid ())
PausePrivateStateThread ();
@@ -4697,11 +4740,7 @@ Process::SettingsTerminate ()
ExecutionResults
Process::RunThreadPlan (ExecutionContext &exe_ctx,
lldb::ThreadPlanSP &thread_plan_sp,
- bool stop_others,
- bool run_others,
- bool unwind_on_error,
- bool ignore_breakpoints,
- uint32_t timeout_usec,
+ const EvaluateExpressionOptions &options,
Stream &errors)
{
ExecutionResults return_value = eExecutionSetupError;
@@ -4812,6 +4851,17 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
thread->QueueThreadPlan(thread_plan_sp, false); // This used to pass "true" does that make sense?
+ if (options.GetDebug())
+ {
+ // In this case, we aren't actually going to run, we just want to stop right away.
+ // Flush this thread so we will refetch the stacks and show the correct backtrace.
+ // FIXME: To make this prettier we should invent some stop reason for this, but that
+ // is only cosmetic, and this functionality is only of use to lldb developers who can
+ // live with not pretty...
+ thread->Flush();
+ return eExecutionStoppedForDebug;
+ }
+
Listener listener("lldb.process.listener.run-thread-plan");
lldb::EventSP event_to_broadcast_sp;
@@ -4853,11 +4903,12 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
TimeValue one_thread_timeout = TimeValue::Now();
TimeValue final_timeout = one_thread_timeout;
- if (run_others)
+ uint32_t timeout_usec = options.GetTimeoutUsec();
+ if (options.GetTryAllThreads())
{
// If we are running all threads then we take half the time to run all threads, bounded by
// .25 sec.
- if (timeout_usec == 0)
+ if (options.GetTimeoutUsec() == 0)
one_thread_timeout.OffsetWithMicroSeconds(default_one_thread_timeout_usec);
else
{
@@ -4969,7 +5020,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
if (before_first_timeout)
{
- if (run_others)
+ if (options.GetTryAllThreads())
timeout_ptr = &one_thread_timeout;
else
{
@@ -5085,7 +5136,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
if (log)
log->Printf ("Process::RunThreadPlan() stopped for breakpoint: %s.", stop_info_sp->GetDescription());
return_value = eExecutionHitBreakpoint;
- if (!ignore_breakpoints)
+ if (!options.DoesIgnoreBreakpoints())
{
event_to_broadcast_sp = event_sp;
}
@@ -5094,7 +5145,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
{
if (log)
log->PutCString ("Process::RunThreadPlan(): thread plan didn't successfully complete.");
- if (!unwind_on_error)
+ if (!options.DoesUnwindOnError())
event_to_broadcast_sp = event_sp;
return_value = eExecutionInterrupted;
}
@@ -5145,7 +5196,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
// either exit, or try with all threads running for the same timeout.
if (log) {
- if (run_others)
+ if (options.GetTryAllThreads())
{
uint64_t remaining_time = final_timeout - TimeValue::Now();
if (before_first_timeout)
@@ -5228,7 +5279,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
continue;
}
- if (!run_others)
+ if (!options.GetTryAllThreads())
{
if (log)
log->PutCString ("Process::RunThreadPlan(): try_all_threads was false, we stopped so now we're quitting.");
@@ -5301,8 +5352,8 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
// 1) The execution successfully completed
// 2) We hit a breakpoint, and ignore_breakpoints was true
// 3) We got some other error, and discard_on_error was true
- bool should_unwind = (return_value == eExecutionInterrupted && unwind_on_error)
- || (return_value == eExecutionHitBreakpoint && ignore_breakpoints);
+ bool should_unwind = (return_value == eExecutionInterrupted && options.DoesUnwindOnError())
+ || (return_value == eExecutionHitBreakpoint && options.DoesIgnoreBreakpoints());
if (return_value == eExecutionCompleted
|| should_unwind)
@@ -5422,7 +5473,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
if (log)
log->PutCString("Process::RunThreadPlan(): execution set up error.");
- if (unwind_on_error)
+ if (options.DoesUnwindOnError())
{
thread->DiscardThreadPlansUpToPlan (thread_plan_sp);
thread_plan_sp->SetPrivate (orig_plan_private);
@@ -5446,7 +5497,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
{
if (log)
log->PutCString("Process::RunThreadPlan(): thread plan stopped in mid course");
- if (unwind_on_error && thread_plan_sp)
+ if (options.DoesUnwindOnError() && thread_plan_sp)
{
if (log)
log->PutCString("Process::RunThreadPlan(): discarding thread plan 'cause unwind_on_error is set.");
@@ -5518,6 +5569,9 @@ Process::ExecutionResultAsCString (ExecutionResults result)
case eExecutionTimedOut:
result_name = "eExecutionTimedOut";
break;
+ case eExecutionStoppedForDebug:
+ result_name = "eExecutionStoppedForDebug";
+ break;
}
return result_name;
}
@@ -5633,7 +5687,7 @@ Process::DidExec ()
{
Target &target = GetTarget();
target.CleanupProcess ();
- target.ClearModules();
+ target.ClearModules(false);
m_dynamic_checkers_ap.reset();
m_abi_sp.reset();
m_system_runtime_ap.reset();
@@ -5649,5 +5703,9 @@ Process::DidExec ()
// Flush the process (threads and all stack frames) after running CompleteAttach()
// in case the dynamic loader loaded things in new locations.
Flush();
+
+ // After we figure out what was loaded/unloaded in CompleteAttach,
+ // we need to let the target know so it can do any cleanup it needs to.
+ target.DidExec();
}
diff --git a/source/Target/RegisterContext.cpp b/source/Target/RegisterContext.cpp
index 3d68ba8..93dce3e 100644
--- a/source/Target/RegisterContext.cpp
+++ b/source/Target/RegisterContext.cpp
@@ -440,6 +440,18 @@ RegisterContext::WriteRegisterValueToMemory (const RegisterInfo *reg_info,
}
+bool
+RegisterContext::ReadAllRegisterValues (lldb_private::RegisterCheckpoint &reg_checkpoint)
+{
+ return ReadAllRegisterValues(reg_checkpoint.GetData());
+}
+
+bool
+RegisterContext::WriteAllRegisterValues (const lldb_private::RegisterCheckpoint &reg_checkpoint)
+{
+ return WriteAllRegisterValues(reg_checkpoint.GetData());
+}
+
TargetSP
RegisterContext::CalculateTarget ()
{
diff --git a/source/Target/StackFrameList.cpp b/source/Target/StackFrameList.cpp
index eaac361..631a77b 100644
--- a/source/Target/StackFrameList.cpp
+++ b/source/Target/StackFrameList.cpp
@@ -301,7 +301,7 @@ StackFrameList::GetFramesUpTo(uint32_t end_idx)
if (reg_ctx_sp)
{
- const bool success = unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
+ const bool success = unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
// There shouldn't be any way not to get the frame info for frame 0.
// But if the unwinder can't make one, lets make one by hand with the
// SP as the CFA and see if that gets any further.
@@ -329,7 +329,7 @@ StackFrameList::GetFramesUpTo(uint32_t end_idx)
}
else
{
- const bool success = unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
+ const bool success = unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
if (!success)
{
// We've gotten to the end of the stack.
@@ -451,14 +451,17 @@ StackFrameList::GetFramesUpTo(uint32_t end_idx)
{
if (end_idx < m_concrete_frames_fetched)
return;
-
- uint32_t num_frames = unwinder->GetFramesUpTo(end_idx);
- if (num_frames <= end_idx + 1)
+
+ if (unwinder)
{
- //Done unwinding.
- m_concrete_frames_fetched = UINT32_MAX;
+ uint32_t num_frames = unwinder->GetFramesUpTo(end_idx);
+ if (num_frames <= end_idx + 1)
+ {
+ //Done unwinding.
+ m_concrete_frames_fetched = UINT32_MAX;
+ }
+ m_frames.resize(num_frames);
}
- m_frames.resize(num_frames);
}
}
diff --git a/source/Target/SystemRuntime.cpp b/source/Target/SystemRuntime.cpp
index 7ce150f..5c07ed3 100644
--- a/source/Target/SystemRuntime.cpp
+++ b/source/Target/SystemRuntime.cpp
@@ -33,7 +33,8 @@ SystemRuntime::FindPlugin (Process *process)
// SystemRuntime constructor
//----------------------------------------------------------------------
SystemRuntime::SystemRuntime(Process *process) :
- m_process (process)
+ m_process (process),
+ m_types ()
{
}
@@ -59,15 +60,14 @@ SystemRuntime::ModulesDidLoad (ModuleList &module_list)
{
}
-std::vector<ConstString>
+const std::vector<ConstString> &
SystemRuntime::GetExtendedBacktraceTypes ()
{
- std::vector<ConstString> types;
- return types;
+ return m_types;
}
ThreadSP
-SystemRuntime::GetExtendedBacktrace (ThreadSP thread, ConstString type)
+SystemRuntime::GetExtendedBacktraceThread (ThreadSP thread, ConstString type)
{
return ThreadSP();
}
diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp
index 18efd8c..fd9626a 100644
--- a/source/Target/Target.cpp
+++ b/source/Target/Target.cpp
@@ -192,7 +192,7 @@ Target::Destroy()
DeleteCurrentProcess ();
m_platform_sp.reset();
m_arch.Clear();
- ClearModules();
+ ClearModules(true);
m_section_load_list.Clear();
const bool notify = false;
m_breakpoint_list.RemoveAll(notify);
@@ -1014,9 +1014,9 @@ LoadScriptingResourceForModule (const ModuleSP &module_sp, Target *target)
}
void
-Target::ClearModules()
+Target::ClearModules(bool delete_locations)
{
- ModulesDidUnload (m_images, true);
+ ModulesDidUnload (m_images, delete_locations);
GetSectionLoadList().Clear();
m_images.Clear();
m_scratch_ast_context_ap.reset();
@@ -1025,10 +1025,18 @@ Target::ClearModules()
}
void
+Target::DidExec ()
+{
+ // When a process exec's we need to know about it so we can do some cleanup.
+ m_breakpoint_list.RemoveInvalidLocations(m_arch);
+ m_internal_breakpoint_list.RemoveInvalidLocations(m_arch);
+}
+
+void
Target::SetExecutableModule (ModuleSP& executable_sp, bool get_dependent_files)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TARGET));
- ClearModules();
+ ClearModules(false);
if (executable_sp.get())
{
@@ -1098,7 +1106,7 @@ Target::SetArchitecture (const ArchSpec &arch_spec)
m_arch = arch_spec;
ModuleSP executable_sp = GetExecutableModule ();
- ClearModules();
+ ClearModules(true);
// Need to do something about unsetting breakpoints.
if (executable_sp)
@@ -2182,12 +2190,78 @@ Target::RunStopHooks ()
result.GetImmediateErrorStream()->Flush();
}
+const TargetPropertiesSP &
+Target::GetGlobalProperties()
+{
+ static TargetPropertiesSP g_settings_sp;
+ if (!g_settings_sp)
+ {
+ g_settings_sp.reset (new TargetProperties (NULL));
+ }
+ return g_settings_sp;
+}
+
+Error
+Target::Install (ProcessLaunchInfo *launch_info)
+{
+ Error error;
+ PlatformSP platform_sp (GetPlatform());
+ if (platform_sp)
+ {
+ if (platform_sp->IsRemote())
+ {
+ if (platform_sp->IsConnected())
+ {
+ // Install all files that have an install path, and always install the
+ // main executable when connected to a remote platform
+ const ModuleList& modules = GetImages();
+ const size_t num_images = modules.GetSize();
+ for (size_t idx = 0; idx < num_images; ++idx)
+ {
+ const bool is_main_executable = idx == 0;
+ ModuleSP module_sp(modules.GetModuleAtIndex(idx));
+ if (module_sp)
+ {
+ FileSpec local_file (module_sp->GetFileSpec());
+ if (local_file)
+ {
+ FileSpec remote_file (module_sp->GetRemoteInstallFileSpec());
+ if (!remote_file)
+ {
+ if (is_main_executable) // TODO: add setting for always installing main executable???
+ {
+ // Always install the main executable
+ remote_file.GetDirectory() = platform_sp->GetWorkingDirectory();
+ remote_file.GetFilename() = module_sp->GetFileSpec().GetFilename();
+ }
+ }
+ if (remote_file)
+ {
+ error = platform_sp->Install(local_file, remote_file);
+ if (error.Success())
+ {
+ module_sp->SetPlatformFileSpec(remote_file);
+ if (is_main_executable)
+ {
+ if (launch_info)
+ launch_info->SetExecutableFile(remote_file, false);
+ }
+ }
+ else
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return error;
+}
//--------------------------------------------------------------
-// class Target::StopHook
+// Target::StopHook
//--------------------------------------------------------------
-
-
Target::StopHook::StopHook (lldb::TargetSP target_sp, lldb::user_id_t uid) :
UserID (uid),
m_target_sp (target_sp),
@@ -2519,6 +2593,9 @@ protected:
mutable bool m_got_host_env;
};
+//----------------------------------------------------------------------
+// TargetProperties
+//----------------------------------------------------------------------
TargetProperties::TargetProperties (Target *target) :
Properties ()
{
@@ -2807,17 +2884,10 @@ TargetProperties::GetMemoryModuleLoadLevel() const
}
-const TargetPropertiesSP &
-Target::GetGlobalProperties()
-{
- static TargetPropertiesSP g_settings_sp;
- if (!g_settings_sp)
- {
- g_settings_sp.reset (new TargetProperties (NULL));
- }
- return g_settings_sp;
-}
+//----------------------------------------------------------------------
+// Target::TargetEventData
+//----------------------------------------------------------------------
const ConstString &
Target::TargetEventData::GetFlavorString ()
{
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp
index 98c2601..07f5321 100644
--- a/source/Target/Thread.cpp
+++ b/source/Target/Thread.cpp
@@ -496,7 +496,19 @@ Thread::ThreadStoppedForAReason (void)
bool
Thread::CheckpointThreadState (ThreadStateCheckpoint &saved_state)
{
- if (!SaveFrameZeroState(saved_state.register_backup))
+ saved_state.register_backup_sp.reset();
+ lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0));
+ if (frame_sp)
+ {
+ lldb::RegisterCheckpointSP reg_checkpoint_sp(new RegisterCheckpoint(RegisterCheckpoint::Reason::eExpression));
+ if (reg_checkpoint_sp)
+ {
+ lldb::RegisterContextSP reg_ctx_sp (frame_sp->GetRegisterContext());
+ if (reg_ctx_sp && reg_ctx_sp->ReadAllRegisterValues (*reg_checkpoint_sp))
+ saved_state.register_backup_sp = reg_checkpoint_sp;
+ }
+ }
+ if (!saved_state.register_backup_sp)
return false;
saved_state.stop_info_sp = GetStopInfo();
@@ -511,8 +523,26 @@ Thread::CheckpointThreadState (ThreadStateCheckpoint &saved_state)
bool
Thread::RestoreRegisterStateFromCheckpoint (ThreadStateCheckpoint &saved_state)
{
- RestoreSaveFrameZero(saved_state.register_backup);
- return true;
+ if (saved_state.register_backup_sp)
+ {
+ lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0));
+ if (frame_sp)
+ {
+ lldb::RegisterContextSP reg_ctx_sp (frame_sp->GetRegisterContext());
+ if (reg_ctx_sp)
+ {
+ bool ret = reg_ctx_sp->WriteAllRegisterValues (*saved_state.register_backup_sp);
+
+ // Clear out all stack frames as our world just changed.
+ ClearStackFrames();
+ reg_ctx_sp->InvalidateIfNeeded(true);
+ if (m_unwinder_ap.get())
+ m_unwinder_ap->Clear();
+ return ret;
+ }
+ }
+ }
+ return false;
}
bool
@@ -1420,14 +1450,6 @@ Thread::QueueThreadPlanForStepInRange
ThreadPlanSP
-Thread::QueueThreadPlanForStepOverBreakpointPlan (bool abort_other_plans)
-{
- ThreadPlanSP thread_plan_sp (new ThreadPlanStepOverBreakpoint (*this));
- QueueThreadPlan (thread_plan_sp, abort_other_plans);
- return thread_plan_sp;
-}
-
-ThreadPlanSP
Thread::QueueThreadPlanForStepOut
(
bool abort_other_plans,
@@ -1470,25 +1492,6 @@ Thread::QueueThreadPlanForStepThrough (StackID &return_stack_id, bool abort_othe
}
ThreadPlanSP
-Thread::QueueThreadPlanForCallFunction (bool abort_other_plans,
- Address& function,
- lldb::addr_t arg,
- bool stop_other_threads,
- bool unwind_on_error,
- bool ignore_breakpoints)
-{
- ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this,
- function,
- ClangASTType(),
- arg,
- stop_other_threads,
- unwind_on_error,
- ignore_breakpoints));
- QueueThreadPlan (thread_plan_sp, abort_other_plans);
- return thread_plan_sp;
-}
-
-ThreadPlanSP
Thread::QueueThreadPlanForRunToAddress (bool abort_other_plans,
Address &target_addr,
bool stop_other_threads)
@@ -1994,48 +1997,6 @@ Thread::GetStackFrameStatus (Stream& strm,
num_frames_with_source);
}
-bool
-Thread::SaveFrameZeroState (RegisterCheckpoint &checkpoint)
-{
- lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0));
- if (frame_sp)
- {
- checkpoint.SetStackID(frame_sp->GetStackID());
- lldb::RegisterContextSP reg_ctx_sp (frame_sp->GetRegisterContext());
- if (reg_ctx_sp)
- return reg_ctx_sp->ReadAllRegisterValues (checkpoint.GetData());
- }
- return false;
-}
-
-bool
-Thread::RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint)
-{
- return ResetFrameZeroRegisters (checkpoint.GetData());
-}
-
-bool
-Thread::ResetFrameZeroRegisters (lldb::DataBufferSP register_data_sp)
-{
- lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0));
- if (frame_sp)
- {
- lldb::RegisterContextSP reg_ctx_sp (frame_sp->GetRegisterContext());
- if (reg_ctx_sp)
- {
- bool ret = reg_ctx_sp->WriteAllRegisterValues (register_data_sp);
-
- // Clear out all stack frames as our world just changed.
- ClearStackFrames();
- reg_ctx_sp->InvalidateIfNeeded(true);
- if (m_unwinder_ap.get())
- m_unwinder_ap->Clear();
- return ret;
- }
- }
- return false;
-}
-
Unwind *
Thread::GetUnwinder ()
{
diff --git a/source/Target/ThreadPlanCallFunction.cpp b/source/Target/ThreadPlanCallFunction.cpp
index c9baaaf..854750b 100644
--- a/source/Target/ThreadPlanCallFunction.cpp
+++ b/source/Target/ThreadPlanCallFunction.cpp
@@ -55,8 +55,6 @@ ThreadPlanCallFunction::ConstructorSetup (Thread &thread,
if (!abi)
return false;
- TargetSP target_sp (thread.CalculateTarget());
-
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
SetBreakpoints();
@@ -74,7 +72,7 @@ ThreadPlanCallFunction::ConstructorSetup (Thread &thread,
return false;
}
- Module *exe_module = target_sp->GetExecutableModulePointer();
+ Module *exe_module = GetTarget().GetExecutableModulePointer();
if (exe_module == NULL)
{
@@ -107,7 +105,7 @@ ThreadPlanCallFunction::ConstructorSetup (Thread &thread,
}
}
- start_load_addr = m_start_addr.GetLoadAddress (target_sp.get());
+ start_load_addr = m_start_addr.GetLoadAddress (&GetTarget());
// Checkpoint the thread state so we can restore it later.
if (log && log->GetVerbose())
@@ -120,7 +118,7 @@ ThreadPlanCallFunction::ConstructorSetup (Thread &thread,
log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
return false;
}
- function_load_addr = m_function_addr.GetLoadAddress (target_sp.get());
+ function_load_addr = m_function_addr.GetLoadAddress (&GetTarget());
return true;
}
@@ -128,109 +126,36 @@ ThreadPlanCallFunction::ConstructorSetup (Thread &thread,
ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
const Address &function,
const ClangASTType &return_type,
- addr_t arg,
- bool stop_other_threads,
- bool unwind_on_error,
- bool ignore_breakpoints,
- addr_t *this_arg,
- addr_t *cmd_arg) :
+ llvm::ArrayRef<addr_t> args,
+ const EvaluateExpressionOptions &options) :
ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
m_valid (false),
- m_stop_other_threads (stop_other_threads),
+ m_stop_other_threads (options.GetStopOthers()),
+ m_unwind_on_error (options.DoesUnwindOnError()),
+ m_ignore_breakpoints (options.DoesIgnoreBreakpoints()),
+ m_debug_execution (options.GetDebug()),
+ m_trap_exceptions (options.GetTrapExceptions()),
m_function_addr (function),
m_function_sp (0),
m_return_type (return_type),
m_takedown_done (false),
- m_stop_address (LLDB_INVALID_ADDRESS),
- m_unwind_on_error (unwind_on_error),
- m_ignore_breakpoints (ignore_breakpoints)
+ m_should_clear_objc_exception_bp(false),
+ m_should_clear_cxx_exception_bp (false),
+ m_stop_address (LLDB_INVALID_ADDRESS)
{
lldb::addr_t start_load_addr;
ABI *abi;
lldb::addr_t function_load_addr;
if (!ConstructorSetup (thread, abi, start_load_addr, function_load_addr))
return;
-
- if (this_arg && cmd_arg)
- {
- if (!abi->PrepareTrivialCall (thread,
- m_function_sp,
- function_load_addr,
- start_load_addr,
- this_arg,
- cmd_arg,
- &arg))
- return;
- }
- else if (this_arg)
- {
- if (!abi->PrepareTrivialCall (thread,
- m_function_sp,
- function_load_addr,
- start_load_addr,
- this_arg,
- &arg))
- return;
- }
- else
- {
- if (!abi->PrepareTrivialCall (thread,
- m_function_sp,
- function_load_addr,
- start_load_addr,
- &arg))
- return;
- }
-
- ReportRegisterState ("Function call was set up. Register state was:");
- m_valid = true;
-}
-
-
-ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
- const Address &function,
- const ClangASTType &return_type,
- bool stop_other_threads,
- bool unwind_on_error,
- bool ignore_breakpoints,
- addr_t *arg1_ptr,
- addr_t *arg2_ptr,
- addr_t *arg3_ptr,
- addr_t *arg4_ptr,
- addr_t *arg5_ptr,
- addr_t *arg6_ptr) :
- ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
- m_valid (false),
- m_stop_other_threads (stop_other_threads),
- m_function_addr (function),
- m_function_sp (0),
- m_return_type (return_type),
- m_takedown_done (false),
- m_stop_address (LLDB_INVALID_ADDRESS),
- m_unwind_on_error (unwind_on_error),
- m_ignore_breakpoints (ignore_breakpoints)
-{
- lldb::addr_t start_load_addr;
- ABI *abi;
- lldb::addr_t function_load_addr;
- if (!ConstructorSetup (thread, abi, start_load_addr, function_load_addr))
+ if (!abi->PrepareTrivialCall(thread,
+ m_function_sp,
+ function_load_addr,
+ start_load_addr,
+ args))
return;
- if (!abi->PrepareTrivialCall (thread,
- m_function_sp,
- function_load_addr,
- start_load_addr,
- arg1_ptr,
- arg2_ptr,
- arg3_ptr,
- arg4_ptr,
- arg5_ptr,
- arg6_ptr))
- {
- return;
- }
-
ReportRegisterState ("Function call was set up. Register state was:");
m_valid = true;
@@ -299,7 +224,11 @@ ThreadPlanCallFunction::DoTakedown (bool success)
m_takedown_done = true;
m_stop_address = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
m_real_stop_info_sp = GetPrivateStopInfo ();
- m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state);
+ if (!m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state))
+ {
+ if (log)
+ log->Printf("ThreadPlanCallFunction(%p): DoTakedown failed to restore register state", this);
+ }
SetPlanComplete(success);
ClearBreakpoints();
if (log && log->GetVerbose())
@@ -560,25 +489,34 @@ void
ThreadPlanCallFunction::SetBreakpoints ()
{
ProcessSP process_sp (m_thread.CalculateProcess());
- if (process_sp)
+ if (m_trap_exceptions && process_sp)
{
m_cxx_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeC_plus_plus);
m_objc_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeObjC);
if (m_cxx_language_runtime)
+ {
+ m_should_clear_cxx_exception_bp = !m_cxx_language_runtime->ExceptionBreakpointsAreSet();
m_cxx_language_runtime->SetExceptionBreakpoints();
+ }
if (m_objc_language_runtime)
+ {
+ m_should_clear_objc_exception_bp = !m_objc_language_runtime->ExceptionBreakpointsAreSet();
m_objc_language_runtime->SetExceptionBreakpoints();
+ }
}
}
void
ThreadPlanCallFunction::ClearBreakpoints ()
{
- if (m_cxx_language_runtime)
- m_cxx_language_runtime->ClearExceptionBreakpoints();
- if (m_objc_language_runtime)
- m_objc_language_runtime->ClearExceptionBreakpoints();
+ if (m_trap_exceptions)
+ {
+ if (m_cxx_language_runtime && m_should_clear_cxx_exception_bp)
+ m_cxx_language_runtime->ClearExceptionBreakpoints();
+ if (m_objc_language_runtime && m_should_clear_objc_exception_bp)
+ m_objc_language_runtime->ClearExceptionBreakpoints();
+ }
}
bool
@@ -586,21 +524,24 @@ ThreadPlanCallFunction::BreakpointsExplainStop()
{
StopInfoSP stop_info_sp = GetPrivateStopInfo ();
- if ((m_cxx_language_runtime &&
- m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))
- ||(m_objc_language_runtime &&
- m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp)))
+ if (m_trap_exceptions)
{
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
- if (log)
- log->Printf ("ThreadPlanCallFunction::BreakpointsExplainStop - Hit an exception breakpoint, setting plan complete.");
-
- SetPlanComplete(false);
-
- // If the user has set the ObjC language breakpoint, it would normally get priority over our internal
- // catcher breakpoint, but in this case we can't let that happen, so force the ShouldStop here.
- stop_info_sp->OverrideShouldStop (true);
- return true;
+ if ((m_cxx_language_runtime &&
+ m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))
+ ||(m_objc_language_runtime &&
+ m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp)))
+ {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
+ if (log)
+ log->Printf ("ThreadPlanCallFunction::BreakpointsExplainStop - Hit an exception breakpoint, setting plan complete.");
+
+ SetPlanComplete(false);
+
+ // If the user has set the ObjC language breakpoint, it would normally get priority over our internal
+ // catcher breakpoint, but in this case we can't let that happen, so force the ShouldStop here.
+ stop_info_sp->OverrideShouldStop (true);
+ return true;
+ }
}
return false;
diff --git a/source/Target/ThreadPlanCallUserExpression.cpp b/source/Target/ThreadPlanCallUserExpression.cpp
index 70de1cb..827de3e 100644
--- a/source/Target/ThreadPlanCallUserExpression.cpp
+++ b/source/Target/ThreadPlanCallUserExpression.cpp
@@ -38,14 +38,10 @@ using namespace lldb_private;
ThreadPlanCallUserExpression::ThreadPlanCallUserExpression (Thread &thread,
Address &function,
- lldb::addr_t arg,
- bool stop_other_threads,
- bool unwind_on_error,
- bool ignore_breakpoints,
- lldb::addr_t *this_arg,
- lldb::addr_t *cmd_arg,
+ llvm::ArrayRef<lldb::addr_t> args,
+ const EvaluateExpressionOptions &options,
ClangUserExpression::ClangUserExpressionSP &user_expression_sp) :
- ThreadPlanCallFunction (thread, function, ClangASTType(), arg, stop_other_threads, unwind_on_error, ignore_breakpoints, this_arg, cmd_arg),
+ ThreadPlanCallFunction (thread, function, ClangASTType(), args, options),
m_user_expression_sp (user_expression_sp)
{
// User expressions are generally "User generated" so we should set them up to stop when done.
diff --git a/source/Target/ThreadPlanStepInRange.cpp b/source/Target/ThreadPlanStepInRange.cpp
index c1f14bd..2cfd29f 100644
--- a/source/Target/ThreadPlanStepInRange.cpp
+++ b/source/Target/ThreadPlanStepInRange.cpp
@@ -132,9 +132,9 @@ ThreadPlanStepInRange::ShouldStop (Event *event_ptr)
bool stop_others;
if (m_stop_others == lldb::eOnlyThisThread)
- stop_others = false;
- else
stop_others = true;
+ else
+ stop_others = false;
FrameComparison frame_order = CompareCurrentFrameToStartFrame();
OpenPOWER on IntegriCloud