2 Test SBValue API linked_list_iter which treats the SBValue as a linked list and
3 supports iteration till the end of list is reached.
7 from lldbsuite
.test
.decorators
import *
8 from lldbsuite
.test
.lldbtest
import *
9 from lldbsuite
.test
import lldbutil
12 class ValueAsLinkedListTestCase(TestBase
):
13 NO_DEBUG_INFO_TESTCASE
= True
16 # Call super's setUp().
18 # We'll use the test method name as the exe_name.
19 self
.exe_name
= self
.testMethodName
20 # Find the line number to break at.
21 self
.line
= line_number("main.cpp", "// Break at this line")
24 """Exercise SBValue API linked_list_iter."""
25 d
= {"EXE": self
.exe_name
}
26 self
.build(dictionary
=d
)
27 self
.setTearDownCleanup(dictionary
=d
)
28 exe
= self
.getBuildArtifact(self
.exe_name
)
30 # Create a target by the debugger.
31 target
= self
.dbg
.CreateTarget(exe
)
32 self
.assertTrue(target
, VALID_TARGET
)
34 # Create the breakpoint inside function 'main'.
35 breakpoint
= target
.BreakpointCreateByLocation("main.cpp", self
.line
)
36 self
.assertTrue(breakpoint
, VALID_BREAKPOINT
)
38 # Now launch the process, and do not stop at entry point.
39 process
= target
.LaunchSimple(None, None, self
.get_process_working_directory())
40 self
.assertTrue(process
, PROCESS_IS_VALID
)
43 self
.assertState(process
.GetState(), lldb
.eStateStopped
)
44 thread
= lldbutil
.get_stopped_thread(process
, lldb
.eStopReasonBreakpoint
)
47 "There should be a thread stopped due to breakpoint condition",
49 frame0
= thread
.GetFrameAtIndex(0)
51 # Get variable 'task_head'.
52 task_head
= frame0
.FindVariable("task_head")
53 self
.assertTrue(task_head
, VALID_VARIABLE
)
54 self
.DebugSBValue(task_head
)
56 # By design (see main.cpp), the visited id's are: [1, 2, 4, 5].
57 visitedIDs
= [1, 2, 4, 5]
60 cvf
= lldbutil
.ChildVisitingFormatter(indent_child
=2)
61 for t
in task_head
.linked_list_iter("next"):
62 self
.assertTrue(t
, VALID_VARIABLE
)
63 # Make sure that 'next' corresponds to an SBValue with pointer
65 self
.assertTrue(t
.TypeIsPointerType())
68 list.append(int(t
.GetChildMemberWithName("id").GetValue()))
70 # Sanity checks that the we visited all the items (no more, no less).
72 print("visited IDs:", list)
73 self
.assertEqual(visitedIDs
, list)
75 # Let's exercise the linked_list_iter() API again, this time supplying
76 # our end of list test function.
78 """Test function to determine end of list."""
79 # End of list is reached if either the value object is invalid
80 # or it corresponds to a null pointer.
81 if not val
or int(val
.GetValue(), 16) == 0:
83 # Also check the "id" for correct semantics. If id <= 0, the item
84 # is corrupted, let's return True to signify end of list.
85 if int(val
.GetChildMemberWithName("id").GetValue(), 0) <= 0:
88 # Otherwise, return False.
92 for t
in task_head
.linked_list_iter("next", eol
):
93 self
.assertTrue(t
, VALID_VARIABLE
)
94 # Make sure that 'next' corresponds to an SBValue with pointer
96 self
.assertTrue(t
.TypeIsPointerType())
99 list.append(int(t
.GetChildMemberWithName("id").GetValue()))
101 # Sanity checks that the we visited all the items (no more, no less).
103 print("visited IDs:", list)
104 self
.assertEqual(visitedIDs
, list)
106 # Get variable 'empty_task_head'.
107 empty_task_head
= frame0
.FindVariable("empty_task_head")
108 self
.assertTrue(empty_task_head
, VALID_VARIABLE
)
109 self
.DebugSBValue(empty_task_head
)
112 # There is no iterable item from empty_task_head.linked_list_iter().
113 for t
in empty_task_head
.linked_list_iter("next", eol
):
116 list.append(int(t
.GetChildMemberWithName("id").GetValue()))
118 self
.assertEqual(len(list), 0)
120 # Get variable 'task_evil'.
121 task_evil
= frame0
.FindVariable("task_evil")
122 self
.assertTrue(task_evil
, VALID_VARIABLE
)
123 self
.DebugSBValue(task_evil
)
126 # There 3 iterable items from task_evil.linked_list_iter(). :-)
127 for t
in task_evil
.linked_list_iter("next"):
130 list.append(int(t
.GetChildMemberWithName("id").GetValue()))
132 self
.assertEqual(len(list), 3)