Add an SBProcess API to get the current StopID, either considering or ignoring stops caused by expression

evaluation.

<rdar://problem/12968562>

llvm-svn: 171914
This commit is contained in:
Jim Ingham 2013-01-08 23:22:42 +00:00
parent b68f7b2a77
commit bf2956a2f8
6 changed files with 62 additions and 2 deletions

View File

@ -171,6 +171,9 @@ public:
void
SendAsyncInterrupt();
uint32_t
GetStopID(bool include_expression_stops = false);
size_t
ReadMemory (addr_t addr, void *buf, size_t size, lldb::SBError &error);

View File

@ -1129,6 +1129,7 @@ friend bool operator== (const ProcessModID &lhs, const ProcessModID &rhs);
public:
ProcessModID () :
m_stop_id (0),
m_last_natural_stop_id(0),
m_resume_id (0),
m_memory_id (0),
m_last_user_expression_resume (0),
@ -1153,7 +1154,9 @@ public:
~ProcessModID () {}
void BumpStopID () {
m_stop_id++;
m_stop_id++;
if (!IsLastResumeForUserExpression())
m_last_natural_stop_id++;
}
void BumpMemoryID () { m_memory_id++; }
@ -1165,6 +1168,7 @@ public:
}
uint32_t GetStopID() const { return m_stop_id; }
uint32_t GetLastNaturalStopID() const { return m_last_natural_stop_id; }
uint32_t GetMemoryID () const { return m_memory_id; }
uint32_t GetResumeID () const { return m_resume_id; }
uint32_t GetLastUserExpressionResumeID () const { return m_last_user_expression_resume; }
@ -1207,6 +1211,7 @@ public:
private:
uint32_t m_stop_id;
uint32_t m_last_natural_stop_id;
uint32_t m_resume_id;
uint32_t m_memory_id;
uint32_t m_last_user_expression_resume;
@ -2516,6 +2521,12 @@ public:
return m_mod_id.GetLastUserExpressionResumeID();
}
uint32_t
GetLastNaturalStopID()
{
return m_mod_id.GetLastNaturalStopID();
}
//------------------------------------------------------------------
/// Set accessor for the process exit status (return code).
///

View File

@ -216,6 +216,16 @@ public:
lldb::SBError
Signal (int signal);
%feature("docstring", "
Returns a stop id that will increase every time the process executes. If
include_expression_stops is true, then stops caused by expression evaluation
will cause the returned value to increase, otherwise the counter returned will
only increase when execution is continued explicitly by the user. Note, the value
will always increase, but may increase by more than one per stop.
") GetStopID;
uint32_t
GetStopID(bool include_expression_stops = false);
void
SendAsyncInterrupt();

View File

@ -509,6 +509,21 @@ SBProcess::GetThreadAtIndex (size_t index)
return sb_thread;
}
uint32_t
SBProcess::GetStopID(bool include_expression_stops)
{
ProcessSP process_sp(GetSP());
if (process_sp)
{
Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
if (include_expression_stops)
return process_sp->GetStopID();
else
return process_sp->GetLastNaturalStopID();
}
return 0;
}
StateType
SBProcess::GetState ()
{

View File

@ -72,6 +72,9 @@ class TestObjCStepping(TestBase):
thread = threads[0]
# Get the stop id and for fun make sure it increases:
old_stop_id = process.GetStopID()
# Now step over, which should cause us to hit the breakpoint in "a"
thread.StepOver()
@ -80,6 +83,10 @@ class TestObjCStepping(TestBase):
if len(threads) != 1:
self.fail ("Failed to stop at breakpoint in a.")
# Check that the stop ID increases:
new_stop_id = process.GetStopID()
self.assertTrue(new_stop_id > old_stop_id, "Stop ID increases monotonically.")
thread = threads[0]
# Step over, and we should hit the breakpoint in b:
@ -99,13 +106,25 @@ class TestObjCStepping(TestBase):
current_bp.append(thread.GetStopReasonDataAtIndex(0))
current_bp.append(thread.GetStopReasonDataAtIndex(1))
frame.EvaluateExpression ('(int) printf ("aaaaaaaaaa\n")')
stop_id_before_expression = process.GetStopID()
stop_id_before_including_expressions = process.GetStopID(True)
frame.EvaluateExpression ("(int) printf (print_string)")
frame = thread.GetFrameAtIndex(0)
self.assertTrue (current_line == frame.GetLineEntry().GetLine(), "The line stayed the same after expression.")
self.assertTrue (current_file == frame.GetLineEntry().GetFileSpec(), "The file stayed the same after expression.")
self.assertTrue (thread.GetStopReason() == lldb.eStopReasonBreakpoint, "We still say we stopped for a breakpoint.")
self.assertTrue (thread.GetStopReasonDataAtIndex(0) == current_bp[0] and thread.GetStopReasonDataAtIndex(1) == current_bp[1], "And it is the same breakpoint.")
# Also make sure running the expression didn't change the public stop id
# but did change if we are asking for expression stops as well.
stop_id_after_expression = process.GetStopID()
stop_id_after_including_expressions = process.GetStopID(True)
self.assertTrue (stop_id_before_expression == stop_id_after_expression, "Expression calling doesn't change stop ID")
self.assertTrue (stop_id_after_including_expressions > stop_id_before_including_expressions, "Stop ID including expressions increments over expression call.")
# Do the same thing with an expression that's going to crash, and make sure we are still unchanged.

View File

@ -11,6 +11,7 @@
int a(int);
int b(int);
int c(int);
const char *print_string = "aaaaaaaaaa\n";
int a(int val)
{
@ -63,5 +64,6 @@ int main (int argc, char const *argv[])
int A7 = complex (a(5), b(6), c(7)); // Stop here to make sure bogus target steps over.
printf ("I am using print_string: %s.\n", print_string);
return 0;
}