diff --git a/lldb/scripts/Python/modify-python-lldb.py b/lldb/scripts/Python/modify-python-lldb.py index a6e86c25d569..382509039c95 100644 --- a/lldb/scripts/Python/modify-python-lldb.py +++ b/lldb/scripts/Python/modify-python-lldb.py @@ -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) diff --git a/lldb/test/python_api/value/linked_list/TestValueAPILinkedList.py b/lldb/test/python_api/value/linked_list/TestValueAPILinkedList.py index f07ed1b1de27..2d820cbfe091 100644 --- a/lldb/test/python_api/value/linked_list/TestValueAPILinkedList.py +++ b/lldb/test/python_api/value/linked_list/TestValueAPILinkedList.py @@ -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() diff --git a/lldb/test/python_api/value/linked_list/main.cpp b/lldb/test/python_api/value/linked_list/main.cpp index de812178fdd6..50517f487749 100644 --- a/lldb/test/python_api/value/linked_list/main.cpp +++ b/lldb/test/python_api/value/linked_list/main.cpp @@ -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 }