[Lldb-commits] [lldb] r144064 - in /lldb/trunk: include/lldb/Target/Process.h include/lldb/Target/StopInfo.h source/Expression/ClangUserExpression.cpp source/Target/Process.cpp source/Target/StopInfo.cpp test/functionalities/conditional_break/TestConditionalBreak.py test/functionalities/conditional_break/conditional_break.py
Jim Ingham
jingham at apple.com
Mon Nov 7 19:00:12 PST 2011
Author: jingham
Date: Mon Nov 7 21:00:11 2011
New Revision: 144064
URL: http://llvm.org/viewvc/llvm-project?rev=144064&view=rev
Log:
Do a better job of detecting when a breakpoint command has set the target running again (except you have to ignore
cases where the breakpoint runs expressions, those don't count as really "running again").
Modified:
lldb/trunk/include/lldb/Target/Process.h
lldb/trunk/include/lldb/Target/StopInfo.h
lldb/trunk/source/Expression/ClangUserExpression.cpp
lldb/trunk/source/Target/Process.cpp
lldb/trunk/source/Target/StopInfo.cpp
lldb/trunk/test/functionalities/conditional_break/TestConditionalBreak.py
lldb/trunk/test/functionalities/conditional_break/conditional_break.py
Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=144064&r1=144063&r2=144064&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Mon Nov 7 21:00:11 2011
@@ -890,8 +890,11 @@
friend bool operator== (const ProcessModID &lhs, const ProcessModID &rhs);
public:
ProcessModID () :
- m_stop_id (0),
- m_memory_id (0)
+ m_stop_id (0),
+ m_resume_id (0),
+ m_memory_id (0),
+ m_last_user_expression_resume (0),
+ m_running_user_expression (false)
{}
ProcessModID (const ProcessModID &rhs) :
@@ -911,11 +914,22 @@
~ProcessModID () {}
- void BumpStopID () { m_stop_id++; }
+ void BumpStopID () {
+ m_stop_id++;
+ }
+
void BumpMemoryID () { m_memory_id++; }
+ void BumpResumeID () {
+ m_resume_id++;
+ if (m_running_user_expression > 0)
+ m_last_user_expression_resume = m_resume_id;
+ }
+
uint32_t GetStopID() const { return m_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; }
bool MemoryIDEqual (const ProcessModID &compare) const
{
@@ -936,9 +950,23 @@
{
return m_stop_id != UINT32_MAX;
}
+
+ void
+ SetRunningUserExpression (bool on)
+ {
+ // REMOVEME printf ("Setting running user expression %s at resume id %d - value: %d.\n", on ? "on" : "off", m_resume_id, m_running_user_expression);
+ if (on)
+ m_running_user_expression++;
+ else
+ m_running_user_expression--;
+ }
+
private:
uint32_t m_stop_id;
+ uint32_t m_resume_id;
uint32_t m_memory_id;
+ uint32_t m_last_user_expression_resume;
+ uint32_t m_running_user_expression;
};
inline bool operator== (const ProcessModID &lhs, const ProcessModID &rhs)
{
@@ -1957,12 +1985,30 @@
return m_mod_id;
}
+ const ProcessModID &
+ GetModIDRef () const
+ {
+ return m_mod_id;
+ }
+
uint32_t
GetStopID () const
{
return m_mod_id.GetStopID();
}
+ uint32_t
+ GetResumeID () const
+ {
+ return m_mod_id.GetResumeID();
+ }
+
+ uint32_t
+ GetLastUserExpressionResumeID () const
+ {
+ return m_mod_id.GetLastUserExpressionResumeID();
+ }
+
//------------------------------------------------------------------
/// Set accessor for the process exit status (return code).
///
@@ -2608,6 +2654,9 @@
return true;
}
+ void
+ SetRunningUserExpression (bool on);
+
//------------------------------------------------------------------
// lldb::ExecutionContextScope pure virtual functions
//------------------------------------------------------------------
Modified: lldb/trunk/include/lldb/Target/StopInfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StopInfo.h?rev=144064&r1=144063&r2=144064&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/StopInfo.h (original)
+++ lldb/trunk/include/lldb/Target/StopInfo.h Mon Nov 7 21:00:11 2011
@@ -22,6 +22,7 @@
class StopInfo
{
+ friend class Process;
public:
//------------------------------------------------------------------
// Constructors and Destructors
@@ -136,13 +137,13 @@
//------------------------------------------------------------------
Thread & m_thread; // The thread corresponding to the stop reason.
uint32_t m_stop_id; // The process stop ID for which this stop info is valid
+ uint32_t m_resume_id; // This is the resume ID when we made this stop ID.
uint64_t m_value; // A generic value that can be used for things pertaining to this stop info
std::string m_description; // A textual description describing this stop.
- // This provides an accessor to the PrivateEventState of the process for StopInfo's w/o having to make each
- // StopInfo subclass a friend of Process.
- lldb::StateType
- GetPrivateState ();
+ // This determines whether the target has run since this stop info.
+ // N.B. running to evaluate a user expression does not count.
+ bool HasTargetRunSinceMe ();
private:
friend class Thread;
Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=144064&r1=144063&r2=144064&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUserExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangUserExpression.cpp Mon Nov 7 21:00:11 2011
@@ -567,6 +567,9 @@
if (log)
log->Printf("-- [ClangUserExpression::Execute] Execution of expression begins --");
+ if (exe_ctx.GetProcessPtr())
+ exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
+
ExecutionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
call_plan_sp,
stop_others,
@@ -575,6 +578,9 @@
single_thread_timeout_usec,
error_stream);
+ if (exe_ctx.GetProcessPtr())
+ exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
+
if (log)
log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --");
Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=144064&r1=144063&r2=144064&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Mon Nov 7 21:00:11 2011
@@ -1156,6 +1156,12 @@
}
}
+void
+Process::SetRunningUserExpression (bool on)
+{
+ m_mod_id.SetRunningUserExpression (on);
+}
+
addr_t
Process::GetImageInfoAddress()
{
@@ -2425,6 +2431,7 @@
// to see if they are suppoed to start back up with a signal.
if (m_thread_list.WillResume())
{
+ m_mod_id.BumpResumeID();
error = DoResume();
if (error.Success())
{
@@ -2986,18 +2993,47 @@
// If we're stopped and haven't restarted, then do the breakpoint commands here:
if (m_state == eStateStopped && ! m_restarted)
- {
- int num_threads = m_process_sp->GetThreadList().GetSize();
+ {
+ ThreadList &curr_thread_list = m_process_sp->GetThreadList();
+ int num_threads = curr_thread_list.GetSize();
int idx;
// The actions might change one of the thread's stop_info's opinions about whether we should
// stop the process, so we need to query that as we go.
+
+ // One other complication here, is that we try to catch any case where the target has run (except for expressions)
+ // and immediately exit, but if we get that wrong (which is possible) then the thread list might have changed, and
+ // that would cause our iteration here to crash. We could make a copy of the thread list, but we'd really like
+ // to also know if it has changed at all, so we make up a vector of the thread ID's and check what we get back
+ // against this list & bag out if anything differs.
+ std::vector<lldb::tid_t> thread_index_array(num_threads);
+ for (idx = 0; idx < num_threads; ++idx)
+ thread_index_array[idx] = curr_thread_list.GetThreadAtIndex(idx)->GetIndexID();
+
bool still_should_stop = true;
for (idx = 0; idx < num_threads; ++idx)
{
- lldb::ThreadSP thread_sp = m_process_sp->GetThreadList().GetThreadAtIndex(idx);
-
+ curr_thread_list = m_process_sp->GetThreadList();
+ if (curr_thread_list.GetSize() != num_threads)
+ {
+ lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_PROCESS));
+ log->Printf("Number of threads changed from %d to %d while processing event.", num_threads, curr_thread_list.GetSize());
+ break;
+ }
+
+ lldb::ThreadSP thread_sp = curr_thread_list.GetThreadAtIndex(idx);
+
+ if (thread_sp->GetIndexID() != thread_index_array[idx])
+ {
+ lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_PROCESS));
+ log->Printf("The thread at position %d changed from %d to %d while processing event.",
+ idx,
+ thread_index_array[idx],
+ thread_sp->GetIndexID());
+ break;
+ }
+
StopInfoSP stop_info_sp = thread_sp->GetStopInfo ();
if (stop_info_sp)
{
@@ -3006,7 +3042,9 @@
// event so that whoever is receiving it will know to wait for the running event and reflect
// that state appropriately.
// We also need to stop processing actions, since they aren't expecting the target to be running.
- if (m_process_sp->GetPrivateState() == eStateRunning)
+
+ // FIXME: we might have run.
+ if (stop_info_sp->HasTargetRunSinceMe())
{
SetRestarted (true);
break;
Modified: lldb/trunk/source/Target/StopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StopInfo.cpp?rev=144064&r1=144063&r2=144064&view=diff
==============================================================================
--- lldb/trunk/source/Target/StopInfo.cpp (original)
+++ lldb/trunk/source/Target/StopInfo.cpp Mon Nov 7 21:00:11 2011
@@ -35,6 +35,7 @@
StopInfo::StopInfo (Thread &thread, uint64_t value) :
m_thread (thread),
m_stop_id (thread.GetProcess().GetStopID()),
+ m_resume_id (thread.GetProcess().GetResumeID()),
m_value (value)
{
}
@@ -49,12 +50,37 @@
StopInfo::MakeStopInfoValid ()
{
m_stop_id = m_thread.GetProcess().GetStopID();
+ m_resume_id = m_thread.GetProcess().GetResumeID();
}
-lldb::StateType
-StopInfo::GetPrivateState ()
+bool
+StopInfo::HasTargetRunSinceMe ()
{
- return m_thread.GetProcess().GetPrivateState();
+ lldb::StateType ret_type = m_thread.GetProcess().GetPrivateState();
+ if (ret_type == eStateRunning)
+ {
+ return true;
+ }
+ else if (ret_type == eStateStopped)
+ {
+ // This is a little tricky. We want to count "run and stopped again before you could
+ // ask this question as a "TRUE" answer to HasTargetRunSinceMe. But we don't want to
+ // include any running of the target done for expressions. So we track both resumes,
+ // and resumes caused by expressions, and check if there are any resumes NOT caused
+ // by expressions.
+
+ uint32_t curr_resume_id = m_thread.GetProcess().GetResumeID();
+ uint32_t last_user_expression_id = m_thread.GetProcess().GetLastUserExpressionResumeID ();
+ if (curr_resume_id == m_resume_id)
+ {
+ return false;
+ }
+ else if (curr_resume_id > last_user_expression_id)
+ {
+ return true;
+ }
+ }
+ return false;
}
//----------------------------------------------------------------------
@@ -161,7 +187,7 @@
// However we want to run all the callbacks, except of course if one of them actually
// resumes the target.
// So we use stop_requested to track what we're were asked to do.
- bool stop_requested = true;
+ bool stop_requested = false;
for (size_t j = 0; j < num_owners; j++)
{
lldb::BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(j);
@@ -170,11 +196,30 @@
&m_thread,
m_thread.GetStackFrameAtIndex(0).get(),
false);
- stop_requested = bp_loc_sp->InvokeCallback (&context);
+ bool callback_return;
+
+ // FIXME: For now the callbacks have to run in async mode - the first time we restart we need
+ // to get out of there. So set it here.
+ // When we figure out how to stack breakpoint hits then this will change.
+
+ Debugger &debugger = m_thread.GetProcess().GetTarget().GetDebugger();
+ bool old_async = debugger.GetAsyncExecution();
+ debugger.SetAsyncExecution (true);
+
+ callback_return = bp_loc_sp->InvokeCallback (&context);
+
+ debugger.SetAsyncExecution (old_async);
+
+ if (callback_return)
+ stop_requested = true;
+
// Also make sure that the callback hasn't continued the target.
// If it did, when we'll set m_should_start to false and get out of here.
- if (GetPrivateState() == eStateRunning)
+ if (HasTargetRunSinceMe ())
+ {
m_should_stop = false;
+ break;
+ }
}
if (m_should_stop && !stop_requested)
@@ -423,7 +468,7 @@
bool stop_requested = wp_sp->InvokeCallback (&context);
// Also make sure that the callback hasn't continued the target.
// If it did, when we'll set m_should_start to false and get out of here.
- if (GetPrivateState() == eStateRunning)
+ if (HasTargetRunSinceMe ())
m_should_stop = false;
if (m_should_stop && !stop_requested)
Modified: lldb/trunk/test/functionalities/conditional_break/TestConditionalBreak.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/conditional_break/TestConditionalBreak.py?rev=144064&r1=144063&r2=144064&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/conditional_break/TestConditionalBreak.py (original)
+++ lldb/trunk/test/functionalities/conditional_break/TestConditionalBreak.py Mon Nov 7 21:00:11 2011
@@ -71,6 +71,7 @@
# The 10 in range(10) is just an arbitrary number, which means we would
# like to try for at most 10 times.
for j in range(10):
+ print "j is: ", j
thread = process.GetThreadAtIndex(0)
if thread.GetNumFrames() >= 2:
@@ -102,9 +103,13 @@
# executable, sets the breakpoint on c(), and adds the callback for the
# breakpoint such that lldb only stops when the caller of c() is a().
# the "my" package that defines the date() function.
+ print "About to source .lldb"
+
self.runCmd("command source .lldb")
+ print "About to run."
self.runCmd("run", RUN_SUCCEEDED)
+ print "Done running"
# The stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
Modified: lldb/trunk/test/functionalities/conditional_break/conditional_break.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/conditional_break/conditional_break.py?rev=144064&r1=144063&r2=144064&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/conditional_break/conditional_break.py (original)
+++ lldb/trunk/test/functionalities/conditional_break/conditional_break.py Mon Nov 7 21:00:11 2011
@@ -7,7 +7,8 @@
dbg = lldb.SBDebugger.FindDebuggerWithID(lldb.debugger_unique_id)
# Perform synchronous interaction with the debugger.
- dbg.SetAsync(False)
+ old_async = dbg.GetAsync()
+ dbg.SetAsync(True)
# Retrieve the target, process, and the only thread.
target = dbg.GetSelectedTarget()
@@ -18,17 +19,19 @@
# of the leaf function c() is a(). If it's not the right caller, we ask the
# command interpreter to continue execution.
- #print >> sys.stdout, "Checking call frames..."
- #lldbutil.print_stacktrace(thread)
+ print >> sys.stdout, "Checking call frames..."
+ lldbutil.print_stacktrace(thread)
+ should_stop = True
if thread.GetNumFrames() >= 2:
funcs = lldbutil.get_function_names(thread)
- #print >> sys.stdout, funcs[0], "called from", funcs[1]
+ print >> sys.stdout, funcs[0], "called from", funcs[1]
if (funcs[0] == 'c' and funcs[1] == 'a'):
- #print >> sys.stdout, "Stopped at c() with immediate caller as a()."
- pass
+ should_stop = True
else:
- #print >> sys.stdout, "Continuing..."
process.Continue()
+ should_stop = False
+
+ dbg.SetAsync(old_async)
+ return should_stop
- return True
More information about the lldb-commits
mailing list