forked from OSchip/llvm-project
166 lines
7.0 KiB
Python
166 lines
7.0 KiB
Python
"""
|
|
Use lldb Python API to test dynamic values in ObjC
|
|
"""
|
|
|
|
import os, time
|
|
import re
|
|
import unittest2
|
|
import lldb, lldbutil
|
|
from lldbtest import *
|
|
|
|
class ObjCDynamicValueTestCase(TestBase):
|
|
|
|
mydir = "objc-dynamic-value"
|
|
|
|
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
|
|
@python_api_test
|
|
def test_get_dynamic_objc_vals_with_dsym(self):
|
|
"""Test fetching ObjC dynamic values."""
|
|
self.buildDsym()
|
|
self.do_get_dynamic_vals()
|
|
|
|
@python_api_test
|
|
def test_get_objc_dynamic_vals_with_dwarf(self):
|
|
"""Test fetching ObjC dynamic values."""
|
|
self.buildDwarf()
|
|
self.do_get_dynamic_vals()
|
|
|
|
def setUp(self):
|
|
# Call super's setUp().
|
|
TestBase.setUp(self)
|
|
|
|
# Find the line number to break for main.c.
|
|
|
|
self.source_name = 'dynamic-value.m'
|
|
self.set_property_line = line_number(self.source_name, '// This is the line in setProperty, make sure we step to here.')
|
|
self.handle_SourceBase = line_number(self.source_name,
|
|
'// Break here to check dynamic values.')
|
|
self.main_before_setProperty_line = line_number(self.source_name,
|
|
'// Break here to see if we can step into real method.')
|
|
|
|
def examine_SourceDerived_ptr (self, object):
|
|
self.assertTrue (object)
|
|
self.assertTrue (object.GetTypeName().find ('SourceDerived') != -1)
|
|
derivedValue = object.GetChildMemberWithName ('_derivedValue')
|
|
self.assertTrue (derivedValue)
|
|
self.assertTrue (int (derivedValue.GetValue(), 0) == 30)
|
|
|
|
def do_get_dynamic_vals(self):
|
|
"""Make sure we get dynamic values correctly both for compiled in classes and dynamic ones"""
|
|
exe = os.path.join(os.getcwd(), "a.out")
|
|
|
|
# Create a target from the debugger.
|
|
|
|
target = self.dbg.CreateTarget (exe)
|
|
self.assertTrue(target, VALID_TARGET)
|
|
|
|
# Set up our breakpoints:
|
|
|
|
handle_SourceBase_bkpt = target.BreakpointCreateByLocation(self.source_name, self.handle_SourceBase)
|
|
self.assertTrue(handle_SourceBase_bkpt and
|
|
handle_SourceBase_bkpt.GetNumLocations() == 1,
|
|
VALID_BREAKPOINT)
|
|
|
|
main_before_setProperty_bkpt = target.BreakpointCreateByLocation(self.source_name, self.main_before_setProperty_line)
|
|
self.assertTrue(main_before_setProperty_bkpt and
|
|
main_before_setProperty_bkpt.GetNumLocations() == 1,
|
|
VALID_BREAKPOINT)
|
|
|
|
# Now launch the process, and do not stop at the entry point.
|
|
process = target.LaunchSimple (None, None, os.getcwd())
|
|
|
|
self.assertTrue(process.GetState() == lldb.eStateStopped,
|
|
PROCESS_STOPPED)
|
|
|
|
threads = lldbutil.get_threads_stopped_at_breakpoint (process, main_before_setProperty_bkpt)
|
|
self.assertTrue (len(threads) == 1)
|
|
thread = threads[0]
|
|
|
|
#
|
|
# At this point, myObserver has a Source pointer that is actually a KVO swizzled SourceDerived
|
|
# make sure we can get that properly:
|
|
|
|
frame = thread.GetFrameAtIndex(0)
|
|
myObserver = frame.FindVariable('myObserver', lldb.eDynamicCanRunTarget)
|
|
self.assertTrue (myObserver)
|
|
myObserver_source = myObserver.GetChildMemberWithName ('_source', lldb.eDynamicCanRunTarget)
|
|
self.examine_SourceDerived_ptr (myObserver_source)
|
|
|
|
# The "frame var" code uses another path to get into children, so let's
|
|
# make sure that works as well:
|
|
|
|
result = lldb.SBCommandReturnObject()
|
|
|
|
self.expect('frame var -d run-target myObserver->_source', 'frame var finds its way into a child member',
|
|
patterns = ['\(SourceDerived \*\)'])
|
|
|
|
# This test is not entirely related to the main thrust of this test case, but since we're here,
|
|
# try stepping into setProperty, and make sure we get into the version in Source:
|
|
|
|
thread.StepInto()
|
|
|
|
threads = lldbutil.get_stopped_threads (process, lldb.eStopReasonPlanComplete)
|
|
self.assertTrue (len(threads) == 1)
|
|
line_entry = threads[0].GetFrameAtIndex(0).GetLineEntry()
|
|
self.assertTrue (line_entry.GetLine() == self.set_property_line)
|
|
self.assertTrue (line_entry.GetFileSpec().GetFilename() == self.source_name)
|
|
|
|
# Okay, back to the main business. Continue to the handle_SourceBase and make sure we get the correct dynamic value.
|
|
|
|
threads = lldbutil.continue_to_breakpoint (process, handle_SourceBase_bkpt)
|
|
self.assertTrue (len(threads) == 1)
|
|
thread = threads[0]
|
|
|
|
frame = thread.GetFrameAtIndex(0)
|
|
|
|
# Get "object" using FindVariable:
|
|
|
|
noDynamic = lldb.eNoDynamicValues
|
|
useDynamic = lldb.eDynamicCanRunTarget
|
|
|
|
object_static = frame.FindVariable ('object', noDynamic)
|
|
object_dynamic = frame.FindVariable ('object', useDynamic)
|
|
|
|
# Delete this object to make sure that this doesn't cause havoc with the dynamic object that depends on it.
|
|
del (object_static)
|
|
|
|
self.examine_SourceDerived_ptr (object_dynamic)
|
|
|
|
# Get "this" using FindValue, make sure that works too:
|
|
object_static = frame.FindValue ('object', lldb.eValueTypeVariableArgument, noDynamic)
|
|
object_dynamic = frame.FindValue ('object', lldb.eValueTypeVariableArgument, useDynamic)
|
|
del (object_static)
|
|
self.examine_SourceDerived_ptr (object_dynamic)
|
|
|
|
# Get "this" using the EvaluateExpression:
|
|
# These tests fail for now because EvaluateExpression doesn't currently support dynamic typing...
|
|
#object_static = frame.EvaluateExpression ('object', noDynamic)
|
|
#object_dynamic = frame.EvaluateExpression ('object', useDynamic)
|
|
#self.examine_value_object_of_object_ptr (object_static, object_dynamic, myB_loc)
|
|
|
|
# Continue again to the handle_SourceBase and make sure we get the correct dynamic value.
|
|
# This one looks exactly the same, but in fact this is an "un-KVO'ed" version of SourceBase, so
|
|
# its isa pointer points to SourceBase not NSKVOSourceBase or whatever...
|
|
|
|
threads = lldbutil.continue_to_breakpoint (process, handle_SourceBase_bkpt)
|
|
self.assertTrue (len(threads) == 1)
|
|
thread = threads[0]
|
|
|
|
frame = thread.GetFrameAtIndex(0)
|
|
|
|
# Get "object" using FindVariable:
|
|
|
|
object_static = frame.FindVariable ('object', noDynamic)
|
|
object_dynamic = frame.FindVariable ('object', useDynamic)
|
|
|
|
# Delete this object to make sure that this doesn't cause havoc with the dynamic object that depends on it.
|
|
del (object_static)
|
|
|
|
self.examine_SourceDerived_ptr (object_dynamic)
|
|
|
|
if __name__ == '__main__':
|
|
import atexit
|
|
lldb.SBDebugger.Initialize()
|
|
atexit.register(lambda: lldb.SBDebugger.Terminate())
|
|
unittest2.main()
|