aboutsummaryrefslogtreecommitdiff
path: root/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list
diff options
context:
space:
mode:
Diffstat (limited to 'packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list')
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py186
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/TestDataFormatterLibcxxListLoop.py54
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/main.cpp30
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/main.cpp43
6 files changed, 327 insertions, 0 deletions
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/Makefile
new file mode 100644
index 000000000000..1f609a41d908
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/Makefile
@@ -0,0 +1,7 @@
+LEVEL = ../../../../../make
+
+CXX_SOURCES := main.cpp
+
+USE_LIBCPP := 1
+include $(LEVEL)/Makefile.rules
+CXXFLAGS += -O0
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py
new file mode 100644
index 000000000000..18ee31a86106
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py
@@ -0,0 +1,186 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time, re
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class LibcxxListDataFormatterTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.cpp', '// Set break point at this line.')
+ self.line2 = line_number('main.cpp', '// Set second break point at this line.')
+ self.line3 = line_number('main.cpp', '// Set third break point at this line.')
+ self.line4 = line_number('main.cpp', '// Set fourth break point at this line.')
+
+ @skipIfGcc
+ @skipIfWindows # libc++ not ported to Windows yet
+ def test_with_run_command(self):
+ """Test that that file and class static variables display correctly."""
+ self.build()
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1)
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line2, num_expected_locations=-1)
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line3, num_expected_locations=-1)
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line4, num_expected_locations=-1)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ lldbutil.skip_if_library_missing(self, self.target(), lldbutil.PrintableRegex("libc\+\+"))
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # This is the function to remove the custom formats in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('type format clear', check=False)
+ self.runCmd('type summary clear', check=False)
+ self.runCmd('type filter clear', check=False)
+ self.runCmd('type synth clear', check=False)
+ self.runCmd("settings set target.max-children-count 256", check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.runCmd("frame variable numbers_list --show-types")
+ self.runCmd("type summary add std::int_list std::string_list int_list string_list --summary-string \"list has ${svar%#} items\" -e")
+ self.runCmd("type format add -f hex int")
+
+ self.expect("frame variable numbers_list --raw", matching=False,
+ substrs = ['list has 0 items',
+ '{}'])
+
+ self.expect("frame variable numbers_list",
+ substrs = ['list has 0 items',
+ '{}'])
+
+ self.expect("p numbers_list",
+ substrs = ['list has 0 items',
+ '{}'])
+
+ self.runCmd("n")
+
+ self.expect("frame variable numbers_list",
+ substrs = ['list has 1 items',
+ '[0] = ',
+ '0x12345678'])
+
+ self.runCmd("n");self.runCmd("n");self.runCmd("n");
+
+ self.expect("frame variable numbers_list",
+ substrs = ['list has 4 items',
+ '[0] = ',
+ '0x12345678',
+ '[1] =',
+ '0x11223344',
+ '[2] =',
+ '0xbeeffeed',
+ '[3] =',
+ '0x00abba00'])
+
+ self.runCmd("n");self.runCmd("n");
+
+ self.expect("frame variable numbers_list",
+ substrs = ['list has 6 items',
+ '[0] = ',
+ '0x12345678',
+ '0x11223344',
+ '0xbeeffeed',
+ '0x00abba00',
+ '[4] =',
+ '0x0abcdef0',
+ '[5] =',
+ '0x0cab0cab'])
+
+ self.expect("p numbers_list",
+ substrs = ['list has 6 items',
+ '[0] = ',
+ '0x12345678',
+ '0x11223344',
+ '0xbeeffeed',
+ '0x00abba00',
+ '[4] =',
+ '0x0abcdef0',
+ '[5] =',
+ '0x0cab0cab'])
+
+ # check access-by-index
+ self.expect("frame variable numbers_list[0]",
+ substrs = ['0x12345678']);
+ self.expect("frame variable numbers_list[1]",
+ substrs = ['0x11223344']);
+
+ self.runCmd("n")
+
+ self.expect("frame variable numbers_list",
+ substrs = ['list has 0 items',
+ '{}'])
+
+ self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");
+
+ self.expect("frame variable numbers_list",
+ substrs = ['list has 4 items',
+ '[0] = ', '1',
+ '[1] = ', '2',
+ '[2] = ', '3',
+ '[3] = ', '4'])
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(self.frame().FindVariable("numbers_list").MightHaveChildren(), "numbers_list.MightHaveChildren() says False for non empty!")
+
+ self.runCmd("type format delete int")
+
+ self.runCmd("c")
+
+ self.expect("frame variable text_list",
+ substrs = ['list has 3 items',
+ '[0]', 'goofy',
+ '[1]', 'is',
+ '[2]', 'smart'])
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(self.frame().FindVariable("text_list").MightHaveChildren(), "text_list.MightHaveChildren() says False for non empty!")
+
+ self.expect("p text_list",
+ substrs = ['list has 3 items',
+ '\"goofy\"',
+ '\"is\"',
+ '\"smart\"'])
+
+ self.runCmd("n")
+
+ # check access-by-index
+ self.expect("frame variable text_list[0]",
+ substrs = ['goofy']);
+ self.expect("frame variable text_list[3]",
+ substrs = ['!!!']);
+
+ self.runCmd("continue")
+
+ # check that the list provider correctly updates if elements move
+ countingList = self.frame().FindVariable("countingList")
+ countingList.SetPreferDynamicValue(True)
+ countingList.SetPreferSyntheticValue(True)
+
+ self.assertTrue(countingList.GetChildAtIndex(0).GetValueAsUnsigned(0) == 3141, "list[0] == 3141")
+ self.assertTrue(countingList.GetChildAtIndex(1).GetValueAsUnsigned(0) == 3141, "list[1] == 3141")
+
+ self.runCmd("continue")
+
+ self.assertTrue(countingList.GetChildAtIndex(0).GetValueAsUnsigned(0) == 3141, "uniqued list[0] == 3141")
+ self.assertTrue(countingList.GetChildAtIndex(1).GetValueAsUnsigned(0) == 3142, "uniqued list[1] == 3142")
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/Makefile
new file mode 100644
index 000000000000..a5dabdb6349d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/Makefile
@@ -0,0 +1,7 @@
+LEVEL = ../../../../../../make
+
+CXX_SOURCES := main.cpp
+
+USE_LIBCPP := 1
+include $(LEVEL)/Makefile.rules
+CXXFLAGS += -O0
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/TestDataFormatterLibcxxListLoop.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/TestDataFormatterLibcxxListLoop.py
new file mode 100644
index 000000000000..167cb2b887af
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/TestDataFormatterLibcxxListLoop.py
@@ -0,0 +1,54 @@
+"""
+Test that the debugger handles loops in std::list (which can appear as a result of e.g. memory
+corruption).
+"""
+
+from __future__ import print_function
+
+
+
+import os, time, re
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class LibcxxListDataFormatterTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipIfGcc
+ @skipIfWindows # libc++ not ported to Windows yet
+ @add_test_categories(["pyapi"])
+ def test_with_run_command(self):
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target and target.IsValid(), "Target is valid")
+
+ file_spec = lldb.SBFileSpec ("main.cpp", False)
+ breakpoint1 = target.BreakpointCreateBySourceRegex('// Set break point at this line.', file_spec)
+ self.assertTrue(breakpoint1 and breakpoint1.IsValid())
+ breakpoint2 = target.BreakpointCreateBySourceRegex('// Set second break point at this line.', file_spec)
+ self.assertTrue(breakpoint2 and breakpoint2.IsValid())
+
+ # Run the program, it should stop at breakpoint 1.
+ process = target.LaunchSimple(None, None, self.get_process_working_directory())
+ lldbutil.skip_if_library_missing(self, target, lldbutil.PrintableRegex("libc\+\+"))
+ self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID)
+ self.assertEqual(len(lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint1)), 1)
+
+ # verify our list is displayed correctly
+ self.expect("frame variable *numbers_list", substrs=['[0] = 1', '[1] = 2', '[2] = 3', '[3] = 4', '[5] = 6'])
+
+ # Continue to breakpoint 2.
+ process.Continue()
+ self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID)
+ self.assertEqual(len(lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint2)), 1)
+
+ # The list is now inconsistent. However, we should be able to get the first three
+ # elements at least (and most importantly, not crash).
+ self.expect("frame variable *numbers_list", substrs=['[0] = 1', '[1] = 2', '[2] = 3'])
+
+ # Run to completion.
+ process.Continue()
+ self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/main.cpp
new file mode 100644
index 000000000000..6a1266528d5e
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/main.cpp
@@ -0,0 +1,30 @@
+// Evil hack: To simulate memory corruption, we want to fiddle with some internals of std::list.
+// Make those accessible to us.
+#define private public
+#define protected public
+
+#ifdef _LIBCPP_INLINE_VISIBILITY
+#undef _LIBCPP_INLINE_VISIBILITY
+#endif
+#define _LIBCPP_INLINE_VISIBILITY
+#include <list>
+
+#include <assert.h>
+
+typedef std::list<int> int_list;
+
+int main()
+{
+#ifdef LLDB_USING_LIBCPP
+ int_list *numbers_list = new int_list{1,2,3,4,5,6,7,8,9,10};
+
+ auto *third_elem = numbers_list->__end_.__next_->__next_->__next_; // Set break point at this line.
+ assert(third_elem->__value_ == 3);
+ auto *fifth_elem = third_elem->__next_->__next_;
+ assert(fifth_elem->__value_ == 5);
+ fifth_elem->__next_ = third_elem;
+#endif
+
+ // Any attempt to free the list will probably crash the program. Let's just leak it.
+ return 0; // Set second break point at this line.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/main.cpp
new file mode 100644
index 000000000000..4f2bd74495a9
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/main.cpp
@@ -0,0 +1,43 @@
+#include <string>
+#ifdef _LIBCPP_INLINE_VISIBILITY
+#undef _LIBCPP_INLINE_VISIBILITY
+#endif
+#define _LIBCPP_INLINE_VISIBILITY
+#include <list>
+
+
+typedef std::list<int> int_list;
+typedef std::list<std::string> string_list;
+
+int main()
+{
+ int_list numbers_list;
+
+ (numbers_list.push_back(0x12345678)); // Set break point at this line.
+ (numbers_list.push_back(0x11223344));
+ (numbers_list.push_back(0xBEEFFEED));
+ (numbers_list.push_back(0x00ABBA00));
+ (numbers_list.push_back(0x0ABCDEF0));
+ (numbers_list.push_back(0x0CAB0CAB));
+
+ numbers_list.clear();
+
+ (numbers_list.push_back(1));
+ (numbers_list.push_back(2));
+ (numbers_list.push_back(3));
+ (numbers_list.push_back(4));
+
+ string_list text_list;
+ (text_list.push_back(std::string("goofy")));
+ (text_list.push_back(std::string("is")));
+ (text_list.push_back(std::string("smart")));
+
+ (text_list.push_back(std::string("!!!"))); // Set second break point at this line.
+
+ std::list<int> countingList = {3141, 3142, 3142,3142,3142, 3142, 3142, 3141};
+ countingList.sort();
+ countingList.unique(); // Set third break point at this line.
+ countingList.size(); // Set fourth break point at this line.
+
+ return 0;
+}