Improve SBThread's stepping API using SBError parameter.
Summary: The new methods will allow to get error messages from stepping API.
Reviewers: aprantl, clayborg, labath, jingham
Reviewed By: aprantl, clayborg, jingham
Subscribers: apolyakov, labath, jingham, clayborg, lemo, lldb-commits
Differential Revision: https://reviews.llvm.org/D47991
llvm-svn: 335180
diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp
index def3b3a..0d25b85 100644
--- a/lldb/source/API/SBThread.cpp
+++ b/lldb/source/API/SBThread.cpp
@@ -633,6 +633,11 @@
}
void SBThread::StepOver(lldb::RunMode stop_other_threads) {
+ SBError error; // Ignored
+ StepOver(stop_other_threads, error);
+}
+
+void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
std::unique_lock<std::recursive_mutex> lock;
@@ -643,28 +648,29 @@
static_cast<void *>(exe_ctx.GetThreadPtr()),
Thread::RunModeAsCString(stop_other_threads));
- if (exe_ctx.HasThreadScope()) {
- Thread *thread = exe_ctx.GetThreadPtr();
- bool abort_other_plans = false;
- StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
-
- ThreadPlanSP new_plan_sp;
- if (frame_sp) {
- if (frame_sp->HasDebugInformation()) {
- const LazyBool avoid_no_debug = eLazyBoolCalculate;
- SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
- new_plan_sp = thread->QueueThreadPlanForStepOverRange(
- abort_other_plans, sc.line_entry, sc, stop_other_threads,
- avoid_no_debug);
- } else {
- new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
- true, abort_other_plans, stop_other_threads);
- }
- }
-
- // This returns an error, we should use it!
- ResumeNewPlan(exe_ctx, new_plan_sp.get());
+ if (!exe_ctx.HasThreadScope()) {
+ error.SetErrorString("this SBThread object is invalid");
+ return;
}
+
+ Thread *thread = exe_ctx.GetThreadPtr();
+ bool abort_other_plans = false;
+ StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
+
+ ThreadPlanSP new_plan_sp;
+ if (frame_sp) {
+ if (frame_sp->HasDebugInformation()) {
+ const LazyBool avoid_no_debug = eLazyBoolCalculate;
+ SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
+ new_plan_sp = thread->QueueThreadPlanForStepOverRange(
+ abort_other_plans, sc.line_entry, sc, stop_other_threads,
+ avoid_no_debug);
+ } else {
+ new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
+ true, abort_other_plans, stop_other_threads);
+ }
+ }
+ error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
}
void SBThread::StepInto(lldb::RunMode stop_other_threads) {
@@ -673,7 +679,7 @@
void SBThread::StepInto(const char *target_name,
lldb::RunMode stop_other_threads) {
- SBError error;
+ SBError error; // Ignored
StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
}
@@ -691,41 +697,48 @@
target_name ? target_name : "<NULL>",
Thread::RunModeAsCString(stop_other_threads));
- if (exe_ctx.HasThreadScope()) {
- bool abort_other_plans = false;
+ if (!exe_ctx.HasThreadScope()) {
+ error.SetErrorString("this SBThread object is invalid");
+ return;
+ }
- Thread *thread = exe_ctx.GetThreadPtr();
- StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
- ThreadPlanSP new_plan_sp;
+ bool abort_other_plans = false;
- if (frame_sp && frame_sp->HasDebugInformation()) {
- SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
- AddressRange range;
- if (end_line == LLDB_INVALID_LINE_NUMBER)
- range = sc.line_entry.range;
- else {
- if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
- return;
- }
+ Thread *thread = exe_ctx.GetThreadPtr();
+ StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
+ ThreadPlanSP new_plan_sp;
- const LazyBool step_out_avoids_code_without_debug_info =
- eLazyBoolCalculate;
- const LazyBool step_in_avoids_code_without_debug_info =
- eLazyBoolCalculate;
- new_plan_sp = thread->QueueThreadPlanForStepInRange(
- abort_other_plans, range, sc, target_name, stop_other_threads,
- step_in_avoids_code_without_debug_info,
- step_out_avoids_code_without_debug_info);
- } else {
- new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
- false, abort_other_plans, stop_other_threads);
+ if (frame_sp && frame_sp->HasDebugInformation()) {
+ SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
+ AddressRange range;
+ if (end_line == LLDB_INVALID_LINE_NUMBER)
+ range = sc.line_entry.range;
+ else {
+ if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
+ return;
}
- error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
+ const LazyBool step_out_avoids_code_without_debug_info =
+ eLazyBoolCalculate;
+ const LazyBool step_in_avoids_code_without_debug_info =
+ eLazyBoolCalculate;
+ new_plan_sp = thread->QueueThreadPlanForStepInRange(
+ abort_other_plans, range, sc, target_name, stop_other_threads,
+ step_in_avoids_code_without_debug_info,
+ step_out_avoids_code_without_debug_info);
+ } else {
+ new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
+ false, abort_other_plans, stop_other_threads);
}
+ error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
}
void SBThread::StepOut() {
+ SBError error; // Ignored
+ StepOut(error);
+}
+
+void SBThread::StepOut(SBError &error) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
std::unique_lock<std::recursive_mutex> lock;
@@ -735,23 +748,30 @@
log->Printf("SBThread(%p)::StepOut ()",
static_cast<void *>(exe_ctx.GetThreadPtr()));
- if (exe_ctx.HasThreadScope()) {
- bool abort_other_plans = false;
- bool stop_other_threads = false;
-
- Thread *thread = exe_ctx.GetThreadPtr();
-
- const LazyBool avoid_no_debug = eLazyBoolCalculate;
- ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
- abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
- eVoteNoOpinion, 0, avoid_no_debug));
-
- // This returns an error, we should use it!
- ResumeNewPlan(exe_ctx, new_plan_sp.get());
+ if (!exe_ctx.HasThreadScope()) {
+ error.SetErrorString("this SBThread object is invalid");
+ return;
}
+
+ bool abort_other_plans = false;
+ bool stop_other_threads = false;
+
+ Thread *thread = exe_ctx.GetThreadPtr();
+
+ const LazyBool avoid_no_debug = eLazyBoolCalculate;
+ ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
+ abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
+ eVoteNoOpinion, 0, avoid_no_debug));
+
+ error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
}
-void SBThread::StepOutOfFrame(lldb::SBFrame &sb_frame) {
+void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
+ SBError error; // Ignored
+ StepOutOfFrame(sb_frame, error);
+}
+
+void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
std::unique_lock<std::recursive_mutex> lock;
@@ -762,6 +782,7 @@
log->Printf(
"SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.",
static_cast<void *>(exe_ctx.GetThreadPtr()));
+ error.SetErrorString("passed invalid SBFrame object");
return;
}
@@ -774,27 +795,36 @@
static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
}
- if (exe_ctx.HasThreadScope()) {
- bool abort_other_plans = false;
- bool stop_other_threads = false;
- Thread *thread = exe_ctx.GetThreadPtr();
- if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
- log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another "
- "thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.",
- static_cast<void *>(exe_ctx.GetThreadPtr()),
- sb_frame.GetThread().GetThreadID(), thread->GetID());
- }
-
- ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
- abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
- eVoteNoOpinion, frame_sp->GetFrameIndex()));
-
- // This returns an error, we should use it!
- ResumeNewPlan(exe_ctx, new_plan_sp.get());
+ if (!exe_ctx.HasThreadScope()) {
+ error.SetErrorString("this SBThread object is invalid");
+ return;
}
+
+ bool abort_other_plans = false;
+ bool stop_other_threads = false;
+ Thread *thread = exe_ctx.GetThreadPtr();
+ if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
+ log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another "
+ "thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.",
+ static_cast<void *>(exe_ctx.GetThreadPtr()),
+ sb_frame.GetThread().GetThreadID(), thread->GetID());
+ error.SetErrorString("passed a frame from another thread");
+ return;
+ }
+
+ ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
+ abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
+ eVoteNoOpinion, frame_sp->GetFrameIndex()));
+
+ error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
}
void SBThread::StepInstruction(bool step_over) {
+ SBError error; // Ignored
+ StepInstruction(step_over, error);
+}
+
+void SBThread::StepInstruction(bool step_over, SBError &error) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
std::unique_lock<std::recursive_mutex> lock;
@@ -804,17 +834,24 @@
log->Printf("SBThread(%p)::StepInstruction (step_over=%i)",
static_cast<void *>(exe_ctx.GetThreadPtr()), step_over);
- if (exe_ctx.HasThreadScope()) {
- Thread *thread = exe_ctx.GetThreadPtr();
- ThreadPlanSP new_plan_sp(
- thread->QueueThreadPlanForStepSingleInstruction(step_over, true, true));
-
- // This returns an error, we should use it!
- ResumeNewPlan(exe_ctx, new_plan_sp.get());
+ if (!exe_ctx.HasThreadScope()) {
+ error.SetErrorString("this SBThread object is invalid");
+ return;
}
+
+ Thread *thread = exe_ctx.GetThreadPtr();
+ ThreadPlanSP new_plan_sp(
+ thread->QueueThreadPlanForStepSingleInstruction(step_over, true, true));
+
+ error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
}
void SBThread::RunToAddress(lldb::addr_t addr) {
+ SBError error; // Ignored
+ RunToAddress(addr, error);
+}
+
+void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
std::unique_lock<std::recursive_mutex> lock;
@@ -824,20 +861,22 @@
log->Printf("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")",
static_cast<void *>(exe_ctx.GetThreadPtr()), addr);
- if (exe_ctx.HasThreadScope()) {
- bool abort_other_plans = false;
- bool stop_other_threads = true;
-
- Address target_addr(addr);
-
- Thread *thread = exe_ctx.GetThreadPtr();
-
- ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
- abort_other_plans, target_addr, stop_other_threads));
-
- // This returns an error, we should use it!
- ResumeNewPlan(exe_ctx, new_plan_sp.get());
+ if (!exe_ctx.HasThreadScope()) {
+ error.SetErrorString("this SBThread object is invalid");
+ return;
}
+
+ bool abort_other_plans = false;
+ bool stop_other_threads = true;
+
+ Address target_addr(addr);
+
+ Thread *thread = exe_ctx.GetThreadPtr();
+
+ ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
+ abort_other_plans, target_addr, stop_other_threads));
+
+ error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
}
SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
@@ -1082,6 +1121,11 @@
}
bool SBThread::Suspend() {
+ SBError error; // Ignored
+ return Suspend(error);
+}
+
+bool SBThread::Suspend(SBError &error) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
std::unique_lock<std::recursive_mutex> lock;
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
@@ -1093,11 +1137,13 @@
exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
result = true;
} else {
+ error.SetErrorString("process is running");
if (log)
log->Printf("SBThread(%p)::Suspend() => error: process is running",
static_cast<void *>(exe_ctx.GetThreadPtr()));
}
- }
+ } else
+ error.SetErrorString("this SBThread object is invalid");
if (log)
log->Printf("SBThread(%p)::Suspend() => %i",
static_cast<void *>(exe_ctx.GetThreadPtr()), result);
@@ -1105,6 +1151,11 @@
}
bool SBThread::Resume() {
+ SBError error; // Ignored
+ return Resume(error);
+}
+
+bool SBThread::Resume(SBError &error) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
std::unique_lock<std::recursive_mutex> lock;
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
@@ -1117,11 +1168,13 @@
exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
result = true;
} else {
+ error.SetErrorString("process is running");
if (log)
log->Printf("SBThread(%p)::Resume() => error: process is running",
static_cast<void *>(exe_ctx.GetThreadPtr()));
}
- }
+ } else
+ error.SetErrorString("this SBThread object is invalid");
if (log)
log->Printf("SBThread(%p)::Resume() => %i",
static_cast<void *>(exe_ctx.GetThreadPtr()), result);