This abstracts read/write locks on the current host system. It is currently backed by pthread_rwlock_t objects so it should work on all unix systems. We also need a way to control multi-threaded access to the process through the public API when it is running. For example it isn't a good idea to try and get stack frames while the process is running. To implement this, the lldb_private::Process class now contains a ReadWriteLock member variable named m_run_lock which is used to control the public process state. The public process state represents the state of the process as the client knows it. The private is used to control the actual current process state. So the public state of the process can be stopped, yet the private state can be running when evaluating an expression for example. Adding the read/write lock where readers are clients that want the process to stay stopped, and writers are clients that run the process, allows us to accurately control multi-threaded access to the process. Switched the SBThread and SBFrame over to us shared pointers to the ExecutionContextRef class instead of making their own class to track this. This fixed an issue with assigning on SBFrame to another and will also centralize the code that tracks weak references to execution context objects into one location. llvm-svn: 154099
67 lines
2.2 KiB
Python
67 lines
2.2 KiB
Python
"""
|
|
Test utility functions for the frame object.
|
|
"""
|
|
|
|
import os
|
|
import unittest2
|
|
import lldb
|
|
from lldbtest import *
|
|
|
|
class FrameUtilsTestCase(TestBase):
|
|
|
|
mydir = os.path.join("python_api", "lldbutil", "frame")
|
|
|
|
def setUp(self):
|
|
# Call super's setUp().
|
|
TestBase.setUp(self)
|
|
# Find the line number to break inside main().
|
|
self.line = line_number('main.c',
|
|
"// Find the line number here.")
|
|
|
|
@python_api_test
|
|
def test_frame_utils(self):
|
|
"""Test utility functions for the frame object."""
|
|
self.buildDefault()
|
|
self.frame_utils()
|
|
|
|
def frame_utils(self):
|
|
exe = os.path.join(os.getcwd(), "a.out")
|
|
|
|
target = self.dbg.CreateTarget(exe)
|
|
self.assertTrue(target, VALID_TARGET)
|
|
|
|
breakpoint = target.BreakpointCreateByLocation("main.c", self.line)
|
|
self.assertTrue(breakpoint, VALID_BREAKPOINT)
|
|
|
|
# Now launch the process, and do not stop at entry point.
|
|
process = target.LaunchSimple(None, None, os.getcwd())
|
|
|
|
if not process:
|
|
self.fail("SBTarget.LaunchProcess() failed")
|
|
self.assertTrue(process.GetState() == lldb.eStateStopped,
|
|
PROCESS_STOPPED)
|
|
|
|
import lldbutil
|
|
thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
|
|
self.assertTrue (thread)
|
|
frame0 = thread.GetFrameAtIndex(0)
|
|
self.assertTrue (frame0)
|
|
frame1 = thread.GetFrameAtIndex(1)
|
|
self.assertTrue (frame1)
|
|
parent = lldbutil.get_parent_frame(frame0)
|
|
self.assertTrue(parent and parent.GetFrameID() == frame1.GetFrameID())
|
|
frame0_args = lldbutil.get_args_as_string(frame0)
|
|
parent_args = lldbutil.get_args_as_string(parent)
|
|
self.assertTrue(frame0_args and parent_args and "(int)val=1" in frame0_args)
|
|
if self.TraceOn():
|
|
lldbutil.print_stacktrace(thread)
|
|
print "Current frame: %s" % frame0_args
|
|
print "Parent frame: %s" % parent_args
|
|
|
|
|
|
if __name__ == '__main__':
|
|
import atexit
|
|
lldb.SBDebugger.Initialize()
|
|
atexit.register(lambda: lldb.SBDebugger.Terminate())
|
|
unittest2.main()
|