forked from OSchip/llvm-project
Add logic to SBValue.linked_list_iter() to detect infinite loop and to bail out early.
Add code to test case to create an evil linked list with: task_evil -> task_2 -> task_3 -> task_evil ... and to check that the linked list iterator only iterates 3 times. llvm-svn: 137291
This commit is contained in:
parent
e6d0c86297
commit
e1894cf97c
|
@ -112,6 +112,8 @@ linked_list_iter_def = '''
|
|||
end-of-list test function which takes an SBValue for an item and returns
|
||||
True if EOL is reached and False if not.
|
||||
|
||||
linked_list_iter() also detects infinite loop and bails out early.
|
||||
|
||||
The end_of_list_test arg, if omitted, defaults to the __eol_test__
|
||||
function above.
|
||||
|
||||
|
@ -130,8 +132,10 @@ linked_list_iter_def = '''
|
|||
if end_of_list_test(self):
|
||||
return
|
||||
item = self
|
||||
visited = set()
|
||||
try:
|
||||
while not end_of_list_test(item):
|
||||
while not end_of_list_test(item) and not item.GetValueAsUnsigned() in visited:
|
||||
visited.add(item.GetValueAsUnsigned())
|
||||
yield item
|
||||
# Prepare for the next iteration.
|
||||
item = item.GetChildMemberWithName(next_item_name)
|
||||
|
|
|
@ -127,6 +127,20 @@ class ValueAsLinkedListTestCase(TestBase):
|
|||
|
||||
self.assertTrue(len(list) == 0)
|
||||
|
||||
# Get variable 'task_evil'.
|
||||
task_evil = frame0.FindVariable('task_evil')
|
||||
self.assertTrue(task_evil, VALID_VARIABLE)
|
||||
self.DebugSBValue(task_evil)
|
||||
|
||||
list = []
|
||||
# There 3 iterable items from task_evil.linked_list_iter(). :-)
|
||||
for t in task_evil.linked_list_iter('next'):
|
||||
if self.TraceOn():
|
||||
print cvf.format(t)
|
||||
list.append(int(t.GetChildMemberWithName("id").GetValue()))
|
||||
|
||||
self.assertTrue(len(list) == 3)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import atexit
|
||||
lldb.SBDebugger.Initialize()
|
||||
|
|
|
@ -45,5 +45,12 @@ int main (int argc, char const *argv[])
|
|||
// This corresponds to an empty task list.
|
||||
Task *empty_task_head = NULL;
|
||||
|
||||
Task *task_evil = new Task(1, NULL);
|
||||
Task *task_2 = new Task(2, NULL);
|
||||
Task *task_3 = new Task(3, NULL);
|
||||
task_evil->next = task_2;
|
||||
task_2->next = task_3;
|
||||
task_3->next = task_evil; // In order to cause inifinite loop. :-)
|
||||
|
||||
return 0; // Break at this line
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue