summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Ingham <jingham@apple.com>2019-10-01 00:47:25 +0000
committerJim Ingham <jingham@apple.com>2019-10-01 00:47:25 +0000
commit58c3235ee976e577ab183a3058e804f4ac1ae027 (patch)
treeca295584f2be50ea9534b189b879dd90b7e5d75d
parent3b69bcc363d7e5b518dc673203e6ff88cd2498cb (diff)
downloadbcm5719-llvm-58c3235ee976e577ab183a3058e804f4ac1ae027.tar.gz
bcm5719-llvm-58c3235ee976e577ab183a3058e804f4ac1ae027.zip
Allow the internal-state-thread free access to the TargetAPI mutex.
It is always doing work on behalf of another thread that presumably has the mutex, so if it is calling SB API's it should have free access to the mutex. This is the same decision as we made earlier with the process RunLock. Differential Revision: https://reviews.llvm.org/D68174 llvm-svn: 373280
-rw-r--r--lldb/include/lldb/Target/Process.h2
-rw-r--r--lldb/include/lldb/Target/Target.h8
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/step_scripted/Steps.py35
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py44
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/step_scripted/main.c5
-rw-r--r--lldb/source/Target/Process.cpp6
-rw-r--r--lldb/source/Target/Target.cpp7
7 files changed, 96 insertions, 11 deletions
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index 65c68566f07..a4ef1cc4041 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -2272,6 +2272,8 @@ public:
void ClearPreResumeAction(PreResumeActionCallback callback, void *baton);
ProcessRunLock &GetRunLock();
+
+ bool CurrentThreadIsPrivateStateThread();
virtual Status SendEventData(const char *data) {
Status return_error("Sending an event is not supported for this process.");
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index dbec198c15e..e465046959f 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -535,7 +535,7 @@ public:
static const lldb::TargetPropertiesSP &GetGlobalProperties();
- std::recursive_mutex &GetAPIMutex() { return m_mutex; }
+ std::recursive_mutex &GetAPIMutex();
void DeleteCurrentProcess();
@@ -1288,6 +1288,12 @@ protected:
lldb::PlatformSP m_platform_sp; ///< The platform for this target.
std::recursive_mutex m_mutex; ///< An API mutex that is used by the lldb::SB*
/// classes make the SB interface thread safe
+ /// When the private state thread calls SB API's - usually because it is
+ /// running OS plugin or Python ThreadPlan code - it should not block on the
+ /// API mutex that is held by the code that kicked off the sequence of events
+ /// that led us to run the code. We hand out this mutex instead when we
+ /// detect that code is running on the private state thread.
+ std::recursive_mutex m_private_mutex;
Arch m_arch;
ModuleList m_images; ///< The list of images for this process (shared
/// libraries and anything dynamically loaded).
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/step_scripted/Steps.py b/lldb/packages/Python/lldbsuite/test/functionalities/step_scripted/Steps.py
index 1383a03f464..f93559af736 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/step_scripted/Steps.py
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/step_scripted/Steps.py
@@ -35,3 +35,38 @@ class StepScripted(StepWithChild):
def queue_child_thread_plan(self):
return self.thread_plan.QueueThreadPlanForStepScripted("Steps.StepOut")
+
+# This plan does a step-over until a variable changes value.
+class StepUntil(StepWithChild):
+ def __init__(self, thread_plan, dict):
+ self.frame = thread_plan.GetThread().frames[0]
+ self.target = thread_plan.GetThread().GetProcess().GetTarget()
+ self.value = self.frame.FindVariable("foo")
+ StepWithChild.__init__(self, thread_plan)
+
+ def queue_child_thread_plan(self):
+ le = self.frame.GetLineEntry()
+ start_addr = le.GetStartAddress()
+ start = start_addr.GetLoadAddress(self.target)
+ end = le.GetEndAddress().GetLoadAddress(self.target)
+ print("Stepping from 0x%x to 0x%x (0x%x)"%(start, end, end - start))
+ return self.thread_plan.QueueThreadPlanForStepOverRange(start_addr,
+ end - start)
+
+ def should_stop(self, event):
+ if not self.child_thread_plan.IsPlanComplete():
+ return False
+
+ # If we've stepped out of this frame, stop.
+ if not self.frame.IsValid():
+ return True
+
+ if not self.value.IsValid():
+ return True
+
+ print("Got next value: %d"%(self.value.GetValueAsUnsigned()))
+ if not self.value.GetValueDidChange():
+ self.child_thread_plan = self.queue_child_thread_plan()
+ return False
+ else:
+ return True
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py b/lldb/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py
index ce5f33f0bc9..cadadde9677 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py
@@ -12,23 +12,23 @@ class StepScriptedTestCase(TestBase):
NO_DEBUG_INFO_TESTCASE = True
+ def setUp(self):
+ TestBase.setUp(self)
+ self.main_source_file = lldb.SBFileSpec("main.c")
+ self.runCmd("command script import Steps.py")
+
def test_standard_step_out(self):
- """Tests stepping with the scripted thread plan laying over a standard thread plan for stepping out."""
+ """Tests stepping with the scripted thread plan laying over a standard
+ thread plan for stepping out."""
self.build()
- self.main_source_file = lldb.SBFileSpec("main.c")
self.step_out_with_scripted_plan("Steps.StepOut")
def test_scripted_step_out(self):
- """Tests stepping with the scripted thread plan laying over an another scripted thread plan for stepping out."""
+ """Tests stepping with the scripted thread plan laying over an another
+ scripted thread plan for stepping out."""
self.build()
- self.main_source_file = lldb.SBFileSpec("main.c")
self.step_out_with_scripted_plan("Steps.StepScripted")
- def setUp(self):
- TestBase.setUp(self)
- self.main_source_file = lldb.SBFileSpec("main.c")
- self.runCmd("command script import Steps.py")
-
def step_out_with_scripted_plan(self, name):
(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self,
"Set a breakpoint here",
@@ -43,6 +43,7 @@ class StepScriptedTestCase(TestBase):
frame = thread.GetFrameAtIndex(0)
self.assertEqual("main", frame.GetFunctionName())
+
def test_misspelled_plan_name(self):
"""Test that we get a useful error if we misspell the plan class name"""
self.build()
@@ -60,3 +61,28 @@ class StepScriptedTestCase(TestBase):
# Make sure we didn't let the process run:
self.assertEqual(stop_id, process.GetStopID(), "Process didn't run")
+
+ def test_checking_variable(self):
+ """Test that we can call SBValue API's from a scripted thread plan"""
+ self.build()
+ (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self,
+ "Set a breakpoint here",
+ self.main_source_file)
+
+ frame = thread.GetFrameAtIndex(0)
+ self.assertEqual("foo", frame.GetFunctionName())
+ foo_val = frame.FindVariable("foo")
+ self.assertTrue(foo_val.GetError().Success(), "Got the foo variable")
+ self.assertEqual(foo_val.GetValueAsUnsigned(), 10, "foo starts at 10")
+
+ err = thread.StepUsingScriptedThreadPlan("Steps.StepUntil")
+ self.assertTrue(err.Success(), err.GetCString())
+
+ # We should not have exited:
+ self.assertEqual(process.GetState(), lldb.eStateStopped, "We are stopped")
+
+ # We should still be in foo:
+ self.assertEqual("foo", frame.GetFunctionName())
+
+ # And foo should have changed:
+ self.assertTrue(foo_val.GetValueDidChange(), "Foo changed")
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/step_scripted/main.c b/lldb/packages/Python/lldbsuite/test/functionalities/step_scripted/main.c
index 88b3c17125d..bfd8a35d556 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/step_scripted/main.c
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/step_scripted/main.c
@@ -1,7 +1,10 @@
#include <stdio.h>
void foo() {
- printf("Set a breakpoint here.\n");
+ int foo = 10;
+ printf("%d\n", foo); // Set a breakpoint here.
+ foo = 20;
+ printf("%d\n", foo);
}
int main() {
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 40482e715dc..d0008023147 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -5538,6 +5538,12 @@ ProcessRunLock &Process::GetRunLock() {
return m_public_run_lock;
}
+bool Process::CurrentThreadIsPrivateStateThread()
+{
+ return m_private_state_thread.EqualsThread(Host::GetCurrentThread());
+}
+
+
void Process::Flush() {
m_thread_list.Flush();
m_extended_thread_list.Flush();
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 90ce85f1489..38406214ba1 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -4129,3 +4129,10 @@ Target::TargetEventData::GetModuleListFromEvent(const Event *event_ptr) {
module_list = event_data->m_module_list;
return module_list;
}
+
+std::recursive_mutex &Target::GetAPIMutex() {
+ if (GetProcessSP() && GetProcessSP()->CurrentThreadIsPrivateStateThread())
+ return m_private_mutex;
+ else
+ return m_mutex;
+}
OpenPOWER on IntegriCloud