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
This commit is contained in:
@@ -633,6 +633,11 @@ SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
|
||||
}
|
||||
|
||||
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 @@ void SBThread::StepOver(lldb::RunMode stop_other_threads) {
|
||||
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(lldb::RunMode stop_other_threads) {
|
||||
|
||||
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 @@ void SBThread::StepInto(const char *target_name, uint32_t end_line,
|
||||
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 @@ void SBThread::StepOut() {
|
||||
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 @@ void SBThread::StepOutOfFrame(lldb::SBFrame &sb_frame) {
|
||||
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 @@ void SBThread::StepOutOfFrame(lldb::SBFrame &sb_frame) {
|
||||
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 @@ void SBThread::StepInstruction(bool step_over) {
|
||||
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 @@ void SBThread::RunToAddress(lldb::addr_t addr) {
|
||||
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 @@ SBError SBThread::UnwindInnermostExpression() {
|
||||
}
|
||||
|
||||
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 @@ bool SBThread::Suspend() {
|
||||
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::Suspend() {
|
||||
}
|
||||
|
||||
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 @@ bool SBThread::Resume() {
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user