aboutsummaryrefslogtreecommitdiff
path: root/packages/Python/lldbsuite/test/functionalities
diff options
context:
space:
mode:
Diffstat (limited to 'packages/Python/lldbsuite/test/functionalities')
-rw-r--r--packages/Python/lldbsuite/test/functionalities/abbreviation/.categories1
-rw-r--r--packages/Python/lldbsuite/test/functionalities/abbreviation/TestAbbreviations.py101
-rw-r--r--packages/Python/lldbsuite/test/functionalities/abbreviation/TestCommonShortSpellings.py39
-rw-r--r--packages/Python/lldbsuite/test/functionalities/alias/.categories1
-rw-r--r--packages/Python/lldbsuite/test/functionalities/archives/Makefile9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/archives/README62
-rw-r--r--packages/Python/lldbsuite/test/functionalities/archives/TestBSDArchives.py57
-rw-r--r--packages/Python/lldbsuite/test/functionalities/archives/a.c19
-rw-r--r--packages/Python/lldbsuite/test/functionalities/archives/b.c19
-rw-r--r--packages/Python/lldbsuite/test/functionalities/archives/main.c17
-rw-r--r--packages/Python/lldbsuite/test/functionalities/asan/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/asan/TestMemoryHistory.py103
-rw-r--r--packages/Python/lldbsuite/test/functionalities/asan/TestReportData.py79
-rw-r--r--packages/Python/lldbsuite/test/functionalities/asan/main.c34
-rw-r--r--packages/Python/lldbsuite/test/functionalities/attach_resume/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/attach_resume/TestAttachResume.py73
-rw-r--r--packages/Python/lldbsuite/test/functionalities/attach_resume/main.cpp50
-rw-r--r--packages/Python/lldbsuite/test/functionalities/avoids-fd-leak/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/avoids-fd-leak/TestFdLeak.py78
-rw-r--r--packages/Python/lldbsuite/test/functionalities/avoids-fd-leak/main.c28
-rw-r--r--packages/Python/lldbsuite/test/functionalities/backticks/.categories1
-rw-r--r--packages/Python/lldbsuite/test/functionalities/backticks/TestBackticksWithoutATarget.py21
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/TestAddressBreakpoints.py91
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/main.c8
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py206
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommandsFromPython.py95
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestRegexpBreakCommand.py51
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/a.c9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/b.c9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/bktptcmd.py6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/main.c13
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/TestBreakpointConditions.py181
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/main.c54
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ids/Makefile9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ids/TestBreakpointIDs.py51
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ids/main.cpp65
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py136
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/main.c54
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/TestBreakpointLanguage.py85
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/a.c5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/b.cpp5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/main.cpp11
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/Makefile9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py88
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/main.c43
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/TestBreakpointOptions.py93
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/foo.cpp12
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/main.cpp8
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/TestCompDirSymLink.py63
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/main.cpp13
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/Makefile9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/TestConsecutiveBreakpoints.py59
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/main.cpp19
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/Makefile9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/TestCPPBreakpointLocations.py62
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/main.cpp77
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/TestCPPExceptionBreakpoint.py48
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/main.cpp13
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/dummy_target_breakpoints/Makefile9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/dummy_target_breakpoints/TestBreakpointsWithNoTargets.py67
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/dummy_target_breakpoints/main.c11
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/TestInlinedBreakpoints.py57
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/basic_type.cpp178
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/int.cpp9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/objc/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/objc/TestObjCBreakpoints.py94
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/objc/main.m98
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_history/.categories1
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_history/TestCommandHistory.py68
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_regex/.categories1
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_regex/TestCommandRegex.py56
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/.categories1
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/TestCommandScript.py142
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/bug11569.py7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/import/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/import/TestImport.py73
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/import/bar/bar.py12
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/import/bar/barutil.py2
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/import/dummymodule.py2
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/import/foo/bar/foobar.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/import/foo/foo.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/import/foo/foo2.py9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/import/main.c15
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/import/rdar-12586188/Makefile3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/import/rdar-12586188/TestRdar12586188.py31
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/import/rdar-12586188/fail12586188.py4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/import/rdar-12586188/fail212586188.py4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/import/thepackage/TPunitA.py6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/import/thepackage/TPunitB.py6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/import/thepackage/__init__.py6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/main.cpp70
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/mysto.py23
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/py_import12
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/welcome.py46
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_source/.categories1
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_source/.lldb1
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_source/TestCommandSource.py36
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_source/my.py6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/completion/.categories1
-rw-r--r--packages/Python/lldbsuite/test/functionalities/completion/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py324
-rw-r--r--packages/Python/lldbsuite/test/functionalities/completion/main.cpp14
-rw-r--r--packages/Python/lldbsuite/test/functionalities/conditional_break/.lldb3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/conditional_break/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/conditional_break/TestConditionalBreak.py133
-rw-r--r--packages/Python/lldbsuite/test/functionalities/conditional_break/conditional_break.py30
-rw-r--r--packages/Python/lldbsuite/test/functionalities/conditional_break/main.c54
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/.categories1
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/Makefile9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/TestFormattersBoolRefPtr.py72
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/main.mm29
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/compactvectors/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/compactvectors/TestCompactVectors.py58
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/compactvectors/main.cpp26
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-advanced/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py285
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-advanced/main.cpp174
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-categories/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py329
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-categories/main.cpp46
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-cpp/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py265
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-cpp/main.cpp121
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-disabling/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-disabling/TestDataFormatterDisabling.py80
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-disabling/main.cpp18
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-enum-format/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-enum-format/TestDataFormatterEnumFormat.py65
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-enum-format/main.cpp13
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-globals/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-globals/TestDataFormatterGlobals.py67
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-globals/main.cpp27
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-named-summaries/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py122
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-named-summaries/main.cpp59
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/.categories1
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/Makefile9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py464
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/main.m694
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/nsstring/Makefile9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/nsstring/TestDataFormatterNSString.py107
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/nsstring/main.m99
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/Makefile9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/TestFormattersOneIsSingular.py90
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/main.m42
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-ptr-to-array/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-ptr-to-array/TestPtrToArrayFormatting.py57
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-ptr-to-array/main.cpp17
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py252
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py23
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/ftsp.py32
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp66
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-script/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py170
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-script/main.cpp53
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/Makefile19
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py175
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/main.cpp57
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-smart-array/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py348
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-smart-array/main.cpp65
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/Makefile4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/TestInitializerList.py40
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/main.cpp21
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/TestDataFormatterLibccIterator.py66
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/main.cpp42
-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
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py298
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/main.cpp77
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/TestDataFormatterLibccMultiMap.py298
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/main.cpp77
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/TestDataFormatterLibcxxMultiSet.py69
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/main.cpp57
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/TestDataFormatterLibcxxSet.py69
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/main.cpp57
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py86
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/main.cpp15
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/TestDataFormatterUnordered.py75
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/main.cpp84
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/TestDataFormatterLibcxxVBool.py58
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/main.cpp69
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py180
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/main.cpp35
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/Makefile15
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/TestDataFormatterStdIterator.py62
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/main.cpp38
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/Makefile15
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py188
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/main.cpp34
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/Makefile14
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py322
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/main.cpp55
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/Makefile15
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/TestDataFormatterStdString.py66
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/main.cpp12
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile8
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py58
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/main.cpp63
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/Makefile15
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py207
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/main.cpp31
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synth/Makefile12
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py205
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synth/main.cpp86
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py96
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/main.cpp29
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/myIntSynthProvider.py36
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/dump_dynamic/Makefile12
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/dump_dynamic/TestDumpDynamic.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/dump_dynamic/main.cpp35
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/format-propagation/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/format-propagation/TestFormatPropagation.py75
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/format-propagation/main.cpp13
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/frameformat_smallstruct/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/frameformat_smallstruct/TestFrameFormatSmallStruct.py38
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/frameformat_smallstruct/main.cpp25
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/hexcaps/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/hexcaps/TestDataFormatterHexCaps.py82
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/hexcaps/main.cpp28
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/language_category_updates/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/language_category_updates/TestDataFormatterLanguageCategoryUpdates.py60
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/language_category_updates/main.cpp20
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/nsarraysynth/Makefile9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/nsarraysynth/TestNSArraySynthetic.py67
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/nsarraysynth/main.m35
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/nsdictionarysynth/Makefile9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/nsdictionarysynth/TestNSDictionarySynthetic.py69
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/nsdictionarysynth/main.m30
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/nssetsynth/Makefile9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/nssetsynth/TestNSSetSynthetic.py74
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/nssetsynth/main.m34
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/ostypeformatting/Makefile9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/ostypeformatting/TestFormattersOsType.py52
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/ostypeformatting/main.mm23
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/ptr_ref_typedef/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/ptr_ref_typedef/TestPtrRef2Typedef.py57
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/ptr_ref_typedef/main.cpp19
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/refpointer-recursion/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/refpointer-recursion/TestDataFormatterRefPtrRecursion.py41
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/refpointer-recursion/main.cpp21
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/setvaluefromcstring/Makefile4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/setvaluefromcstring/TestSetValueFromCString.py4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/setvaluefromcstring/main.m19
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/stringprinter/Makefile12
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/stringprinter/TestStringPrinter.py4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/stringprinter/main.cpp40
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/summary-string-onfail/Makefile12
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/summary-string-onfail/Test-rdar-9974002.py133
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/summary-string-onfail/main.cpp30
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/TestSyntheticCapping.py75
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/fooSynthProvider.py21
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/main.cpp62
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/synthupdate/Makefile12
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/synthupdate/TestSyntheticFilterRecompute.py74
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/synthupdate/main.m25
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/typedef_array/Makefile4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/typedef_array/TestTypedefArray.py4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/typedef_array/main.cpp14
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/user-format-vs-summary/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/user-format-vs-summary/TestUserFormatVsSummary.py59
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/user-format-vs-summary/main.cpp20
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/var-in-aggregate-misuse/Makefile11
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/var-in-aggregate-misuse/TestVarInAggregateMisuse.py74
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/var-in-aggregate-misuse/main.cpp41
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/TestDataFormatterVarScriptFormatting.py56
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/helperfunc.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/main.cpp8
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/vector-types/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/vector-types/TestVectorTypesFormatting.py73
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/vector-types/main.cpp17
-rw-r--r--packages/Python/lldbsuite/test/functionalities/dead-strip/Makefile18
-rw-r--r--packages/Python/lldbsuite/test/functionalities/dead-strip/TestDeadStrip.py58
-rw-r--r--packages/Python/lldbsuite/test/functionalities/dead-strip/cmds.txt4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/dead-strip/main.c53
-rw-r--r--packages/Python/lldbsuite/test/functionalities/disassembly/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/disassembly/TestDisassembleBreakpoint.py54
-rw-r--r--packages/Python/lldbsuite/test/functionalities/disassembly/main.cpp28
-rw-r--r--packages/Python/lldbsuite/test/functionalities/dynamic_value_child_count/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/dynamic_value_child_count/TestDynamicValueChildCount.py78
-rw-r--r--packages/Python/lldbsuite/test/functionalities/dynamic_value_child_count/pass-to-base.cpp36
-rw-r--r--packages/Python/lldbsuite/test/functionalities/embedded_interpreter/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/embedded_interpreter/TestConvenienceVariables.py78
-rw-r--r--packages/Python/lldbsuite/test/functionalities/embedded_interpreter/main.c6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/exec/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/exec/TestExec.py85
-rw-r--r--packages/Python/lldbsuite/test/functionalities/exec/main.cpp94
-rw-r--r--packages/Python/lldbsuite/test/functionalities/expr-doesnt-deadlock/.categories1
-rw-r--r--packages/Python/lldbsuite/test/functionalities/expr-doesnt-deadlock/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/expr-doesnt-deadlock/TestExprDoesntBlock.py57
-rw-r--r--packages/Python/lldbsuite/test/functionalities/expr-doesnt-deadlock/locking.c80
-rw-r--r--packages/Python/lldbsuite/test/functionalities/fat_archives/Makefile14
-rw-r--r--packages/Python/lldbsuite/test/functionalities/fat_archives/TestFatArchives.py58
-rw-r--r--packages/Python/lldbsuite/test/functionalities/fat_archives/a.c4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/fat_archives/a.h1
-rw-r--r--packages/Python/lldbsuite/test/functionalities/fat_archives/main.c6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/format/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/format/TestFormats.py59
-rw-r--r--packages/Python/lldbsuite/test/functionalities/format/main.c15
-rw-r--r--packages/Python/lldbsuite/test/functionalities/inferior-assert/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/inferior-assert/TestInferiorAssert.py253
-rw-r--r--packages/Python/lldbsuite/test/functionalities/inferior-assert/main.c19
-rw-r--r--packages/Python/lldbsuite/test/functionalities/inferior-changed/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/inferior-changed/TestInferiorChanged.py80
-rw-r--r--packages/Python/lldbsuite/test/functionalities/inferior-changed/main.c16
-rw-r--r--packages/Python/lldbsuite/test/functionalities/inferior-changed/main2.c18
-rw-r--r--packages/Python/lldbsuite/test/functionalities/inferior-crashing/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/inferior-crashing/TestInferiorCrashing.py220
-rw-r--r--packages/Python/lldbsuite/test/functionalities/inferior-crashing/main.c18
-rw-r--r--packages/Python/lldbsuite/test/functionalities/inferior-crashing/recursive-inferior/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/inferior-crashing/recursive-inferior/TestRecursiveInferior.py220
-rw-r--r--packages/Python/lldbsuite/test/functionalities/inferior-crashing/recursive-inferior/main.c19
-rw-r--r--packages/Python/lldbsuite/test/functionalities/inline-stepping/Makefile9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/inline-stepping/TestInlineStepping.py270
-rw-r--r--packages/Python/lldbsuite/test/functionalities/inline-stepping/calling.cpp136
-rw-r--r--packages/Python/lldbsuite/test/functionalities/jitloader_gdb/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/jitloader_gdb/TestJITLoaderGDB.py37
-rw-r--r--packages/Python/lldbsuite/test/functionalities/jitloader_gdb/main.c44
-rw-r--r--packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/TestLaunchWithShellExpand.py97
-rw-r--r--packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/file1.txt0
-rw-r--r--packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/file2.txt0
-rw-r--r--packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/file3.txt0
-rw-r--r--packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/file4.txy0
-rw-r--r--packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/file5.tyx0
-rw-r--r--packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/foo bar0
-rw-r--r--packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/main.cpp5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/load_unload/Makefile24
-rw-r--r--packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py357
-rw-r--r--packages/Python/lldbsuite/test/functionalities/load_unload/a.cpp22
-rw-r--r--packages/Python/lldbsuite/test/functionalities/load_unload/a.mk23
-rw-r--r--packages/Python/lldbsuite/test/functionalities/load_unload/b.cpp21
-rw-r--r--packages/Python/lldbsuite/test/functionalities/load_unload/b.mk11
-rw-r--r--packages/Python/lldbsuite/test/functionalities/load_unload/c.cpp13
-rw-r--r--packages/Python/lldbsuite/test/functionalities/load_unload/c.mk11
-rw-r--r--packages/Python/lldbsuite/test/functionalities/load_unload/cmds.txt2
-rw-r--r--packages/Python/lldbsuite/test/functionalities/load_unload/d.cpp21
-rw-r--r--packages/Python/lldbsuite/test/functionalities/load_unload/d.mk13
-rw-r--r--packages/Python/lldbsuite/test/functionalities/load_unload/hidden/Makefile11
-rw-r--r--packages/Python/lldbsuite/test/functionalities/load_unload/hidden/d.cpp21
-rw-r--r--packages/Python/lldbsuite/test/functionalities/load_unload/main.cpp80
-rw-r--r--packages/Python/lldbsuite/test/functionalities/longjmp/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/longjmp/TestLongjmp.py85
-rw-r--r--packages/Python/lldbsuite/test/functionalities/longjmp/main.c31
-rw-r--r--packages/Python/lldbsuite/test/functionalities/memory/read/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/memory/read/TestMemoryRead.py99
-rw-r--r--packages/Python/lldbsuite/test/functionalities/memory/read/main.cpp19
-rw-r--r--packages/Python/lldbsuite/test/functionalities/non-overlapping-index-variable-i/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/non-overlapping-index-variable-i/TestIndexVariable.py43
-rw-r--r--packages/Python/lldbsuite/test/functionalities/non-overlapping-index-variable-i/main.cpp51
-rw-r--r--packages/Python/lldbsuite/test/functionalities/nosucharch/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/nosucharch/TestNoSuchArch.py29
-rw-r--r--packages/Python/lldbsuite/test/functionalities/nosucharch/main.cpp3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/object-file/TestImageListMultiArchitecture.py41
-rw-r--r--packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-freebsd-10.0-x86_64-clang-3.3bin0 -> 7477 bytes
-rw-r--r--packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-freebsd-10.0-x86_64-gcc-4.7.3bin0 -> 7520 bytes
-rw-r--r--packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-netbsd-6.1-x86_64-gcc-4.5.3bin0 -> 7352 bytes
-rw-r--r--packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-ubuntu-14.04-x86_64-clang-3.5prebin0 -> 8112 bytes
-rw-r--r--packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-ubuntu-14.04-x86_64-gcc-4.8.2bin0 -> 8056 bytes
-rw-r--r--packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-unknown-kalimba_arch4-kcc-36bin0 -> 17224 bytes
-rw-r--r--packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-unknown-kalimba_arch5-kcc-39bin0 -> 28356 bytes
-rw-r--r--packages/Python/lldbsuite/test/functionalities/object-file/bin/hello.c8
-rw-r--r--packages/Python/lldbsuite/test/functionalities/object-file/bin/hello.cpp8
-rw-r--r--packages/Python/lldbsuite/test/functionalities/paths/TestPaths.py48
-rw-r--r--packages/Python/lldbsuite/test/functionalities/platform/TestPlatformCommand.py65
-rw-r--r--packages/Python/lldbsuite/test/functionalities/plugins/commands/Makefile8
-rw-r--r--packages/Python/lldbsuite/test/functionalities/plugins/commands/TestPluginCommands.py58
-rw-r--r--packages/Python/lldbsuite/test/functionalities/plugins/commands/plugin.cpp62
-rw-r--r--packages/Python/lldbsuite/test/functionalities/plugins/python_os_plugin/Makefile3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/plugins/python_os_plugin/TestPythonOSPlugin.py150
-rw-r--r--packages/Python/lldbsuite/test/functionalities/plugins/python_os_plugin/main.c7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/plugins/python_os_plugin/operating_system.py90
-rw-r--r--packages/Python/lldbsuite/test/functionalities/plugins/python_os_plugin/operating_system2.py88
-rw-r--r--packages/Python/lldbsuite/test/functionalities/postmortem/minidump/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py128
-rw-r--r--packages/Python/lldbsuite/test/functionalities/postmortem/minidump/fizzbuzz.cpp31
-rw-r--r--packages/Python/lldbsuite/test/functionalities/postmortem/minidump/fizzbuzz_no_heap.dmpbin0 -> 6297 bytes
-rw-r--r--packages/Python/lldbsuite/test/functionalities/postmortem/minidump/main.cpp21
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_attach/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_attach/TestProcessAttach.py58
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_attach/attach_denied/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_attach/attach_denied/TestAttachDenied.py60
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_attach/attach_denied/main.cpp108
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_attach/main.cpp37
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_group/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_group/TestChangeProcessGroup.py107
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_group/main.c86
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_launch/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_launch/TestProcessLaunch.py207
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_launch/input-file.txt2
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_launch/main.cpp17
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_launch/my_working_dir/.keep0
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_launch/print_cwd.cpp21
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_launch/print_env.cpp11
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_save_core/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_save_core/TestProcessSaveCore.py58
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_save_core/main.cpp21
-rw-r--r--packages/Python/lldbsuite/test/functionalities/recursion/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/recursion/TestValueObjectRecursion.py59
-rw-r--r--packages/Python/lldbsuite/test/functionalities/recursion/main.cpp41
-rw-r--r--packages/Python/lldbsuite/test/functionalities/register/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/register/TestRegisters.py349
-rw-r--r--packages/Python/lldbsuite/test/functionalities/register/a.cpp44
-rw-r--r--packages/Python/lldbsuite/test/functionalities/register/main.cpp51
-rw-r--r--packages/Python/lldbsuite/test/functionalities/rerun/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/rerun/TestRerun.py76
-rw-r--r--packages/Python/lldbsuite/test/functionalities/rerun/main.cpp5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/return-value/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py214
-rw-r--r--packages/Python/lldbsuite/test/functionalities/return-value/call-func.c407
-rw-r--r--packages/Python/lldbsuite/test/functionalities/set-data/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/set-data/TestSetData.py62
-rw-r--r--packages/Python/lldbsuite/test/functionalities/set-data/main.m19
-rw-r--r--packages/Python/lldbsuite/test/functionalities/signal/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/signal/TestSendSignal.py105
-rw-r--r--packages/Python/lldbsuite/test/functionalities/signal/handle-segv/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/signal/handle-segv/TestHandleSegv.py43
-rw-r--r--packages/Python/lldbsuite/test/functionalities/signal/handle-segv/main.c58
-rw-r--r--packages/Python/lldbsuite/test/functionalities/signal/main.c27
-rw-r--r--packages/Python/lldbsuite/test/functionalities/signal/raise/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/signal/raise/TestRaise.py221
-rw-r--r--packages/Python/lldbsuite/test/functionalities/signal/raise/main.c42
-rw-r--r--packages/Python/lldbsuite/test/functionalities/single-quote-in-filename-to-lldb/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/single-quote-in-filename-to-lldb/TestSingleQuoteInFilename.py71
-rw-r--r--packages/Python/lldbsuite/test/functionalities/single-quote-in-filename-to-lldb/main.c7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/single-quote-in-filename-to-lldb/path with '09/.keep0
-rw-r--r--packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/Makefile8
-rw-r--r--packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/TestStepNoDebug.py113
-rw-r--r--packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/with-debug.c29
-rw-r--r--packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/without-debug.c17
-rw-r--r--packages/Python/lldbsuite/test/functionalities/stop-hook/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookCmd.py65
-rw-r--r--packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookMechanism.py101
-rw-r--r--packages/Python/lldbsuite/test/functionalities/stop-hook/main.cpp54
-rw-r--r--packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py77
-rw-r--r--packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/main.cpp77
-rw-r--r--packages/Python/lldbsuite/test/functionalities/target_command/Makefile8
-rw-r--r--packages/Python/lldbsuite/test/functionalities/target_command/TestTargetCommand.py201
-rw-r--r--packages/Python/lldbsuite/test/functionalities/target_command/a.c16
-rw-r--r--packages/Python/lldbsuite/test/functionalities/target_command/b.c13
-rw-r--r--packages/Python/lldbsuite/test/functionalities/target_command/c.c29
-rw-r--r--packages/Python/lldbsuite/test/functionalities/target_command/globals.c25
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/TestNumThreads.py53
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/Makefile6
-rwxr-xr-xpackages/Python/lldbsuite/test/functionalities/thread/backtrace_all/ParallelTask.cpp151
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/TestBacktraceAll.py57
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/break_after_join/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/break_after_join/TestBreakAfterJoin.py77
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/break_after_join/main.cpp118
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentEvents.py491
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/main.cpp200
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/Makefile4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/TestCrashDuringStep.py53
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/main.cpp16
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/TestCreateAfterAttach.py122
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/main.cpp78
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/create_during_step/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/create_during_step/TestCreateDuringStep.py127
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/create_during_step/main.cpp89
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/TestExitDuringBreak.py81
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/main.cpp130
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py144
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/main.cpp87
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/jump/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/jump/TestThreadJump.py60
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/jump/main.cpp35
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/jump/other.cpp13
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/main.cpp50
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/multi_break/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/multi_break/TestMultipleBreakpoints.py77
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/multi_break/main.cpp61
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/state/Makefile4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/state/TestThreadStates.py333
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/state/main.cpp45
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/step_out/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py131
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/step_out/main.cpp63
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/thread_exit/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py116
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/thread_exit/main.cpp85
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/TestThreadSpecificBreakpoint.py63
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/main.cpp20
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/TestThreadSpecificBpPlusCondition.py65
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/main.cpp39
-rw-r--r--packages/Python/lldbsuite/test/functionalities/tty/TestTerminal.py40
-rw-r--r--packages/Python/lldbsuite/test/functionalities/type_completion/Makefile12
-rw-r--r--packages/Python/lldbsuite/test/functionalities/type_completion/TestTypeCompletion.py108
-rw-r--r--packages/Python/lldbsuite/test/functionalities/type_completion/main.cpp81
-rw-r--r--packages/Python/lldbsuite/test/functionalities/type_lookup/Makefile9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/type_lookup/TestTypeLookup.py43
-rw-r--r--packages/Python/lldbsuite/test/functionalities/type_lookup/main.m16
-rw-r--r--packages/Python/lldbsuite/test/functionalities/unwind/noreturn/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/unwind/noreturn/TestNoreturnUnwind.py76
-rw-r--r--packages/Python/lldbsuite/test/functionalities/unwind/noreturn/main.c37
-rw-r--r--packages/Python/lldbsuite/test/functionalities/unwind/sigtramp/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/unwind/sigtramp/TestSigtrampUnwind.py81
-rw-r--r--packages/Python/lldbsuite/test/functionalities/unwind/sigtramp/main.c27
-rw-r--r--packages/Python/lldbsuite/test/functionalities/unwind/standard/Makefile3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/unwind/standard/TestStandardUnwind.py145
-rw-r--r--packages/Python/lldbsuite/test/functionalities/unwind/standard/hand_written/divmod.cpp15
-rw-r--r--packages/Python/lldbsuite/test/functionalities/unwind/standard/hand_written/fprintf.cpp16
-rw-r--r--packages/Python/lldbsuite/test/functionalities/unwind/standard/hand_written/new_delete.cpp15
-rw-r--r--packages/Python/lldbsuite/test/functionalities/value_md5_crash/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/value_md5_crash/TestValueMD5Crash.py52
-rw-r--r--packages/Python/lldbsuite/test/functionalities/value_md5_crash/main.cpp29
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/TestWatchLocation.py98
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/main.cpp106
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchpoint/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchpoint/TestMyFirstWatchpoint.py84
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchpoint/main.c30
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/TestWatchpointMultipleThreads.py137
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/main.cpp83
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/TestStepOverWatchpoint.py113
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/main.c19
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/variable_out_of_scope/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/variable_out_of_scope/TestWatchedVarHitWhenInScope.py83
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/variable_out_of_scope/main.c15
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/TestWatchpointCommands.py313
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py139
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py87
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/main.cpp28
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/condition/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/condition/TestWatchpointConditionCmd.py78
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/condition/main.cpp28
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/main.c24
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_events/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_events/TestWatchpointEvents.py89
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_events/main.c9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/TestValueOfVectorVariable.py47
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/main.c16
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/TestWatchLocationWithWatchSet.py89
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py67
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/main.cpp121
575 files changed, 29006 insertions, 0 deletions
diff --git a/packages/Python/lldbsuite/test/functionalities/abbreviation/.categories b/packages/Python/lldbsuite/test/functionalities/abbreviation/.categories
new file mode 100644
index 000000000000..3a3f4df6416b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/abbreviation/.categories
@@ -0,0 +1 @@
+cmdline
diff --git a/packages/Python/lldbsuite/test/functionalities/abbreviation/TestAbbreviations.py b/packages/Python/lldbsuite/test/functionalities/abbreviation/TestAbbreviations.py
new file mode 100644
index 000000000000..1bce5bed491f
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/abbreviation/TestAbbreviations.py
@@ -0,0 +1,101 @@
+"""
+Test some lldb command abbreviations and aliases for proper resolution.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class AbbreviationsTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFlakeyFreeBSD("llvm.org/pr22611 thread race condition breaks prompt setting")
+ @no_debug_info_test
+ def test_command_abbreviations_and_aliases (self):
+ command_interpreter = self.dbg.GetCommandInterpreter()
+ self.assertTrue(command_interpreter, VALID_COMMAND_INTERPRETER)
+ result = lldb.SBCommandReturnObject()
+
+ # Check that abbreviations are expanded to the full command.
+ command_interpreter.ResolveCommand("ap script", result)
+ self.assertTrue(result.Succeeded())
+ self.assertEqual("apropos script", result.GetOutput())
+
+ command_interpreter.ResolveCommand("h", result)
+ self.assertTrue(result.Succeeded())
+ self.assertEqual("help", result.GetOutput())
+
+ # Check resolution of abbreviations for multi-word commands.
+ command_interpreter.ResolveCommand("lo li", result)
+ self.assertTrue(result.Succeeded())
+ self.assertEqual("log list", result.GetOutput())
+
+ command_interpreter.ResolveCommand("br s", result)
+ self.assertTrue(result.Succeeded())
+ self.assertEqual("breakpoint set", result.GetOutput())
+
+ # Try an ambiguous abbreviation.
+ # "pl" could be "platform" or "plugin".
+ command_interpreter.ResolveCommand("pl", result)
+ self.assertFalse(result.Succeeded())
+ self.assertTrue(result.GetError().startswith("Ambiguous command"))
+
+ # Make sure an unabbreviated command is not mangled.
+ command_interpreter.ResolveCommand("breakpoint set --name main --line 123", result)
+ self.assertTrue(result.Succeeded())
+ self.assertEqual("breakpoint set --name main --line 123", result.GetOutput())
+
+ # Create some aliases.
+ self.runCmd("com a alias com al")
+ self.runCmd("alias gurp help")
+
+ # Check that an alias is replaced with the actual command
+ command_interpreter.ResolveCommand("gurp target create", result)
+ self.assertTrue(result.Succeeded())
+ self.assertEqual("help target create", result.GetOutput())
+
+ # Delete the alias and make sure it no longer has an effect.
+ self.runCmd("com u gurp")
+ command_interpreter.ResolveCommand("gurp", result)
+ self.assertFalse(result.Succeeded())
+
+ # Check aliases with text replacement.
+ self.runCmd("alias pltty process launch -s -o %1 -e %1")
+ command_interpreter.ResolveCommand("pltty /dev/tty0", result)
+ self.assertTrue(result.Succeeded())
+ self.assertEqual("process launch -s -o /dev/tty0 -e /dev/tty0", result.GetOutput())
+
+ self.runCmd("alias xyzzy breakpoint set -n %1 -l %2")
+ command_interpreter.ResolveCommand("xyzzy main 123", result)
+ self.assertTrue(result.Succeeded())
+ self.assertEqual("breakpoint set -n main -l 123", result.GetOutput().strip())
+
+ # And again, without enough parameters.
+ command_interpreter.ResolveCommand("xyzzy main", result)
+ self.assertFalse(result.Succeeded())
+
+ # Check a command that wants the raw input.
+ command_interpreter.ResolveCommand(r'''sc print("\n\n\tHello!\n")''', result)
+ self.assertTrue(result.Succeeded())
+ self.assertEqual(r'''script print("\n\n\tHello!\n")''', result.GetOutput())
+
+ # Prompt changing stuff should be tested, but this doesn't seem like the
+ # right test to do it in. It has nothing to do with aliases or abbreviations.
+ #self.runCmd("com sou ./change_prompt.lldb")
+ #self.expect("settings show prompt",
+ # startstr = 'prompt (string) = "[with-three-trailing-spaces] "')
+ #self.runCmd("settings clear prompt")
+ #self.expect("settings show prompt",
+ # startstr = 'prompt (string) = "(lldb) "')
+ #self.runCmd("se se prompt 'Sycamore> '")
+ #self.expect("se sh prompt",
+ # startstr = 'prompt (string) = "Sycamore> "')
+ #self.runCmd("se cl prompt")
+ #self.expect("set sh prompt",
+ # startstr = 'prompt (string) = "(lldb) "')
diff --git a/packages/Python/lldbsuite/test/functionalities/abbreviation/TestCommonShortSpellings.py b/packages/Python/lldbsuite/test/functionalities/abbreviation/TestCommonShortSpellings.py
new file mode 100644
index 000000000000..9edbf212278c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/abbreviation/TestCommonShortSpellings.py
@@ -0,0 +1,39 @@
+"""
+Test some lldb command abbreviations to make sure the common short spellings of
+many commands remain available even after we add/delete commands in the future.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class CommonShortSpellingsTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @no_debug_info_test
+ def test_abbrevs2 (self):
+ command_interpreter = self.dbg.GetCommandInterpreter()
+ self.assertTrue(command_interpreter, VALID_COMMAND_INTERPRETER)
+ result = lldb.SBCommandReturnObject()
+
+ abbrevs = [
+ ('br s', 'breakpoint set'),
+ ('disp', '_regexp-display'), # a.k.a., 'display'
+ ('di', 'disassemble'),
+ ('dis', 'disassemble'),
+ ('ta st a', 'target stop-hook add'),
+ ('fr v', 'frame variable'),
+ ('f 1', 'frame select 1'),
+ ('ta st li', 'target stop-hook list'),
+ ]
+
+ for (short_val, long_val) in abbrevs:
+ command_interpreter.ResolveCommand(short_val, result)
+ self.assertTrue(result.Succeeded())
+ self.assertEqual(long_val, result.GetOutput())
diff --git a/packages/Python/lldbsuite/test/functionalities/alias/.categories b/packages/Python/lldbsuite/test/functionalities/alias/.categories
new file mode 100644
index 000000000000..3a3f4df6416b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/alias/.categories
@@ -0,0 +1 @@
+cmdline
diff --git a/packages/Python/lldbsuite/test/functionalities/archives/Makefile b/packages/Python/lldbsuite/test/functionalities/archives/Makefile
new file mode 100644
index 000000000000..64da83becbda
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/archives/Makefile
@@ -0,0 +1,9 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+MAKE_DSYM := NO
+ARCHIVE_NAME := libfoo.a
+ARCHIVE_C_SOURCES := a.c b.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/archives/README b/packages/Python/lldbsuite/test/functionalities/archives/README
new file mode 100644
index 000000000000..d327f4585c67
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/archives/README
@@ -0,0 +1,62 @@
+a.out file refers to libfoo.a for a.o and b.o, which is what we want to accomplish for
+this test case.
+
+[16:17:44] johnny:/Volumes/data/lldb/svn/latest/test/functionalities/archives $ dsymutil -s a.out
+----------------------------------------------------------------------
+Symbol table for: 'a.out' (x86_64)
+----------------------------------------------------------------------
+Index n_strx n_type n_sect n_desc n_value
+======== -------- ------------------ ------ ------ ----------------
+[ 0] 00000002 64 (N_SO ) 00 0000 0000000000000000 '/Volumes/data/lldb/svn/latest/test/functionalities/archives/'
+[ 1] 0000003f 64 (N_SO ) 00 0000 0000000000000000 'main.c'
+[ 2] 00000046 66 (N_OSO ) 03 0001 000000004f0f780c '/Volumes/data/lldb/svn/latest/test/functionalities/archives/main.o'
+[ 3] 00000001 2e (N_BNSYM ) 01 0000 0000000100000d70
+[ 4] 00000089 24 (N_FUN ) 01 0000 0000000100000d70 '_main'
+[ 5] 00000001 24 (N_FUN ) 00 0000 000000000000005d
+[ 6] 00000001 4e (N_ENSYM ) 01 0000 000000000000005d
+[ 7] 00000001 64 (N_SO ) 01 0000 0000000000000000
+[ 8] 00000002 64 (N_SO ) 00 0000 0000000000000000 '/Volumes/data/lldb/svn/latest/test/functionalities/archives/'
+[ 9] 0000008f 64 (N_SO ) 00 0000 0000000000000000 'a.c'
+[ 10] 00000093 66 (N_OSO ) 03 0001 000000004f0f780c '/Volumes/data/lldb/svn/latest/test/functionalities/archives/libfoo.a(a.o)'
+[ 11] 00000001 2e (N_BNSYM ) 01 0000 0000000100000dd0
+[ 12] 000000dd 24 (N_FUN ) 01 0000 0000000100000dd0 '_a'
+[ 13] 00000001 24 (N_FUN ) 00 0000 0000000000000020
+[ 14] 00000001 4e (N_ENSYM ) 01 0000 0000000000000020
+[ 15] 00000001 2e (N_BNSYM ) 01 0000 0000000100000df0
+[ 16] 000000e0 24 (N_FUN ) 01 0000 0000000100000df0 '_aa'
+[ 17] 00000001 24 (N_FUN ) 00 0000 0000000000000018
+[ 18] 00000001 4e (N_ENSYM ) 01 0000 0000000000000018
+[ 19] 000000e4 20 (N_GSYM ) 00 0000 0000000000000000 '___a_global'
+[ 20] 00000001 64 (N_SO ) 01 0000 0000000000000000
+[ 21] 00000002 64 (N_SO ) 00 0000 0000000000000000 '/Volumes/data/lldb/svn/latest/test/functionalities/archives/'
+[ 22] 000000f0 64 (N_SO ) 00 0000 0000000000000000 'b.c'
+[ 23] 000000f4 66 (N_OSO ) 03 0001 000000004f0f780c '/Volumes/data/lldb/svn/latest/test/functionalities/archives/libfoo.a(b.o)'
+[ 24] 00000001 2e (N_BNSYM ) 01 0000 0000000100000e10
+[ 25] 0000013e 24 (N_FUN ) 01 0000 0000000100000e10 '_b'
+[ 26] 00000001 24 (N_FUN ) 00 0000 0000000000000020
+[ 27] 00000001 4e (N_ENSYM ) 01 0000 0000000000000020
+[ 28] 00000001 2e (N_BNSYM ) 01 0000 0000000100000e30
+[ 29] 00000141 24 (N_FUN ) 01 0000 0000000100000e30 '_bb'
+[ 30] 00000001 24 (N_FUN ) 00 0000 0000000000000018
+[ 31] 00000001 4e (N_ENSYM ) 01 0000 0000000000000018
+[ 32] 00000145 26 (N_STSYM ) 0a 0000 000000010000104c '___b_global'
+[ 33] 00000001 64 (N_SO ) 01 0000 0000000000000000
+[ 34] 00000151 0e ( SECT ) 07 0000 0000000100001000 '_pvars'
+[ 35] 00000158 0e ( SECT ) 0a 0000 000000010000104c '___b_global'
+[ 36] 00000164 0f ( SECT EXT) 0b 0000 0000000100001050 '_NXArgc'
+[ 37] 0000016c 0f ( SECT EXT) 0b 0000 0000000100001058 '_NXArgv'
+[ 38] 00000174 0f ( SECT EXT) 0a 0000 0000000100001048 '___a_global'
+[ 39] 00000180 0f ( SECT EXT) 0b 0000 0000000100001068 '___progname'
+[ 40] 0000018c 03 ( ABS EXT) 01 0010 0000000100000000 '__mh_execute_header'
+[ 41] 000001a0 0f ( SECT EXT) 01 0000 0000000100000dd0 '_a'
+[ 42] 000001a3 0f ( SECT EXT) 01 0000 0000000100000df0 '_aa'
+[ 43] 000001a7 0f ( SECT EXT) 01 0000 0000000100000e10 '_b'
+[ 44] 000001aa 0f ( SECT EXT) 01 0000 0000000100000e30 '_bb'
+[ 45] 000001ae 0f ( SECT EXT) 0b 0000 0000000100001060 '_environ'
+[ 46] 000001b7 0f ( SECT EXT) 01 0000 0000000100000d70 '_main'
+[ 47] 000001bd 0f ( SECT EXT) 01 0000 0000000100000d30 'start'
+[ 48] 000001c3 01 ( UNDF EXT) 00 0100 0000000000000000 '_exit'
+[ 49] 000001c9 01 ( UNDF EXT) 00 0100 0000000000000000 '_printf'
+[ 50] 000001d1 01 ( UNDF EXT) 00 0100 0000000000000000 'dyld_stub_binder'
+
+
diff --git a/packages/Python/lldbsuite/test/functionalities/archives/TestBSDArchives.py b/packages/Python/lldbsuite/test/functionalities/archives/TestBSDArchives.py
new file mode 100644
index 000000000000..02e1b9551853
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/archives/TestBSDArchives.py
@@ -0,0 +1,57 @@
+"""Test breaking inside functions defined within a BSD archive file libfoo.a."""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class BSDArchivesTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number in a(int) to break at.
+ self.line = line_number('a.c', '// Set file and line breakpoint inside a().')
+
+ @expectedFailureWindows("llvm.org/pr24527") # Makefile.rules doesn't know how to build static libs on Windows.
+ def test(self):
+ """Break inside a() and b() defined within libfoo.a."""
+ self.build()
+
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Break inside a() by file and line first.
+ lldbutil.run_break_set_by_file_and_line (self, "a.c", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Break at a(int) first.
+ self.expect("frame variable", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['(int) arg = 1'])
+ self.expect("frame variable __a_global", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['(int) __a_global = 1'])
+
+ # Set breakpoint for b() next.
+ lldbutil.run_break_set_by_symbol (self, "b", num_expected_locations=1, sym_exact=True)
+
+ # Continue the program, we should break at b(int) next.
+ self.runCmd("continue")
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+ self.expect("frame variable", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['(int) arg = 2'])
+ self.expect("frame variable __b_global", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['(int) __b_global = 2'])
diff --git a/packages/Python/lldbsuite/test/functionalities/archives/a.c b/packages/Python/lldbsuite/test/functionalities/archives/a.c
new file mode 100644
index 000000000000..2b6ebbe47a76
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/archives/a.c
@@ -0,0 +1,19 @@
+//===-- a.c -----------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+int __a_global = 1;
+
+int a(int arg) {
+ int result = arg + __a_global;
+ return result; // Set file and line breakpoint inside a().
+}
+
+int aa(int arg1) {
+ int result1 = arg1 - __a_global;
+ return result1;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/archives/b.c b/packages/Python/lldbsuite/test/functionalities/archives/b.c
new file mode 100644
index 000000000000..51d77dd4bcdc
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/archives/b.c
@@ -0,0 +1,19 @@
+//===-- b.c -----------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+static int __b_global = 2;
+
+int b(int arg) {
+ int result = arg + __b_global;
+ return result;
+}
+
+int bb(int arg1) {
+ int result2 = arg1 - __b_global;
+ return result2;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/archives/main.c b/packages/Python/lldbsuite/test/functionalities/archives/main.c
new file mode 100644
index 000000000000..c5b1cc2f0d1c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/archives/main.c
@@ -0,0 +1,17 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+extern int a(int);
+extern int b(int);
+int main (int argc, char const *argv[])
+{
+ printf ("a(1) returns %d\n", a(1));
+ printf ("b(2) returns %d\n", b(2));
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/asan/Makefile b/packages/Python/lldbsuite/test/functionalities/asan/Makefile
new file mode 100644
index 000000000000..26654a023ed1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/asan/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+CFLAGS_EXTRAS := -fsanitize=address -g
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/asan/TestMemoryHistory.py b/packages/Python/lldbsuite/test/functionalities/asan/TestMemoryHistory.py
new file mode 100644
index 000000000000..e92b967d8adf
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/asan/TestMemoryHistory.py
@@ -0,0 +1,103 @@
+"""
+Test that ASan memory history provider returns correct stack traces
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class AsanTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureLinux # non-core functionality, need to reenable and fix later (DES 2014.11.07)
+ @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
+ @skipIfRemote
+ @skipUnlessCompilerRt
+ @expectedFailureDarwin
+ def test (self):
+ self.build ()
+ self.asan_tests ()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ self.line_malloc = line_number('main.c', '// malloc line')
+ self.line_malloc2 = line_number('main.c', '// malloc2 line')
+ self.line_free = line_number('main.c', '// free line')
+ self.line_breakpoint = line_number('main.c', '// break line')
+
+ def asan_tests (self):
+ exe = os.path.join (os.getcwd(), "a.out")
+ self.expect("file " + exe, patterns = [ "Current executable set to .*a.out" ])
+
+ self.runCmd("breakpoint set -f main.c -l %d" % self.line_breakpoint)
+
+ # "memory history" command should not work without a process
+ self.expect("memory history 0",
+ error = True,
+ substrs = ["invalid process"])
+
+ self.runCmd("run")
+
+ # ASan will relaunch the process to insert its library.
+ self.expect("thread list", "Process should be stopped due to exec.",
+ substrs = ['stopped', 'stop reason = '])
+
+ self.runCmd("continue")
+
+ # the stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped', 'stop reason = breakpoint'])
+
+ # test that the ASan dylib is present
+ self.expect("image lookup -n __asan_describe_address", "__asan_describe_address should be present",
+ substrs = ['1 match found'])
+
+ # test the 'memory history' command
+ self.expect("memory history 'pointer'",
+ substrs = [
+ 'Memory allocated at', 'a.out`f1', 'main.c:%d' % self.line_malloc,
+ 'Memory deallocated at', 'a.out`f2', 'main.c:%d' % self.line_free])
+
+ # do the same using SB API
+ process = self.dbg.GetSelectedTarget().process
+ val = process.GetSelectedThread().GetSelectedFrame().EvaluateExpression("pointer")
+ addr = val.GetValueAsUnsigned()
+ threads = process.GetHistoryThreads(addr);
+ self.assertEqual(threads.GetSize(), 2)
+
+ history_thread = threads.GetThreadAtIndex(0)
+ self.assertTrue(history_thread.num_frames >= 2)
+ self.assertEqual(history_thread.frames[1].GetLineEntry().GetFileSpec().GetFilename(), "main.c")
+ self.assertEqual(history_thread.frames[1].GetLineEntry().GetLine(), self.line_free)
+
+ history_thread = threads.GetThreadAtIndex(1)
+ self.assertTrue(history_thread.num_frames >= 2)
+ self.assertEqual(history_thread.frames[1].GetLineEntry().GetFileSpec().GetFilename(), "main.c")
+ self.assertEqual(history_thread.frames[1].GetLineEntry().GetLine(), self.line_malloc)
+
+ # let's free the container (SBThreadCollection) and see if the SBThreads still live
+ threads = None
+ self.assertTrue(history_thread.num_frames >= 2)
+ self.assertEqual(history_thread.frames[1].GetLineEntry().GetFileSpec().GetFilename(), "main.c")
+ self.assertEqual(history_thread.frames[1].GetLineEntry().GetLine(), self.line_malloc)
+
+ # now let's break when an ASan report occurs and try the API then
+ self.runCmd("breakpoint set -n __asan_report_error")
+
+ self.runCmd("continue")
+
+ # the stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped', 'stop reason = breakpoint'])
+
+ # make sure the 'memory history' command still works even when we're generating a report now
+ self.expect("memory history 'another_pointer'",
+ substrs = [
+ 'Memory allocated at', 'a.out`f1', 'main.c:%d' % self.line_malloc2])
diff --git a/packages/Python/lldbsuite/test/functionalities/asan/TestReportData.py b/packages/Python/lldbsuite/test/functionalities/asan/TestReportData.py
new file mode 100644
index 000000000000..4ef587895196
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/asan/TestReportData.py
@@ -0,0 +1,79 @@
+"""
+Test the AddressSanitizer runtime support for report breakpoint and data extraction.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+import json
+
+class AsanTestReportDataCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureLinux # non-core functionality, need to reenable and fix later (DES 2014.11.07)
+ @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
+ @skipIfRemote
+ @skipUnlessCompilerRt
+ @expectedFailureDarwin
+ def test(self):
+ self.build ()
+ self.asan_tests ()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ self.line_malloc = line_number('main.c', '// malloc line')
+ self.line_malloc2 = line_number('main.c', '// malloc2 line')
+ self.line_free = line_number('main.c', '// free line')
+ self.line_breakpoint = line_number('main.c', '// break line')
+ self.line_crash = line_number('main.c', '// BOOM line')
+
+ def asan_tests (self):
+ exe = os.path.join (os.getcwd(), "a.out")
+ self.expect("file " + exe, patterns = [ "Current executable set to .*a.out" ])
+ self.runCmd("run")
+
+ # ASan will relaunch the process to insert its library.
+ self.expect("thread list", "Process should be stopped due to exec.",
+ substrs = ['stopped', 'stop reason = '])
+
+ # no extended info when we have no ASan report
+ thread = self.dbg.GetSelectedTarget().process.GetSelectedThread()
+ s = lldb.SBStream()
+ self.assertFalse(thread.GetStopReasonExtendedInfoAsJSON(s))
+
+ self.runCmd("continue")
+
+ self.expect("thread list", "Process should be stopped due to ASan report",
+ substrs = ['stopped', 'stop reason = Use of deallocated memory detected'])
+
+ self.assertEqual(self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason(), lldb.eStopReasonInstrumentation)
+
+ self.expect("bt", "The backtrace should show the crashing line",
+ substrs = ['main.c:%d' % self.line_crash])
+
+ self.expect("thread info -s", "The extended stop info should contain the ASan provided fields",
+ substrs = ["access_size", "access_type", "address", "pc", "description", "heap-use-after-free"])
+
+ output_lines = self.res.GetOutput().split('\n')
+ json_line = output_lines[2]
+ data = json.loads(json_line)
+ self.assertEqual(data["description"], "heap-use-after-free")
+ self.assertEqual(data["instrumentation_class"], "AddressSanitizer")
+ self.assertEqual(data["stop_type"], "fatal_error")
+
+ # now let's try the SB API
+ process = self.dbg.GetSelectedTarget().process
+ thread = process.GetSelectedThread()
+
+ s = lldb.SBStream()
+ self.assertTrue(thread.GetStopReasonExtendedInfoAsJSON(s))
+ s = s.GetData()
+ data2 = json.loads(s)
+ self.assertEqual(data, data2)
diff --git a/packages/Python/lldbsuite/test/functionalities/asan/main.c b/packages/Python/lldbsuite/test/functionalities/asan/main.c
new file mode 100644
index 000000000000..fab760e49f00
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/asan/main.c
@@ -0,0 +1,34 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+#include <stdlib.h>
+
+char *pointer;
+char *another_pointer;
+
+void f1() {
+ pointer = malloc(10); // malloc line
+ another_pointer = malloc(20); // malloc2 line
+}
+
+void f2() {
+ free(pointer); // free line
+}
+
+int main (int argc, char const *argv[])
+{
+ f1();
+ f2();
+
+ printf("Hello world!\n"); // break line
+
+ pointer[0] = 'A'; // BOOM line
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/attach_resume/Makefile b/packages/Python/lldbsuite/test/functionalities/attach_resume/Makefile
new file mode 100644
index 000000000000..13d40a13b3e3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/attach_resume/Makefile
@@ -0,0 +1,7 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+ENABLE_THREADS := YES
+EXE := AttachResume
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/attach_resume/TestAttachResume.py b/packages/Python/lldbsuite/test/functionalities/attach_resume/TestAttachResume.py
new file mode 100644
index 000000000000..693c0a70fd62
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/attach_resume/TestAttachResume.py
@@ -0,0 +1,73 @@
+"""
+Test process attach/resume.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+exe_name = "AttachResume" # Must match Makefile
+
+class AttachResumeTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipIfRemote
+ @expectedFailureFreeBSD('llvm.org/pr19310')
+ @expectedFailureWindows("llvm.org/pr24778")
+ def test_attach_continue_interrupt_detach(self):
+ """Test attach/continue/interrupt/detach"""
+ self.build()
+ self.process_attach_continue_interrupt_detach()
+
+ def process_attach_continue_interrupt_detach(self):
+ """Test attach/continue/interrupt/detach"""
+
+ exe = os.path.join(os.getcwd(), exe_name)
+
+ popen = self.spawnSubprocess(exe)
+ self.addTearDownHook(self.cleanupSubprocesses)
+
+ self.runCmd("process attach -p " + str(popen.pid))
+
+ self.setAsync(True)
+ listener = self.dbg.GetListener()
+
+ self.runCmd("c")
+ lldbutil.expect_state_changes(self, listener, [lldb.eStateRunning])
+
+ self.runCmd("process interrupt")
+ lldbutil.expect_state_changes(self, listener, [lldb.eStateStopped])
+
+ # be sure to continue/interrupt/continue (r204504)
+ self.runCmd("c")
+ lldbutil.expect_state_changes(self, listener, [lldb.eStateRunning])
+
+ self.runCmd("process interrupt")
+ lldbutil.expect_state_changes(self, listener, [lldb.eStateStopped])
+
+ # Second interrupt should have no effect.
+ self.expect("process interrupt", patterns=["Process is not running"], error=True)
+
+ # check that this breakpoint is auto-cleared on detach (r204752)
+ self.runCmd("br set -f main.cpp -l %u" % (line_number('main.cpp', '// Set breakpoint here')))
+
+ self.runCmd("c")
+ lldbutil.expect_state_changes(self, listener, [lldb.eStateRunning, lldb.eStateStopped])
+ self.expect('br list', 'Breakpoint not hit',
+ substrs = ['hit count = 1'])
+
+ # Make sure the breakpoint is not hit again.
+ self.expect("expr debugger_flag = false", substrs=[" = false"]);
+
+ self.runCmd("c")
+ lldbutil.expect_state_changes(self, listener, [lldb.eStateRunning])
+
+ # make sure to detach while in running state (r204759)
+ self.runCmd("detach")
+ lldbutil.expect_state_changes(self, listener, [lldb.eStateDetached])
diff --git a/packages/Python/lldbsuite/test/functionalities/attach_resume/main.cpp b/packages/Python/lldbsuite/test/functionalities/attach_resume/main.cpp
new file mode 100644
index 000000000000..7cf360258546
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/attach_resume/main.cpp
@@ -0,0 +1,50 @@
+#include <stdio.h>
+#include <fcntl.h>
+
+#include <chrono>
+#include <thread>
+
+#if defined(__linux__)
+#include <sys/prctl.h>
+#endif
+
+volatile bool debugger_flag = true; // The debugger will flip this to false
+
+void *start(void *data)
+{
+ int i;
+ size_t idx = (size_t)data;
+ for (i=0; i<30; i++)
+ {
+ if ( idx == 0 && debugger_flag)
+ std::this_thread::sleep_for(std::chrono::microseconds(1)); // Set breakpoint here
+ std::this_thread::sleep_for(std::chrono::seconds(1));
+ }
+ return 0;
+}
+
+int main(int argc, char const *argv[])
+{
+#if defined(__linux__)
+ // Immediately enable any ptracer so that we can allow the stub attach
+ // operation to succeed. Some Linux kernels are locked down so that
+ // only an ancestor process can be a ptracer of a process. This disables that
+ // restriction. Without it, attach-related stub tests will fail.
+#if defined(PR_SET_PTRACER) && defined(PR_SET_PTRACER_ANY)
+ // For now we execute on best effort basis. If this fails for
+ // some reason, so be it.
+ const int prctl_result = prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0);
+ static_cast<void> (prctl_result);
+#endif
+#endif
+
+ static const size_t nthreads = 16;
+ std::thread threads[nthreads];
+ size_t i;
+
+ for (i=0; i<nthreads; i++)
+ threads[i] = std::move(std::thread(start, (void*)i));
+
+ for (i=0; i<nthreads; i++)
+ threads[i].join();
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/avoids-fd-leak/Makefile b/packages/Python/lldbsuite/test/functionalities/avoids-fd-leak/Makefile
new file mode 100644
index 000000000000..0d70f2595019
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/avoids-fd-leak/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/avoids-fd-leak/TestFdLeak.py b/packages/Python/lldbsuite/test/functionalities/avoids-fd-leak/TestFdLeak.py
new file mode 100644
index 000000000000..e4bc08711f4c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/avoids-fd-leak/TestFdLeak.py
@@ -0,0 +1,78 @@
+"""
+Test whether a process started by lldb has no extra file descriptors open.
+"""
+
+from __future__ import print_function
+
+
+
+import os
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+
+def python_leaky_fd_version(test):
+ import sys
+ # Python random module leaks file descriptors on some versions.
+ return sys.version_info >= (2, 7, 8) and sys.version_info < (2, 7, 10)
+
+
+class AvoidsFdLeakTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailure(python_leaky_fd_version, "bugs.freebsd.org/197376")
+ @expectedFailureFreeBSD("llvm.org/pr25624 still failing with Python 2.7.10")
+ @skipIfWindows # The check for descriptor leakage needs to be implemented differently here.
+ @skipIfTargetAndroid() # Android have some other file descriptors open by the shell
+ def test_fd_leak_basic (self):
+ self.do_test([])
+
+ @expectedFailure(python_leaky_fd_version, "bugs.freebsd.org/197376")
+ @expectedFailureFreeBSD("llvm.org/pr25624 still failing with Python 2.7.10")
+ @skipIfWindows # The check for descriptor leakage needs to be implemented differently here.
+ @skipIfTargetAndroid() # Android have some other file descriptors open by the shell
+ def test_fd_leak_log (self):
+ self.do_test(["log enable -f '/dev/null' lldb commands"])
+
+ def do_test (self, commands):
+ self.build()
+ exe = os.path.join (os.getcwd(), "a.out")
+
+ for c in commands:
+ self.runCmd(c)
+
+ target = self.dbg.CreateTarget(exe)
+
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ self.assertTrue(process.GetState() == lldb.eStateExited, "Process should have exited.")
+ self.assertTrue(process.GetExitStatus() == 0,
+ "Process returned non-zero status. Were incorrect file descriptors passed?")
+
+ @expectedFailure(python_leaky_fd_version, "bugs.freebsd.org/197376")
+ @expectedFailureFreeBSD("llvm.org/pr25624 still failing with Python 2.7.10")
+ @expectedFlakeyLinux
+ @skipIfWindows # The check for descriptor leakage needs to be implemented differently here.
+ @skipIfTargetAndroid() # Android have some other file descriptors open by the shell
+ def test_fd_leak_multitarget (self):
+ self.build()
+ exe = os.path.join (os.getcwd(), "a.out")
+
+ target = self.dbg.CreateTarget(exe)
+ breakpoint = target.BreakpointCreateBySourceRegex ('Set breakpoint here', lldb.SBFileSpec ("main.c", False))
+ self.assertTrue(breakpoint, VALID_BREAKPOINT)
+
+ process1 = target.LaunchSimple (None, None, self.get_process_working_directory())
+ self.assertTrue(process1, PROCESS_IS_VALID)
+ self.assertTrue(process1.GetState() == lldb.eStateStopped, "Process should have been stopped.")
+
+ target2 = self.dbg.CreateTarget(exe)
+ process2 = target2.LaunchSimple (None, None, self.get_process_working_directory())
+ self.assertTrue(process2, PROCESS_IS_VALID)
+
+ self.assertTrue(process2.GetState() == lldb.eStateExited, "Process should have exited.")
+ self.assertTrue(process2.GetExitStatus() == 0,
+ "Process returned non-zero status. Were incorrect file descriptors passed?")
diff --git a/packages/Python/lldbsuite/test/functionalities/avoids-fd-leak/main.c b/packages/Python/lldbsuite/test/functionalities/avoids-fd-leak/main.c
new file mode 100644
index 000000000000..5bdf227928ed
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/avoids-fd-leak/main.c
@@ -0,0 +1,28 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+
+int
+main (int argc, char const **argv)
+{
+ struct stat buf;
+ int i, rv = 0; // Set breakpoint here.
+
+ // Make sure stdin/stdout/stderr exist.
+ for (i = 0; i <= 2; ++i) {
+ if (fstat(i, &buf) != 0)
+ return 1;
+ }
+
+ // Make sure no other file descriptors are open.
+ for (i = 3; i <= 256; ++i) {
+ if (fstat(i, &buf) == 0 || errno != EBADF) {
+ fprintf(stderr, "File descriptor %d is open.\n", i);
+ rv = 2;
+ }
+ }
+
+ return rv;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/backticks/.categories b/packages/Python/lldbsuite/test/functionalities/backticks/.categories
new file mode 100644
index 000000000000..3a3f4df6416b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/backticks/.categories
@@ -0,0 +1 @@
+cmdline
diff --git a/packages/Python/lldbsuite/test/functionalities/backticks/TestBackticksWithoutATarget.py b/packages/Python/lldbsuite/test/functionalities/backticks/TestBackticksWithoutATarget.py
new file mode 100644
index 000000000000..d31412bc783c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/backticks/TestBackticksWithoutATarget.py
@@ -0,0 +1,21 @@
+"""
+Test that backticks without a target should work (not infinite looping).
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+
+class BackticksWithNoTargetTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @no_debug_info_test
+ def test_backticks_no_target(self):
+ """A simple test of backticks without a target."""
+ self.expect("print `1+2-3`",
+ substrs = [' = 0'])
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/Makefile
new file mode 100644
index 000000000000..6067ee45e984
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+CFLAGS_EXTRAS += -std=c99
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/TestAddressBreakpoints.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/TestAddressBreakpoints.py
new file mode 100644
index 000000000000..9442a076e2a3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/TestAddressBreakpoints.py
@@ -0,0 +1,91 @@
+"""
+Test address breakpoints set with shared library of SBAddress work correctly.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import re
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+class AddressBreakpointTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test_address_breakpoints (self):
+ """Test address breakpoints set with shared library of SBAddress work correctly."""
+ self.build()
+ self.address_breakpoints()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ def address_breakpoints(self):
+ """Test address breakpoints set with shared library of SBAddress work correctly."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Now create a breakpoint on main.c by name 'c'.
+ breakpoint = target.BreakpointCreateBySourceRegex("Set a breakpoint here", lldb.SBFileSpec("main.c"))
+ self.assertTrue(breakpoint and
+ breakpoint.GetNumLocations() == 1,
+ VALID_BREAKPOINT)
+
+ # Get the breakpoint location from breakpoint after we verified that,
+ # indeed, it has one location.
+ location = breakpoint.GetLocationAtIndex(0)
+ self.assertTrue(location and
+ location.IsEnabled(),
+ VALID_BREAKPOINT_LOCATION)
+
+ # Next get the address from the location, and create an address breakpoint using
+ # that address:
+
+ address = location.GetAddress()
+ target.BreakpointDelete(breakpoint.GetID())
+
+ breakpoint = target.BreakpointCreateBySBAddress(address)
+
+ # Disable ASLR. This will allow us to actually test (on platforms that support this flag)
+ # that the breakpoint was able to track the module.
+
+ launch_info = lldb.SBLaunchInfo(None)
+ flags = launch_info.GetLaunchFlags()
+ flags &= ~lldb.eLaunchFlagDisableASLR
+ launch_info.SetLaunchFlags(flags)
+
+ error = lldb.SBError()
+
+ process = target.Launch (launch_info, error)
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # Did we hit our breakpoint?
+ from lldbsuite.test.lldbutil import get_threads_stopped_at_breakpoint
+ threads = get_threads_stopped_at_breakpoint (process, breakpoint)
+ self.assertTrue(len(threads) == 1, "There should be a thread stopped at our breakpoint")
+
+ # The hit count for the breakpoint should be 1.
+ self.assertTrue(breakpoint.GetHitCount() == 1)
+
+ process.Kill()
+
+ # Now re-launch and see that we hit the breakpoint again:
+ launch_info.Clear()
+ launch_info.SetLaunchFlags(flags)
+
+ process = target.Launch(launch_info, error)
+ self.assertTrue (process, PROCESS_IS_VALID)
+
+ thread = get_threads_stopped_at_breakpoint (process, breakpoint)
+ self.assertTrue(len(threads) == 1, "There should be a thread stopped at our breakpoint")
+
+ # The hit count for the breakpoint should now be 2.
+ self.assertTrue(breakpoint.GetHitCount() == 2)
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/main.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/main.c
new file mode 100644
index 000000000000..6b779296e188
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/main.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+int
+main()
+{
+ printf ("Set a breakpoint here.\n");
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/Makefile
new file mode 100644
index 000000000000..a6376f9b165d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c a.c b.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
new file mode 100644
index 000000000000..8cf7539432ba
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
@@ -0,0 +1,206 @@
+"""
+Test lldb breakpoint command add/list/delete.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class BreakpointCommandTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @classmethod
+ def classCleanup(cls):
+ """Cleanup the test byproduct of breakpoint_command_sequence(self)."""
+ cls.RemoveTempFile("output.txt")
+ cls.RemoveTempFile("output2.txt")
+
+ @expectedFailureWindows("llvm.org/pr24528")
+ def test(self):
+ """Test a sequence of breakpoint command add, list, and delete."""
+ self.build()
+ self.breakpoint_command_sequence()
+ self.breakpoint_command_script_parameters ()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside main().
+ self.line = line_number('main.c', '// Set break point at this line.')
+ # disable "There is a running process, kill it and restart?" prompt
+ self.runCmd("settings set auto-confirm true")
+ self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
+
+ def breakpoint_command_sequence(self):
+ """Test a sequence of breakpoint command add, list, and delete."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Add three breakpoints on the same line. The first time we don't specify the file,
+ # since the default file is the one containing main:
+ lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1, loc_exact=True)
+ lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
+ lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
+ # Breakpoint 4 - set at the same location as breakpoint 1 to test setting breakpoint commands on two breakpoints at a time
+ lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1, loc_exact=True)
+
+ # Now add callbacks for the breakpoints just created.
+ self.runCmd("breakpoint command add -s command -o 'frame variable --show-types --scope' 1 4")
+ self.runCmd("breakpoint command add -s python -o 'here = open(\"output.txt\", \"w\"); here.write(\"lldb\\n\"); here.close()' 2")
+ self.runCmd("breakpoint command add --python-function bktptcmd.function 3")
+
+ # Check that the breakpoint commands are correctly set.
+
+ # The breakpoint list now only contains breakpoint 1.
+ self.expect("breakpoint list", "Breakpoints 1 & 2 created",
+ substrs = ["2: file = 'main.c', line = %d, exact_match = 0, locations = 1" % self.line],
+ patterns = ["1: file = '.*main.c', line = %d, exact_match = 0, locations = 1" % self.line] )
+
+ self.expect("breakpoint list -f", "Breakpoints 1 & 2 created",
+ substrs = ["2: file = 'main.c', line = %d, exact_match = 0, locations = 1" % self.line],
+ patterns = ["1: file = '.*main.c', line = %d, exact_match = 0, locations = 1" % self.line,
+ "1.1: .+at main.c:%d, .+unresolved, hit count = 0" % self.line,
+ "2.1: .+at main.c:%d, .+unresolved, hit count = 0" % self.line])
+
+ self.expect("breakpoint command list 1", "Breakpoint 1 command ok",
+ substrs = ["Breakpoint commands:",
+ "frame variable --show-types --scope"])
+ self.expect("breakpoint command list 2", "Breakpoint 2 command ok",
+ substrs = ["Breakpoint commands:",
+ "here = open",
+ "here.write",
+ "here.close()"])
+ self.expect("breakpoint command list 3", "Breakpoint 3 command ok",
+ substrs = ["Breakpoint commands:",
+ "bktptcmd.function(frame, bp_loc, internal_dict)"])
+
+ self.expect("breakpoint command list 4", "Breakpoint 4 command ok",
+ substrs = ["Breakpoint commands:",
+ "frame variable --show-types --scope"])
+
+ self.runCmd("breakpoint delete 4")
+
+ self.runCmd("command script import --allow-reload ./bktptcmd.py")
+
+ # Next lets try some other breakpoint kinds. First break with a regular expression
+ # and then specify only one file. The first time we should get two locations,
+ # the second time only one:
+
+ lldbutil.run_break_set_by_regexp (self, r"._MyFunction", num_expected_locations=2)
+
+ lldbutil.run_break_set_by_regexp (self, r"._MyFunction", extra_options="-f a.c", num_expected_locations=1)
+
+ lldbutil.run_break_set_by_regexp (self, r"._MyFunction", extra_options="-f a.c -f b.c", num_expected_locations=2)
+
+ # Now try a source regex breakpoint:
+ lldbutil.run_break_set_by_source_regexp (self, r"is about to return [12]0", extra_options="-f a.c -f b.c", num_expected_locations=2)
+
+ lldbutil.run_break_set_by_source_regexp (self, r"is about to return [12]0", extra_options="-f a.c", num_expected_locations=1)
+
+ # Run the program. Remove 'output.txt' if it exists.
+ self.RemoveTempFile("output.txt")
+ self.RemoveTempFile("output2.txt")
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # Check that the file 'output.txt' exists and contains the string "lldb".
+
+ # The 'output.txt' file should now exist.
+ self.assertTrue(os.path.isfile("output.txt"),
+ "'output.txt' exists due to breakpoint command for breakpoint 2.")
+ self.assertTrue(os.path.isfile("output2.txt"),
+ "'output2.txt' exists due to breakpoint command for breakpoint 3.")
+
+ # Read the output file produced by running the program.
+ with open('output.txt', 'r') as f:
+ output = f.read()
+
+ self.expect(output, "File 'output.txt' and the content matches", exe=False,
+ startstr = "lldb")
+
+ with open('output2.txt', 'r') as f:
+ output = f.read()
+
+ self.expect(output, "File 'output2.txt' and the content matches", exe=False,
+ startstr = "lldb")
+
+
+ # Finish the program.
+ self.runCmd("process continue")
+
+ # Remove the breakpoint command associated with breakpoint 1.
+ self.runCmd("breakpoint command delete 1")
+
+ # Remove breakpoint 2.
+ self.runCmd("breakpoint delete 2")
+
+ self.expect("breakpoint command list 1",
+ startstr = "Breakpoint 1 does not have an associated command.")
+ self.expect("breakpoint command list 2", error=True,
+ startstr = "error: '2' is not a currently valid breakpoint id.")
+
+ # The breakpoint list now only contains breakpoint 1.
+ self.expect("breakpoint list -f", "Breakpoint 1 exists",
+ patterns = ["1: file = '.*main.c', line = %d, exact_match = 0, locations = 1, resolved = 1" %
+ self.line,
+ "hit count = 1"])
+
+ # Not breakpoint 2.
+ self.expect("breakpoint list -f", "No more breakpoint 2", matching=False,
+ substrs = ["2: file = 'main.c', line = %d, exact_match = 0, locations = 1, resolved = 1" %
+ self.line])
+
+ # Run the program again, with breakpoint 1 remaining.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # We should be stopped again due to breakpoint 1.
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # The breakpoint should have a hit count of 2.
+ self.expect("breakpoint list -f", BREAKPOINT_HIT_TWICE,
+ substrs = ['resolved, hit count = 2'])
+
+ def breakpoint_command_script_parameters (self):
+ """Test that the frame and breakpoint location are being properly passed to the script breakpoint command function."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Add a breakpoint.
+ lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
+
+ # Now add callbacks for the breakpoints just created.
+ self.runCmd("breakpoint command add -s python -o 'here = open(\"output-2.txt\", \"w\"); here.write(str(frame) + \"\\n\"); here.write(str(bp_loc) + \"\\n\"); here.close()' 1")
+
+ # Remove 'output-2.txt' if it already exists.
+
+ if (os.path.exists('output-2.txt')):
+ os.remove ('output-2.txt')
+
+ # Run program, hit breakpoint, and hopefully write out new version of 'output-2.txt'
+ self.runCmd ("run", RUN_SUCCEEDED)
+
+ # Check that the file 'output.txt' exists and contains the string "lldb".
+
+ # The 'output-2.txt' file should now exist.
+ self.assertTrue(os.path.isfile("output-2.txt"),
+ "'output-2.txt' exists due to breakpoint command for breakpoint 1.")
+
+ # Read the output file produced by running the program.
+ with open('output-2.txt', 'r') as f:
+ output = f.read()
+
+ self.expect (output, "File 'output-2.txt' and the content matches", exe=False,
+ startstr = "frame #0:",
+ patterns = ["1.* where = .*main .* resolved, hit count = 1" ])
+
+ # Now remove 'output-2.txt'
+ os.remove ('output-2.txt')
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommandsFromPython.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommandsFromPython.py
new file mode 100644
index 000000000000..7a9cc744d528
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommandsFromPython.py
@@ -0,0 +1,95 @@
+"""
+Test that you can set breakpoint commands successfully with the Python API's:
+"""
+
+from __future__ import print_function
+
+
+
+import os
+import re
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+import sys
+from lldbsuite.test.lldbtest import *
+
+class PythonBreakpointCommandSettingTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+ my_var = 10
+
+ @add_test_categories(['pyapi'])
+ def test_step_out_python(self):
+ """Test stepping out using avoid-no-debug with dsyms."""
+ self.build()
+ self.do_set_python_command_from_python ()
+
+ def setUp (self):
+ TestBase.setUp(self)
+ self.main_source = "main.c"
+ self.main_source_spec = lldb.SBFileSpec(self.main_source)
+
+
+ def do_set_python_command_from_python (self):
+ exe = os.path.join(os.getcwd(), "a.out")
+ error = lldb.SBError()
+
+ self.target = self.dbg.CreateTarget(exe)
+ self.assertTrue(self.target, VALID_TARGET)
+
+ body_bkpt = self.target.BreakpointCreateBySourceRegex("Set break point at this line.", self.main_source_spec)
+ self.assertTrue(body_bkpt, VALID_BREAKPOINT)
+
+ func_bkpt = self.target.BreakpointCreateBySourceRegex("Set break point at this line.", self.main_source_spec)
+ self.assertTrue(func_bkpt, VALID_BREAKPOINT)
+
+ # Also test that setting a source regex breakpoint with an empty file spec list sets it on all files:
+ no_files_bkpt = self.target.BreakpointCreateBySourceRegex("Set a breakpoint here", lldb.SBFileSpecList(), lldb.SBFileSpecList())
+ self.assertTrue(no_files_bkpt, VALID_BREAKPOINT)
+ num_locations = no_files_bkpt.GetNumLocations()
+ self.assertTrue(num_locations >= 2, "Got at least two breakpoint locations")
+ got_one_in_A = False
+ got_one_in_B = False
+ for idx in range(0, num_locations):
+ comp_unit = no_files_bkpt.GetLocationAtIndex(idx).GetAddress().GetSymbolContext(lldb.eSymbolContextCompUnit).GetCompileUnit().GetFileSpec()
+ print("Got comp unit: ", comp_unit.GetFilename())
+ if comp_unit.GetFilename() == "a.c":
+ got_one_in_A = True
+ elif comp_unit.GetFilename() == "b.c":
+ got_one_in_B = True
+
+ self.assertTrue(got_one_in_A, "Failed to match the pattern in A")
+ self.assertTrue(got_one_in_B, "Failed to match the pattern in B")
+ self.target.BreakpointDelete(no_files_bkpt.GetID())
+
+ PythonBreakpointCommandSettingTestCase.my_var = 10
+ error = lldb.SBError()
+ error = body_bkpt.SetScriptCallbackBody("\
+import TestBreakpointCommandsFromPython\n\
+TestBreakpointCommandsFromPython.PythonBreakpointCommandSettingTestCase.my_var = 20\n\
+print('Hit breakpoint')")
+ self.assertTrue (error.Success(), "Failed to set the script callback body: %s."%(error.GetCString()))
+
+ self.dbg.HandleCommand("command script import --allow-reload ./bktptcmd.py")
+ func_bkpt.SetScriptCallbackFunction("bktptcmd.function")
+
+ # We will use the function that touches a text file, so remove it first:
+ self.RemoveTempFile("output2.txt")
+
+ # Now launch the process, and do not stop at entry point.
+ self.process = self.target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+
+ # Now finish, and make sure the return value is correct.
+ threads = lldbutil.get_threads_stopped_at_breakpoint (self.process, body_bkpt)
+ self.assertTrue(len(threads) == 1, "Stopped at inner breakpoint.")
+ self.thread = threads[0]
+
+ self.assertTrue(PythonBreakpointCommandSettingTestCase.my_var == 20)
+
+ # Check for the function version as well, which produced this file:
+ # Remember to clean up after ourselves...
+ self.assertTrue(os.path.isfile("output2.txt"),
+ "'output2.txt' exists due to breakpoint command for breakpoint function.")
+ self.RemoveTempFile("output2.txt")
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestRegexpBreakCommand.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestRegexpBreakCommand.py
new file mode 100644
index 000000000000..1ea71cbde45c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestRegexpBreakCommand.py
@@ -0,0 +1,51 @@
+"""
+Test _regexp-break command which uses regular expression matching to dispatch to other built in breakpoint commands.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class RegexpBreakCommandTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test(self):
+ """Test _regexp-break command."""
+ self.build()
+ self.regexp_break_command()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside main().
+ self.source = 'main.c'
+ self.line = line_number(self.source, '// Set break point at this line.')
+
+ def regexp_break_command(self):
+ """Test the super consie "b" command, which is analias for _regexp-break."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ break_results = lldbutil.run_break_set_command (self, "b %d" % self.line)
+ lldbutil.check_breakpoint_result (self, break_results, file_name='main.c', line_number=self.line, num_locations=1)
+
+ break_results = lldbutil.run_break_set_command (self, "b %s:%d" % (self.source, self.line))
+ lldbutil.check_breakpoint_result (self, break_results, file_name='main.c', line_number=self.line, num_locations=1)
+
+ # Check breakpoint with full file path.
+ full_path = os.path.join(os.getcwd(), self.source)
+ break_results = lldbutil.run_break_set_command (self, "b %s:%d" % (full_path, self.line))
+ lldbutil.check_breakpoint_result (self, break_results, file_name='main.c', line_number=self.line, num_locations=1)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/a.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/a.c
new file mode 100644
index 000000000000..870e4a6ab166
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/a.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+int
+a_MyFunction ()
+{
+ // Set a breakpoint here.
+ printf ("a is about to return 10.\n");
+ return 10;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/b.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/b.c
new file mode 100644
index 000000000000..02b78e7bd855
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/b.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+int
+b_MyFunction ()
+{
+ // Set a breakpoint here.
+ printf ("b is about to return 20.\n");
+ return 20;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/bktptcmd.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/bktptcmd.py
new file mode 100644
index 000000000000..4bbb0327eacd
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/bktptcmd.py
@@ -0,0 +1,6 @@
+from __future__ import print_function
+
+def function(frame, bp_loc, dict):
+ there = open("output2.txt", "w");
+ print("lldb", file=there)
+ there.close()
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/main.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/main.c
new file mode 100644
index 000000000000..62ec97f43284
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/main.c
@@ -0,0 +1,13 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int main (int argc, char const *argv[])
+{
+ return 0; // Set break point at this line.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/Makefile
new file mode 100644
index 000000000000..6067ee45e984
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+CFLAGS_EXTRAS += -std=c99
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/TestBreakpointConditions.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/TestBreakpointConditions.py
new file mode 100644
index 000000000000..8c22c8fe869c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/TestBreakpointConditions.py
@@ -0,0 +1,181 @@
+"""
+Test breakpoint conditions with 'breakpoint modify -c <expr> id'.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import re
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+class BreakpointConditionsTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipIfWindows # Requires EE to support COFF on Windows (http://llvm.org/pr22232)
+ def test_breakpoint_condition_and_run_command(self):
+ """Exercise breakpoint condition with 'breakpoint modify -c <expr> id'."""
+ self.build()
+ self.breakpoint_conditions()
+
+ @skipIfWindows # Requires EE to support COFF on Windows (http://llvm.org/pr22232)
+ def test_breakpoint_condition_inline_and_run_command(self):
+ """Exercise breakpoint condition inline with 'breakpoint set'."""
+ self.build()
+ self.breakpoint_conditions(inline=True)
+
+ @skipIfWindows # Requires EE to support COFF on Windows (http://llvm.org/pr22232)
+ @add_test_categories(['pyapi'])
+ def test_breakpoint_condition_and_python_api(self):
+ """Use Python APIs to set breakpoint conditions."""
+ self.build()
+ self.breakpoint_conditions_python()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to of function 'c'.
+ self.line1 = line_number('main.c', '// Find the line number of function "c" here.')
+ self.line2 = line_number('main.c', "// Find the line number of c's parent call here.")
+
+ def breakpoint_conditions(self, inline=False):
+ """Exercise breakpoint condition with 'breakpoint modify -c <expr> id'."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ if inline:
+ # Create a breakpoint by function name 'c' and set the condition.
+ lldbutil.run_break_set_by_symbol (self, "c", extra_options="-c 'val == 3'", num_expected_locations=1, sym_exact=True)
+ else:
+ # Create a breakpoint by function name 'c'.
+ lldbutil.run_break_set_by_symbol (self, "c", num_expected_locations=1, sym_exact=True)
+
+ # And set a condition on the breakpoint to stop on when 'val == 3'.
+ self.runCmd("breakpoint modify -c 'val == 3' 1")
+
+ # Now run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The process should be stopped at this point.
+ self.expect("process status", PROCESS_STOPPED,
+ patterns = ['Process .* stopped'])
+
+ # 'frame variable --show-types val' should return 3 due to breakpoint condition.
+ self.expect("frame variable --show-types val", VARIABLES_DISPLAYED_CORRECTLY,
+ startstr = '(int) val = 3')
+
+ # Also check the hit count, which should be 3, by design.
+ self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
+ substrs = ["resolved = 1",
+ "Condition: val == 3",
+ "hit count = 1"])
+
+ # The frame #0 should correspond to main.c:36, the executable statement
+ # in function name 'c'. And the parent frame should point to main.c:24.
+ self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT_CONDITION,
+ #substrs = ["stop reason = breakpoint"],
+ patterns = ["frame #0.*main.c:%d" % self.line1,
+ "frame #1.*main.c:%d" % self.line2])
+
+ # Test that "breakpoint modify -c ''" clears the condition for the last
+ # created breakpoint, so that when the breakpoint hits, val == 1.
+ self.runCmd("process kill")
+ self.runCmd("breakpoint modify -c ''")
+ self.expect("breakpoint list -f", BREAKPOINT_STATE_CORRECT, matching=False,
+ substrs = ["Condition:"])
+
+ # Now run the program again.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The process should be stopped at this point.
+ self.expect("process status", PROCESS_STOPPED,
+ patterns = ['Process .* stopped'])
+
+ # 'frame variable --show-types val' should return 1 since it is the first breakpoint hit.
+ self.expect("frame variable --show-types val", VARIABLES_DISPLAYED_CORRECTLY,
+ startstr = '(int) val = 1')
+
+ self.runCmd("process kill")
+ self.runCmd("breakpoint disable")
+
+ self.runCmd("breakpoint set -p Loop")
+ arch = self.getArchitecture()
+ if arch in ['x86_64', 'i386']:
+ self.runCmd("breakpoint modify -c ($eax&&i)")
+ elif arch in ['aarch64']:
+ self.runCmd("breakpoint modify -c ($x1&&i)")
+ elif arch in ['arm']:
+ self.runCmd("breakpoint modify -c ($r0&&i)")
+ elif re.match("mips",arch):
+ self.runCmd("breakpoint modify -c ($r2&&i)")
+ self.runCmd("run")
+
+ self.expect("process status", PROCESS_STOPPED,
+ patterns = ['Process .* stopped'])
+
+ self.runCmd("continue")
+
+ self.expect("process status", PROCESS_EXITED,
+ patterns = ['Process .* exited'])
+
+ def breakpoint_conditions_python(self):
+ """Use Python APIs to set breakpoint conditions."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Now create a breakpoint on main.c by name 'c'.
+ breakpoint = target.BreakpointCreateByName('c', 'a.out')
+ #print("breakpoint:", breakpoint)
+ self.assertTrue(breakpoint and
+ breakpoint.GetNumLocations() == 1,
+ VALID_BREAKPOINT)
+
+ # We didn't associate a thread index with the breakpoint, so it should be invalid.
+ self.assertTrue(breakpoint.GetThreadIndex() == lldb.UINT32_MAX,
+ "The thread index should be invalid")
+ # The thread name should be invalid, too.
+ self.assertTrue(breakpoint.GetThreadName() is None,
+ "The thread name should be invalid")
+
+ # Let's set the thread index for this breakpoint and verify that it is,
+ # indeed, being set correctly.
+ breakpoint.SetThreadIndex(1) # There's only one thread for the process.
+ self.assertTrue(breakpoint.GetThreadIndex() == 1,
+ "The thread index has been set correctly")
+
+ # Get the breakpoint location from breakpoint after we verified that,
+ # indeed, it has one location.
+ location = breakpoint.GetLocationAtIndex(0)
+ self.assertTrue(location and
+ location.IsEnabled(),
+ VALID_BREAKPOINT_LOCATION)
+
+ # Set the condition on the breakpoint location.
+ location.SetCondition('val == 3')
+ self.expect(location.GetCondition(), exe=False,
+ startstr = 'val == 3')
+
+ # Now launch the process, and do not stop at entry point.
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # Frame #0 should be on self.line1 and the break condition should hold.
+ from lldbsuite.test.lldbutil import get_stopped_thread
+ thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition")
+ frame0 = thread.GetFrameAtIndex(0)
+ var = frame0.FindValue('val', lldb.eValueTypeVariableArgument)
+ self.assertTrue(frame0.GetLineEntry().GetLine() == self.line1 and
+ var.GetValue() == '3')
+
+ # The hit count for the breakpoint should be 1.
+ self.assertTrue(breakpoint.GetHitCount() == 1)
+
+ process.Continue()
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/main.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/main.c
new file mode 100644
index 000000000000..1aa8235e1b0c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/main.c
@@ -0,0 +1,54 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+// This simple program is to demonstrate the capability of the lldb command
+// "breakpoint modify -c 'val == 3' breakpt-id" to break within c(int val) only
+// when the value of the arg is 3.
+
+int a(int);
+int b(int);
+int c(int);
+
+int a(int val)
+{
+ if (val <= 1)
+ return b(val);
+ else if (val >= 3)
+ return c(val); // Find the line number of c's parent call here.
+
+ return val;
+}
+
+int b(int val)
+{
+ return c(val);
+}
+
+int c(int val)
+{
+ return val + 3; // Find the line number of function "c" here.
+}
+
+int main (int argc, char const *argv[])
+{
+ int A1 = a(1); // a(1) -> b(1) -> c(1)
+ printf("a(1) returns %d\n", A1);
+
+ int B2 = b(2); // b(2) -> c(2)
+ printf("b(2) returns %d\n", B2);
+
+ int A3 = a(3); // a(3) -> c(3)
+ printf("a(3) returns %d\n", A3);
+
+ for (int i = 0; i < 2; ++i)
+ printf("Loop\n");
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ids/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ids/Makefile
new file mode 100644
index 000000000000..f89b52a972e9
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ids/Makefile
@@ -0,0 +1,9 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+ifneq (,$(findstring icc,$(CC)))
+ CXXFLAGS += -debug inline-debug-info
+endif
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ids/TestBreakpointIDs.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ids/TestBreakpointIDs.py
new file mode 100644
index 000000000000..b7edf2a6e4d5
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ids/TestBreakpointIDs.py
@@ -0,0 +1,51 @@
+"""
+Test lldb breakpoint ids.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class BreakpointIDTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test (self):
+ self.build()
+
+ exe = os.path.join (os.getcwd(), "a.out")
+ self.expect("file " + exe,
+ patterns = [ "Current executable set to .*a.out" ])
+
+
+ bpno = lldbutil.run_break_set_by_symbol (self, 'product', num_expected_locations=-1, sym_exact=False)
+ self.assertTrue (bpno == 1, "First breakpoint number is 1.")
+
+ bpno = lldbutil.run_break_set_by_symbol (self, 'sum', num_expected_locations=-1, sym_exact=False)
+ self.assertTrue (bpno == 2, "Second breakpoint number is 2.")
+
+ bpno = lldbutil.run_break_set_by_symbol (self, 'junk', num_expected_locations=0, sym_exact=False)
+ self.assertTrue (bpno == 3, "Third breakpoint number is 3.")
+
+ self.expect ("breakpoint disable 1.1 - 2.2 ",
+ COMMAND_FAILED_AS_EXPECTED, error = True,
+ startstr = "error: Invalid range: Ranges that specify particular breakpoint locations must be within the same major breakpoint; you specified two different major breakpoints, 1 and 2.")
+
+ self.expect ("breakpoint disable 2 - 2.2",
+ COMMAND_FAILED_AS_EXPECTED, error = True,
+ startstr = "error: Invalid breakpoint id range: Either both ends of range must specify a breakpoint location, or neither can specify a breakpoint location.")
+
+ self.expect ("breakpoint disable 2.1 - 2",
+ COMMAND_FAILED_AS_EXPECTED, error = True,
+ startstr = "error: Invalid breakpoint id range: Either both ends of range must specify a breakpoint location, or neither can specify a breakpoint location.")
+
+ self.expect ("breakpoint disable 2.1 - 2.2",
+ startstr = "2 breakpoints disabled.")
+
+ self.expect ("breakpoint enable 2.*",
+ patterns = [ ".* breakpoints enabled."] )
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ids/main.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ids/main.cpp
new file mode 100644
index 000000000000..3deef22c93c8
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ids/main.cpp
@@ -0,0 +1,65 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <cstdlib>
+#include <string>
+#include <fstream>
+#include <iostream>
+
+
+#define INLINE inline __attribute__((always_inline))
+
+INLINE int
+product (int x, int y)
+{
+ int result = x * y;
+ return result;
+}
+
+INLINE int
+sum (int a, int b)
+{
+ int result = a + b;
+ return result;
+}
+
+int
+strange_max (int m, int n)
+{
+ if (m > n)
+ return m;
+ else if (n > m)
+ return n;
+ else
+ return 0;
+}
+
+int
+foo (int i, int j)
+{
+ if (strange_max (i, j) == i)
+ return product (i, j);
+ else if (strange_max (i, j) == j)
+ return sum (i, j);
+ else
+ return product (sum (i, i), sum (j, j));
+}
+
+int
+main(int argc, char const *argv[])
+{
+
+ int array[3];
+
+ array[0] = foo (1238, 78392);
+ array[1] = foo (379265, 23674);
+ array[2] = foo (872934, 234);
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/Makefile
new file mode 100644
index 000000000000..b09a579159d4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py
new file mode 100644
index 000000000000..8a83cb627f7a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py
@@ -0,0 +1,136 @@
+"""
+Test breakpoint ignore count features.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import re
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+class BreakpointIgnoreCountTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test_with_run_command(self):
+ """Exercise breakpoint ignore count with 'breakpoint set -i <count>'."""
+ self.build()
+ self.breakpoint_ignore_count()
+
+ @add_test_categories(['pyapi'])
+ def test_with_python_api(self):
+ """Use Python APIs to set breakpoint ignore count."""
+ self.build()
+ self.breakpoint_ignore_count_python()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to of function 'c'.
+ self.line1 = line_number('main.c', '// Find the line number of function "c" here.')
+ self.line2 = line_number('main.c', '// b(2) -> c(2) Find the call site of b(2).')
+ self.line3 = line_number('main.c', '// a(3) -> c(3) Find the call site of c(3).')
+ self.line4 = line_number('main.c', '// a(3) -> c(3) Find the call site of a(3).')
+ self.line5 = line_number('main.c', '// Find the call site of c in main.')
+
+ def breakpoint_ignore_count(self):
+ """Exercise breakpoint ignore count with 'breakpoint set -i <count>'."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Create a breakpoint in main.c at line1.
+ lldbutil.run_break_set_by_file_and_line (self, 'main.c', self.line1, extra_options='-i 1', num_expected_locations=1, loc_exact=True)
+
+ # Now run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The process should be stopped at this point.
+ self.expect("process status", PROCESS_STOPPED,
+ patterns = ['Process .* stopped'])
+
+ # Also check the hit count, which should be 2, due to ignore count of 1.
+ self.expect("breakpoint list -f", BREAKPOINT_HIT_THRICE,
+ substrs = ["resolved = 1",
+ "hit count = 2"])
+
+ # The frame #0 should correspond to main.c:37, the executable statement
+ # in function name 'c'. And frame #2 should point to main.c:45.
+ self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT,
+ #substrs = ["stop reason = breakpoint"],
+ patterns = ["frame #0.*main.c:%d" % self.line1,
+ "frame #2.*main.c:%d" % self.line2])
+
+ # continue -i 1 is the same as setting the ignore count to 1 again, try that:
+ # Now run the program.
+ self.runCmd("process continue -i 1", RUN_SUCCEEDED)
+
+ # The process should be stopped at this point.
+ self.expect("process status", PROCESS_STOPPED,
+ patterns = ['Process .* stopped'])
+
+ # Also check the hit count, which should be 2, due to ignore count of 1.
+ self.expect("breakpoint list -f", BREAKPOINT_HIT_THRICE,
+ substrs = ["resolved = 1",
+ "hit count = 4"])
+
+ # The frame #0 should correspond to main.c:37, the executable statement
+ # in function name 'c'. And frame #2 should point to main.c:45.
+ self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT,
+ #substrs = ["stop reason = breakpoint"],
+ patterns = ["frame #0.*main.c:%d" % self.line1,
+ "frame #1.*main.c:%d" % self.line5])
+
+
+
+ def breakpoint_ignore_count_python(self):
+ """Use Python APIs to set breakpoint ignore count."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Now create a breakpoint on main.c by name 'c'.
+ breakpoint = target.BreakpointCreateByName('c', 'a.out')
+ self.assertTrue(breakpoint and
+ breakpoint.GetNumLocations() == 1,
+ VALID_BREAKPOINT)
+
+ # Get the breakpoint location from breakpoint after we verified that,
+ # indeed, it has one location.
+ location = breakpoint.GetLocationAtIndex(0)
+ self.assertTrue(location and
+ location.IsEnabled(),
+ VALID_BREAKPOINT_LOCATION)
+
+ # Set the ignore count on the breakpoint location.
+ location.SetIgnoreCount(2)
+ self.assertTrue(location.GetIgnoreCount() == 2,
+ "SetIgnoreCount() works correctly")
+
+ # Now launch the process, and do not stop at entry point.
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # Frame#0 should be on main.c:37, frame#1 should be on main.c:25, and
+ # frame#2 should be on main.c:48.
+ #lldbutil.print_stacktraces(process)
+ from lldbsuite.test.lldbutil import get_stopped_thread
+ thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint")
+ frame0 = thread.GetFrameAtIndex(0)
+ frame1 = thread.GetFrameAtIndex(1)
+ frame2 = thread.GetFrameAtIndex(2)
+ self.assertTrue(frame0.GetLineEntry().GetLine() == self.line1 and
+ frame1.GetLineEntry().GetLine() == self.line3 and
+ frame2.GetLineEntry().GetLine() == self.line4,
+ STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT)
+
+ # The hit count for the breakpoint should be 3.
+ self.assertTrue(breakpoint.GetHitCount() == 3)
+
+ process.Continue()
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/main.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/main.c
new file mode 100644
index 000000000000..b74b37b48b08
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/main.c
@@ -0,0 +1,54 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+// This simple program is to demonstrate the capability of the lldb command
+// "breakpoint modify -i <count> breakpt-id" to set the number of times a
+// breakpoint is skipped before stopping. Ignore count can also be set upon
+// breakpoint creation by 'breakpoint set ... -i <count>'.
+
+int a(int);
+int b(int);
+int c(int);
+
+int a(int val)
+{
+ if (val <= 1)
+ return b(val);
+ else if (val >= 3)
+ return c(val); // a(3) -> c(3) Find the call site of c(3).
+
+ return val;
+}
+
+int b(int val)
+{
+ return c(val);
+}
+
+int c(int val)
+{
+ return val + 3; // Find the line number of function "c" here.
+}
+
+int main (int argc, char const *argv[])
+{
+ int A1 = a(1); // a(1) -> b(1) -> c(1)
+ printf("a(1) returns %d\n", A1);
+
+ int B2 = b(2); // b(2) -> c(2) Find the call site of b(2).
+ printf("b(2) returns %d\n", B2);
+
+ int A3 = a(3); // a(3) -> c(3) Find the call site of a(3).
+ printf("a(3) returns %d\n", A3);
+
+ int C1 = c(5); // Find the call site of c in main.
+ printf ("c(5) returns %d\n", C1);
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/Makefile
new file mode 100644
index 000000000000..4f6b058fa324
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+C_SOURCES := a.c
+CXX_SOURCES := main.cpp b.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/TestBreakpointLanguage.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/TestBreakpointLanguage.py
new file mode 100644
index 000000000000..94fc7bf79f63
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/TestBreakpointLanguage.py
@@ -0,0 +1,85 @@
+"""
+Test that the language option for breakpoints works correctly
+parser.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+import shutil
+import subprocess
+
+class TestBreakpointLanguage(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside main().
+
+ def check_location_file (self, bp, loc, test_name):
+ bp_loc = bp.GetLocationAtIndex(loc)
+ addr = bp_loc.GetAddress()
+ comp_unit = addr.GetCompileUnit()
+ comp_name = comp_unit.GetFileSpec().GetFilename()
+ return comp_name == test_name
+
+ def test_regex_breakpoint_language(self):
+ """Test that the name regex breakpoint commands obey the language filter."""
+
+ self.build()
+ # Create a target by the debugger.
+ exe = os.path.join(os.getcwd(), "a.out")
+ error = lldb.SBError()
+ # Don't read in dependencies so we don't come across false matches that
+ # add unwanted breakpoint hits.
+ self.target = self.dbg.CreateTarget(exe, None, None, False, error)
+ self.assertTrue(self.target, VALID_TARGET)
+
+ cpp_bp = self.target.BreakpointCreateByRegex("func_from", lldb.eLanguageTypeC_plus_plus, lldb.SBFileSpecList(), lldb.SBFileSpecList())
+ self.assertTrue(cpp_bp.GetNumLocations() == 1, "Only one C++ symbol matches")
+ self.assertTrue(self.check_location_file(cpp_bp, 0, "b.cpp"))
+
+ c_bp = self.target.BreakpointCreateByRegex("func_from", lldb.eLanguageTypeC, lldb.SBFileSpecList(), lldb.SBFileSpecList())
+ self.assertTrue(c_bp.GetNumLocations() == 1, "Only one C symbol matches")
+ self.assertTrue(self.check_location_file(c_bp, 0, "a.c"))
+
+ objc_bp = self.target.BreakpointCreateByRegex("func_from", lldb.eLanguageTypeObjC, lldb.SBFileSpecList(), lldb.SBFileSpecList())
+ self.assertTrue(objc_bp.GetNumLocations() == 0, "No ObjC symbol matches")
+
+ def test_by_name_breakpoint_language(self):
+ """Test that the name regex breakpoint commands obey the language filter."""
+
+ self.build()
+ # Create a target by the debugger.
+ exe = os.path.join(os.getcwd(), "a.out")
+ error = lldb.SBError()
+ # Don't read in dependencies so we don't come across false matches that
+ # add unwanted breakpoint hits.
+ self.target = self.dbg.CreateTarget(exe, None, None, False, error)
+ self.assertTrue(self.target, VALID_TARGET)
+
+ cpp_bp = self.target.BreakpointCreateByName("func_from_cpp", lldb.eFunctionNameTypeAuto, lldb.eLanguageTypeC_plus_plus, lldb.SBFileSpecList(), lldb.SBFileSpecList())
+ self.assertTrue(cpp_bp.GetNumLocations() == 1, "Only one C++ symbol matches")
+ self.assertTrue(self.check_location_file(cpp_bp, 0, "b.cpp"))
+
+ no_cpp_bp = self.target.BreakpointCreateByName("func_from_c", lldb.eFunctionNameTypeAuto, lldb.eLanguageTypeC_plus_plus, lldb.SBFileSpecList(), lldb.SBFileSpecList())
+ self.assertTrue(no_cpp_bp.GetNumLocations() == 0, "And the C one doesn't match")
+
+ c_bp = self.target.BreakpointCreateByName("func_from_c", lldb.eFunctionNameTypeAuto, lldb.eLanguageTypeC, lldb.SBFileSpecList(), lldb.SBFileSpecList())
+ self.assertTrue(c_bp.GetNumLocations() == 1, "Only one C symbol matches")
+ self.assertTrue(self.check_location_file(c_bp, 0, "a.c"))
+
+ no_c_bp = self.target.BreakpointCreateByName("func_from_cpp", lldb.eFunctionNameTypeAuto, lldb.eLanguageTypeC, lldb.SBFileSpecList(), lldb.SBFileSpecList())
+ self.assertTrue(no_c_bp.GetNumLocations() == 0, "And the C++ one doesn't match")
+
+ objc_bp = self.target.BreakpointCreateByName("func_from_cpp", lldb.eFunctionNameTypeAuto, lldb.eLanguageTypeObjC, lldb.SBFileSpecList(), lldb.SBFileSpecList())
+ self.assertTrue(objc_bp.GetNumLocations() == 0, "No ObjC symbol matches")
+
+
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/a.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/a.c
new file mode 100644
index 000000000000..b90e2bdcca5d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/a.c
@@ -0,0 +1,5 @@
+int
+func_from_c ()
+{
+ return 5;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/b.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/b.cpp
new file mode 100644
index 000000000000..89373445b9aa
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/b.cpp
@@ -0,0 +1,5 @@
+int
+func_from_cpp()
+{
+ return 10;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/main.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/main.cpp
new file mode 100644
index 000000000000..b7d00a602029
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/main.cpp
@@ -0,0 +1,11 @@
+#include <stdio.h>
+extern "C" int func_from_c();
+extern int func_from_cpp();
+
+int
+main()
+{
+ func_from_c();
+ func_from_cpp();
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/Makefile
new file mode 100644
index 000000000000..7934cd5db427
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/Makefile
@@ -0,0 +1,9 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+ifneq (,$(findstring icc,$(CC)))
+ CFLAGS += -debug inline-debug-info
+endif
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py
new file mode 100644
index 000000000000..5c4dc219a106
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py
@@ -0,0 +1,88 @@
+"""
+Test breakpoint commands for a breakpoint ID with multiple locations.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class BreakpointLocationsTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureWindows("llvm.org/pr24528")
+ @expectedFailureAll(oslist=["linux"], compiler="clang", compiler_version=["=", "3.8"], archs=["i386"], debug_info="dwo")
+ def test(self):
+ """Test breakpoint enable/disable for a breakpoint ID with multiple locations."""
+ self.build()
+ self.breakpoint_locations_test()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside main().
+ self.line = line_number('main.c', '// Set break point at this line.')
+
+ def breakpoint_locations_test(self):
+ """Test breakpoint enable/disable for a breakpoint ID with multiple locations."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # This should create a breakpoint with 3 locations.
+ lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=3)
+
+ # The breakpoint list should show 3 locations.
+ self.expect("breakpoint list -f", "Breakpoint locations shown correctly",
+ substrs = ["1: file = 'main.c', line = %d, exact_match = 0, locations = 3" % self.line],
+ patterns = ["where = a.out`func_inlined .+unresolved, hit count = 0",
+ "where = a.out`main .+\[inlined\].+unresolved, hit count = 0"])
+
+ # The 'breakpoint disable 3.*' command should fail gracefully.
+ self.expect("breakpoint disable 3.*",
+ "Disabling an invalid breakpoint should fail gracefully",
+ error=True,
+ startstr = "error: '3' is not a valid breakpoint ID.")
+
+ # The 'breakpoint disable 1.*' command should disable all 3 locations.
+ self.expect("breakpoint disable 1.*", "All 3 breakpoint locatons disabled correctly",
+ startstr = "3 breakpoints disabled.")
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # We should not stopped on any breakpoint at all.
+ self.expect("process status", "No stopping on any disabled breakpoint",
+ patterns = ["^Process [0-9]+ exited with status = 0"])
+
+ # The 'breakpoint enable 1.*' command should enable all 3 breakpoints.
+ self.expect("breakpoint enable 1.*", "All 3 breakpoint locatons enabled correctly",
+ startstr = "3 breakpoints enabled.")
+
+ # The 'breakpoint disable 1.1' command should disable 1 location.
+ self.expect("breakpoint disable 1.1", "1 breakpoint locatons disabled correctly",
+ startstr = "1 breakpoints disabled.")
+
+ # Run the program againt. We should stop on the two breakpoint locations.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # Stopped once.
+ self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ["stop reason = breakpoint 1."])
+
+ # Continue the program, there should be another stop.
+ self.runCmd("process continue")
+
+ # Stopped again.
+ self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ["stop reason = breakpoint 1."])
+
+ # At this point, 1.1 has a hit count of 0 and the other a hit count of 1".
+ self.expect("breakpoint list -f", "The breakpoints should report correct hit counts",
+ patterns = ["1\.1: .+ unresolved, hit count = 0 +Options: disabled",
+ "1\.2: .+ resolved, hit count = 1",
+ "1\.3: .+ resolved, hit count = 1"])
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/main.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/main.c
new file mode 100644
index 000000000000..7ec3ded67b74
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/main.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+
+#define INLINE inline __attribute__((always_inline))
+
+int
+func_not_inlined (void)
+{
+ printf ("Called func_not_inlined.\n");
+ return 0;
+}
+
+INLINE int
+func_inlined (void)
+{
+ static int func_inline_call_count = 0;
+ printf ("Called func_inlined.\n");
+ ++func_inline_call_count;
+ printf ("Returning func_inlined call count: %d.\n", func_inline_call_count);
+ return func_inline_call_count; // Set break point at this line.
+}
+
+extern int func_inlined (void);
+
+int
+main (int argc, char **argv)
+{
+ printf ("Starting...\n");
+
+ int (*func_ptr) (void);
+ func_ptr = func_inlined;
+
+ int a = func_inlined();
+ printf("First call to func_inlined() returns: %d.\n", a);
+
+ func_not_inlined ();
+
+ func_ptr ();
+
+ printf("Last call to func_inlined() returns: %d.\n", func_inlined ());
+ return 0;
+}
+
+
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/Makefile
new file mode 100644
index 000000000000..457c4972f2d5
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp foo.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/TestBreakpointOptions.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/TestBreakpointOptions.py
new file mode 100644
index 000000000000..29afec202339
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/TestBreakpointOptions.py
@@ -0,0 +1,93 @@
+"""
+Test breakpoint command for different options.
+"""
+
+from __future__ import print_function
+
+
+
+import os
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class BreakpointOptionsTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test(self):
+ """Test breakpoint command for different options."""
+ self.build()
+ self.breakpoint_options_test()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside main().
+ self.line = line_number('main.cpp', '// Set break point at this line.')
+
+ def breakpoint_options_test(self):
+ """Test breakpoint command for different options."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # This should create a breakpoint with 1 locations.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, extra_options = "-K 1", num_expected_locations = 1)
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, extra_options = "-K 0", num_expected_locations = 1)
+
+ # This should create a breakpoint 0 locations.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, extra_options = "-m 0", num_expected_locations = 0)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # Stopped once.
+ self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ["stop reason = breakpoint 2."])
+
+ # Check the list of breakpoint.
+ self.expect("breakpoint list -f", "Breakpoint locations shown correctly",
+ substrs = ["1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % self.line,
+ "2: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % self.line,
+ "3: file = 'main.cpp', line = %d, exact_match = 1, locations = 0" % self.line])
+
+ # Continue the program, there should be another stop.
+ self.runCmd("process continue")
+
+ # Stopped again.
+ self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ["stop reason = breakpoint 1."])
+
+ # Continue the program, we should exit.
+ self.runCmd("process continue")
+
+ # We should exit.
+ self.expect("process status", "Process exited successfully",
+ patterns = ["^Process [0-9]+ exited with status = 0"])
+
+ def breakpoint_options_language_test(self):
+ """Test breakpoint command for language option."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # This should create a breakpoint with 1 locations.
+ lldbutil.run_break_set_by_symbol (self, 'ns::func', sym_exact=False, extra_options = "-L c++", num_expected_locations=1)
+
+ # This should create a breakpoint with 0 locations.
+ lldbutil.run_break_set_by_symbol (self, 'ns::func', sym_exact=False, extra_options = "-L c", num_expected_locations=0)
+ self.runCmd("settings set target.language c")
+ lldbutil.run_break_set_by_symbol (self, 'ns::func', sym_exact=False, num_expected_locations=0)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # Stopped once.
+ self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ["stop reason = breakpoint 1."])
+
+ # Continue the program, we should exit.
+ self.runCmd("process continue")
+
+ # We should exit.
+ self.expect("process status", "Process exited successfully",
+ patterns = ["^Process [0-9]+ exited with status = 0"])
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/foo.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/foo.cpp
new file mode 100644
index 000000000000..e5d0e09803e6
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/foo.cpp
@@ -0,0 +1,12 @@
+
+namespace ns {
+ int func(void)
+ {
+ return 0;
+ }
+}
+
+extern "C" int foo(void)
+{
+ return ns::func();
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/main.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/main.cpp
new file mode 100644
index 000000000000..363b90003d76
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/main.cpp
@@ -0,0 +1,8 @@
+// Set break point at this line.
+
+extern "C" int foo(void);
+int
+main (int argc, char **argv)
+{
+ return foo();
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/Makefile
new file mode 100644
index 000000000000..0ac34a186b25
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/Makefile
@@ -0,0 +1,7 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+EXE := CompDirSymLink
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/TestCompDirSymLink.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/TestCompDirSymLink.py
new file mode 100644
index 000000000000..e1de38bcad8c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/TestCompDirSymLink.py
@@ -0,0 +1,63 @@
+"""
+Test breakpoint command with AT_comp_dir set to symbolic link.
+"""
+from __future__ import print_function
+
+
+
+import os
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+import shutil
+
+
+_EXE_NAME = 'CompDirSymLink' # Must match Makefile
+_SRC_FILE = 'main.cpp'
+_COMP_DIR_SYM_LINK_PROP = 'plugin.symbol-file.dwarf.comp-dir-symlink-paths'
+
+class CompDirSymLinkTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside main().
+ self.line = line_number(_SRC_FILE, '// Set break point at this line.')
+ self.src_path = os.path.join(os.getcwd(), _SRC_FILE)
+
+ @skipIfHostWindows
+ def test_symlink_paths_set(self):
+ pwd_symlink = self.create_src_symlink()
+ self.doBuild(pwd_symlink)
+ self.runCmd("settings set %s %s" % (_COMP_DIR_SYM_LINK_PROP, pwd_symlink))
+ lldbutil.run_break_set_by_file_and_line(self, self.src_path, self.line)
+
+ @skipUnlessHostLinux
+ def test_symlink_paths_set_procselfcwd(self):
+ pwd_symlink = '/proc/self/cwd'
+ self.doBuild(pwd_symlink)
+ self.runCmd("settings set %s %s" % (_COMP_DIR_SYM_LINK_PROP, pwd_symlink))
+ lldbutil.run_break_set_by_file_and_line(self, self.src_path, self.line)
+
+ @skipIfHostWindows
+ def test_symlink_paths_unset(self):
+ pwd_symlink = self.create_src_symlink()
+ self.doBuild(pwd_symlink)
+ self.runCmd('settings clear ' + _COMP_DIR_SYM_LINK_PROP)
+ self.assertRaises(AssertionError, lldbutil.run_break_set_by_file_and_line, self, self.src_path, self.line)
+
+ def create_src_symlink(self):
+ pwd_symlink = os.path.join(os.getcwd(), 'pwd_symlink')
+ if os.path.exists(pwd_symlink):
+ os.unlink(pwd_symlink)
+ os.symlink(os.getcwd(), pwd_symlink)
+ self.addTearDownHook(lambda: os.remove(pwd_symlink))
+ return pwd_symlink
+
+ def doBuild(self, pwd_symlink):
+ self.build(None, None, {'PWD': pwd_symlink}, True)
+
+ exe = os.path.join(os.getcwd(), _EXE_NAME)
+ self.runCmd('file ' + exe, CURRENT_EXECUTABLE_SET)
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/main.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/main.cpp
new file mode 100644
index 000000000000..fef06a011e92
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/main.cpp
@@ -0,0 +1,13 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int main (int argc, char const *argv[])
+{
+ return 0; // Set break point at this line.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/Makefile
new file mode 100644
index 000000000000..f89b52a972e9
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/Makefile
@@ -0,0 +1,9 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+ifneq (,$(findstring icc,$(CC)))
+ CXXFLAGS += -debug inline-debug-info
+endif
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/TestConsecutiveBreakpoints.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/TestConsecutiveBreakpoints.py
new file mode 100644
index 000000000000..af6df3764829
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/TestConsecutiveBreakpoints.py
@@ -0,0 +1,59 @@
+"""
+Test continue from a breakpoint when there is a breakpoint on the next instruction also.
+"""
+
+from __future__ import print_function
+
+
+
+import unittest2
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+class ConsecutiveBreakpoitsTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureAll("llvm.org/pr23478", oslist = not_in(["macosx"]))
+ def test (self):
+ self.build ()
+ self.consecutive_breakpoints_tests()
+
+ def consecutive_breakpoints_tests(self):
+ exe = os.path.join (os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ breakpoint = target.BreakpointCreateBySourceRegex("Set breakpoint here", lldb.SBFileSpec("main.cpp"))
+ self.assertTrue(breakpoint and
+ breakpoint.GetNumLocations() == 1,
+ VALID_BREAKPOINT)
+
+ # Now launch the process, and do not stop at entry point.
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # We should be stopped at the first breakpoint
+ thread = process.GetThreadAtIndex(0)
+ self.assertEqual(thread.GetStopReason(), lldb.eStopReasonBreakpoint)
+
+ # Set breakpoint to the next instruction
+ frame = thread.GetFrameAtIndex(0)
+
+ address = frame.GetPCAddress()
+ instructions = target.ReadInstructions(address, 2)
+ self.assertTrue(len(instructions) == 2)
+ address = instructions[1].GetAddress()
+
+ target.BreakpointCreateByAddress(address.GetLoadAddress(target))
+ process.Continue()
+
+ # We should be stopped at the second breakpoint
+ thread = process.GetThreadAtIndex(0)
+ self.assertEqual(thread.GetStopReason(), lldb.eStopReasonBreakpoint)
+
+ # Run the process until termination
+ process.Continue()
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/main.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/main.cpp
new file mode 100644
index 000000000000..c1943f03dbf1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/main.cpp
@@ -0,0 +1,19 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int
+main(int argc, char const *argv[])
+{
+ int a = 0;
+ int b = 1;
+ a = b + 1; // Set breakpoint here
+ b = a + 1;
+ return 0;
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/Makefile
new file mode 100644
index 000000000000..f89b52a972e9
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/Makefile
@@ -0,0 +1,9 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+ifneq (,$(findstring icc,$(CC)))
+ CXXFLAGS += -debug inline-debug-info
+endif
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/TestCPPBreakpointLocations.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/TestCPPBreakpointLocations.py
new file mode 100644
index 000000000000..dea206b9e9d2
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/TestCPPBreakpointLocations.py
@@ -0,0 +1,62 @@
+"""
+Test lldb breakpoint ids.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class TestCPPBreakpointLocations(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureWindows("llvm.org/pr24764")
+ def test (self):
+ self.build ()
+ self.breakpoint_id_tests ()
+
+ def verify_breakpoint_locations(self, target, bp_dict):
+
+ name = bp_dict['name']
+ names = bp_dict['loc_names']
+ bp = target.BreakpointCreateByName (name)
+ self.assertTrue (bp.GetNumLocations() == len(names), "Make sure we find the right number of breakpoint locations")
+
+ bp_loc_names = list()
+ for bp_loc in bp:
+ bp_loc_names.append(bp_loc.GetAddress().GetFunction().GetName())
+
+ for name in names:
+ found = name in bp_loc_names
+ if not found:
+ print("Didn't find '%s' in: %s" % (name, bp_loc_names))
+ self.assertTrue (found, "Make sure we find all required locations")
+
+ def breakpoint_id_tests (self):
+
+ # Create a target by the debugger.
+ exe = os.path.join(os.getcwd(), "a.out")
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+ bp_dicts = [
+ { 'name' : 'func1', 'loc_names' : [ 'a::c::func1()', 'b::c::func1()'] },
+ { 'name' : 'func2', 'loc_names' : [ 'a::c::func2()', 'c::d::func2()'] },
+ { 'name' : 'func3', 'loc_names' : [ 'a::c::func3()', 'b::c::func3()', 'c::d::func3()'] },
+ { 'name' : 'c::func1', 'loc_names' : [ 'a::c::func1()', 'b::c::func1()'] },
+ { 'name' : 'c::func2', 'loc_names' : [ 'a::c::func2()'] },
+ { 'name' : 'c::func3', 'loc_names' : [ 'a::c::func3()', 'b::c::func3()'] },
+ { 'name' : 'a::c::func1', 'loc_names' : [ 'a::c::func1()'] },
+ { 'name' : 'b::c::func1', 'loc_names' : [ 'b::c::func1()'] },
+ { 'name' : 'c::d::func2', 'loc_names' : [ 'c::d::func2()'] },
+ { 'name' : 'a::c::func1()', 'loc_names' : [ 'a::c::func1()'] },
+ { 'name' : 'b::c::func1()', 'loc_names' : [ 'b::c::func1()'] },
+ { 'name' : 'c::d::func2()', 'loc_names' : [ 'c::d::func2()'] },
+ ]
+
+ for bp_dict in bp_dicts:
+ self.verify_breakpoint_locations(target, bp_dict)
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/main.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/main.cpp
new file mode 100644
index 000000000000..ef582aa36ebb
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/main.cpp
@@ -0,0 +1,77 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+#include <stdint.h>
+
+namespace a {
+ class c {
+ public:
+ c () {}
+ ~c() {}
+ void func1()
+ {
+ puts (__PRETTY_FUNCTION__);
+ }
+ void func2()
+ {
+ puts (__PRETTY_FUNCTION__);
+ }
+ void func3()
+ {
+ puts (__PRETTY_FUNCTION__);
+ }
+ };
+}
+
+namespace b {
+ class c {
+ public:
+ c () {}
+ ~c() {}
+ void func1()
+ {
+ puts (__PRETTY_FUNCTION__);
+ }
+ void func3()
+ {
+ puts (__PRETTY_FUNCTION__);
+ }
+ };
+}
+
+namespace c {
+ class d {
+ public:
+ d () {}
+ ~d() {}
+ void func2()
+ {
+ puts (__PRETTY_FUNCTION__);
+ }
+ void func3()
+ {
+ puts (__PRETTY_FUNCTION__);
+ }
+ };
+}
+
+int main (int argc, char const *argv[])
+{
+ a::c ac;
+ b::c bc;
+ c::d cd;
+ ac.func1();
+ ac.func2();
+ ac.func3();
+ bc.func1();
+ bc.func3();
+ cd.func2();
+ cd.func3();
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/TestCPPExceptionBreakpoint.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/TestCPPExceptionBreakpoint.py
new file mode 100644
index 000000000000..f7a19098b492
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/TestCPPExceptionBreakpoint.py
@@ -0,0 +1,48 @@
+"""
+Test that you can set breakpoint and hit the C++ language exception breakpoint
+"""
+
+from __future__ import print_function
+
+
+
+import os
+import re
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+import sys
+from lldbsuite.test.lldbtest import *
+
+class TestCPPExceptionBreakpoint (TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+ my_var = 10
+
+ @add_test_categories(['pyapi'])
+ @expectedFailureWindows("llvm.org/pr24538") # clang-cl does not support throw or catch
+ def test_cpp_exception_breakpoint(self):
+ """Test setting and hitting the C++ exception breakpoint."""
+ self.build()
+ self.do_cpp_exception_bkpt ()
+
+ def setUp (self):
+ TestBase.setUp(self)
+ self.main_source = "main.c"
+ self.main_source_spec = lldb.SBFileSpec(self.main_source)
+
+
+ def do_cpp_exception_bkpt (self):
+ exe = os.path.join(os.getcwd(), "a.out")
+ error = lldb.SBError()
+
+ self.target = self.dbg.CreateTarget(exe)
+ self.assertTrue(self.target, VALID_TARGET)
+
+ exception_bkpt = self.target.BreakpointCreateForException(lldb.eLanguageTypeC_plus_plus, False, True)
+ self.assertTrue (exception_bkpt.IsValid(), "Created exception breakpoint.")
+
+ process = self.target.LaunchSimple (None, None, self.get_process_working_directory())
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ thread_list = lldbutil.get_threads_stopped_at_breakpoint (process, exception_bkpt)
+ self.assertTrue (len(thread_list) == 1, "One thread stopped at the exception breakpoint.")
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/main.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/main.cpp
new file mode 100644
index 000000000000..76cb22735a71
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/main.cpp
@@ -0,0 +1,13 @@
+#include <exception>
+
+void
+throws_int ()
+{
+ throw 5;
+}
+
+int
+main ()
+{
+ throws_int();
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/dummy_target_breakpoints/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/dummy_target_breakpoints/Makefile
new file mode 100644
index 000000000000..7934cd5db427
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/dummy_target_breakpoints/Makefile
@@ -0,0 +1,9 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+ifneq (,$(findstring icc,$(CC)))
+ CFLAGS += -debug inline-debug-info
+endif
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/dummy_target_breakpoints/TestBreakpointsWithNoTargets.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/dummy_target_breakpoints/TestBreakpointsWithNoTargets.py
new file mode 100644
index 000000000000..f2693e6ed593
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/dummy_target_breakpoints/TestBreakpointsWithNoTargets.py
@@ -0,0 +1,67 @@
+"""
+Test breakpoint commands set before we have a target
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class BreakpointInDummyTarget (TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test(self):
+ """Test breakpoint set before we have a target. """
+ self.build()
+ self.dummy_breakpoint_test()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside main().
+ self.line = line_number('main.c', 'Set a breakpoint on this line.')
+ self.line2 = line_number ('main.c', 'Set another on this line.')
+
+ def dummy_breakpoint_test(self):
+ """Test breakpoint set before we have a target. """
+
+ # This should create a breakpoint with 3 locations.
+ lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=0)
+ lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line2, num_expected_locations=0)
+
+ # This is the function to remove breakpoints from the dummy target
+ # to get a clean slate for the next test case.
+ def cleanup():
+ self.runCmd('breakpoint delete -D -f', check=False)
+ self.runCmd('breakpoint list', check=False)
+
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # The breakpoint list should show 3 locations.
+ self.expect("breakpoint list -f", "Breakpoint locations shown correctly",
+ substrs = ["1: file = 'main.c', line = %d, exact_match = 0, locations = 1" % self.line,
+ "2: file = 'main.c', line = %d, exact_match = 0, locations = 1" % self.line2])
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # Stopped once.
+ self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ["stop reason = breakpoint 1."])
+
+ # Continue the program, there should be another stop.
+ self.runCmd("process continue")
+
+ # Stopped again.
+ self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ["stop reason = breakpoint 2."])
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/dummy_target_breakpoints/main.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/dummy_target_breakpoints/main.c
new file mode 100644
index 000000000000..e1f03237cd11
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/dummy_target_breakpoints/main.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+int
+main (int argc, char **argv)
+{
+ printf ("Set a breakpoint on this line.\n");
+
+ return 0; // Set another on this line.
+}
+
+
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/Makefile
new file mode 100644
index 000000000000..5b73ae626f34
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := int.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/TestInlinedBreakpoints.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/TestInlinedBreakpoints.py
new file mode 100644
index 000000000000..d04178bda78d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/TestInlinedBreakpoints.py
@@ -0,0 +1,57 @@
+"""
+Test that inlined breakpoints (breakpoint set on a file/line included from
+another source file) works correctly.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class InlinedBreakpointsTestCase(TestBase):
+ """Bug fixed: rdar://problem/8464339"""
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test_with_run_command(self):
+ """Test 'b basic_types.cpp:176' does break (where int.cpp includes basic_type.cpp)."""
+ self.build()
+ self.inlined_breakpoints()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside basic_type.cpp.
+ self.line = line_number('basic_type.cpp', '// Set break point at this line.')
+
+ def inlined_breakpoints(self):
+ """Test 'b basic_types.cpp:176' does break (where int.cpp includes basic_type.cpp)."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # With the inline-breakpoint-strategy, our file+line breakpoint should not resolve to a location.
+ self.runCmd('settings set target.inline-breakpoint-strategy headers')
+
+ # Set a breakpoint and fail because it is in an inlined source implemenation file
+ lldbutil.run_break_set_by_file_and_line (self, "basic_type.cpp", self.line, num_expected_locations=0)
+
+ # Now enable breakpoints in implementation files and see the breakpoint set succeed
+ self.runCmd('settings set target.inline-breakpoint-strategy always')
+ # And add hooks to restore the settings during tearDown().
+ self.addTearDownHook(
+ lambda: self.runCmd("settings set target.inline-breakpoint-strategy always"))
+
+ lldbutil.run_break_set_by_file_and_line (self, "basic_type.cpp", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ # And it should break at basic_type.cpp:176.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint',
+ 'basic_type.cpp:%d' % self.line])
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/basic_type.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/basic_type.cpp
new file mode 100644
index 000000000000..5881afe1f395
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/basic_type.cpp
@@ -0,0 +1,178 @@
+// This file must have the following defined before it is included:
+// T defined to the type to test (int, float, etc)
+// T_CSTR a C string representation of the type T ("int", "float")
+// T_VALUE_1 defined to a valid initializer value for TEST_TYPE (7 for int, 2.0 for float)
+// T_VALUE_2, T_VALUE_3, T_VALUE_4 defined to a valid initializer value for TEST_TYPE that is different from TEST_VALUE_1
+// T_PRINTF_FORMAT defined if T can be printed with printf
+//
+// An example for integers is below
+#if 0
+
+#define T int
+#define T_CSTR "int"
+#define T_VALUE_1 11001110
+#define T_VALUE_2 22002220
+#define T_VALUE_3 33003330
+#define T_VALUE_4 44044440
+#define T_PRINTF_FORMAT "%i"
+
+#include "basic_type.cpp"
+
+#endif
+
+class a_class
+{
+public:
+ a_class (const T& a, const T& b) :
+ m_a (a),
+ m_b (b)
+ {
+ }
+
+ ~a_class ()
+ {
+ }
+
+ const T&
+ get_a()
+ {
+ return m_a;
+ }
+
+ void
+ set_a (const T& a)
+ {
+ m_a = a;
+ }
+
+ const T&
+ get_b()
+ {
+ return m_b;
+ }
+
+ void
+ set_b (const T& b)
+ {
+ m_b = b;
+ }
+
+protected:
+ T m_a;
+ T m_b;
+};
+
+typedef struct a_struct_tag {
+ T a;
+ T b;
+} a_struct_t;
+
+
+typedef union a_union_zero_tag {
+ T a;
+ double a_double;
+} a_union_zero_t;
+
+typedef struct a_union_nonzero_tag {
+ double a_double;
+ a_union_zero_t u;
+} a_union_nonzero_t;
+
+
+#include <stdint.h>
+#include <stdio.h>
+
+void Puts(char const *msg)
+{
+ puts(msg);
+}
+
+int
+main (int argc, char const *argv[])
+{
+ T a = T_VALUE_1;
+ T* a_ptr = &a;
+ T& a_ref = a;
+ T a_array_bounded[2] = { T_VALUE_1, T_VALUE_2 };
+ T a_array_unbounded[] = { T_VALUE_1, T_VALUE_2 };
+
+ a_class a_class_instance (T_VALUE_1, T_VALUE_2);
+ a_class *a_class_ptr = &a_class_instance;
+ a_class &a_class_ref = a_class_instance;
+
+ a_struct_t a_struct = { T_VALUE_1, T_VALUE_2 };
+ a_struct_t *a_struct_ptr = &a_struct;
+ a_struct_t &a_struct_ref = a_struct;
+
+ // Create a union with type T at offset zero
+ a_union_zero_t a_union_zero;
+ a_union_zero.a = T_VALUE_1;
+ a_union_zero_t *a_union_zero_ptr = &a_union_zero;
+ a_union_zero_t &a_union_zero_ref = a_union_zero;
+
+ // Create a union with type T at a non-zero offset
+ a_union_nonzero_t a_union_nonzero;
+ a_union_nonzero.u.a = T_VALUE_1;
+ a_union_nonzero_t *a_union_nonzero_ptr = &a_union_nonzero;
+ a_union_nonzero_t &a_union_nonzero_ref = a_union_nonzero;
+
+ a_struct_t a_struct_array_bounded[2] = {{ T_VALUE_1, T_VALUE_2 }, { T_VALUE_3, T_VALUE_4 }};
+ a_struct_t a_struct_array_unbounded[] = {{ T_VALUE_1, T_VALUE_2 }, { T_VALUE_3, T_VALUE_4 }};
+ a_union_zero_t a_union_zero_array_bounded[2];
+ a_union_zero_array_bounded[0].a = T_VALUE_1;
+ a_union_zero_array_bounded[1].a = T_VALUE_2;
+ a_union_zero_t a_union_zero_array_unbounded[] = {{ T_VALUE_1 }, { T_VALUE_2 }};
+
+#ifdef T_PRINTF_FORMAT
+ printf ("%s: a = '" T_PRINTF_FORMAT "'\n", T_CSTR, a);
+ printf ("%s*: %p => *a_ptr = '" T_PRINTF_FORMAT "'\n", T_CSTR, a_ptr, *a_ptr);
+ printf ("%s&: @%p => a_ref = '" T_PRINTF_FORMAT "'\n", T_CSTR, &a_ref, a_ref);
+
+ printf ("%s[2]: a_array_bounded[0] = '" T_PRINTF_FORMAT "'\n", T_CSTR, a_array_bounded[0]);
+ printf ("%s[2]: a_array_bounded[1] = '" T_PRINTF_FORMAT "'\n", T_CSTR, a_array_bounded[1]);
+
+ printf ("%s[]: a_array_unbounded[0] = '" T_PRINTF_FORMAT "'\n", T_CSTR, a_array_unbounded[0]);
+ printf ("%s[]: a_array_unbounded[1] = '" T_PRINTF_FORMAT "'\n", T_CSTR, a_array_unbounded[1]);
+
+ printf ("(a_class) a_class_instance.m_a = '" T_PRINTF_FORMAT "'\n", a_class_instance.get_a());
+ printf ("(a_class) a_class_instance.m_b = '" T_PRINTF_FORMAT "'\n", a_class_instance.get_b());
+ printf ("(a_class*) a_class_ptr = %p, a_class_ptr->m_a = '" T_PRINTF_FORMAT "'\n", a_class_ptr, a_class_ptr->get_a());
+ printf ("(a_class*) a_class_ptr = %p, a_class_ptr->m_b = '" T_PRINTF_FORMAT "'\n", a_class_ptr, a_class_ptr->get_b());
+ printf ("(a_class&) a_class_ref = %p, a_class_ref.m_a = '" T_PRINTF_FORMAT "'\n", &a_class_ref, a_class_ref.get_a());
+ printf ("(a_class&) a_class_ref = %p, a_class_ref.m_b = '" T_PRINTF_FORMAT "'\n", &a_class_ref, a_class_ref.get_b());
+
+ printf ("(a_struct_t) a_struct.a = '" T_PRINTF_FORMAT "'\n", a_struct.a);
+ printf ("(a_struct_t) a_struct.b = '" T_PRINTF_FORMAT "'\n", a_struct.b);
+ printf ("(a_struct_t*) a_struct_ptr = %p, a_struct_ptr->a = '" T_PRINTF_FORMAT "'\n", a_struct_ptr, a_struct_ptr->a);
+ printf ("(a_struct_t*) a_struct_ptr = %p, a_struct_ptr->b = '" T_PRINTF_FORMAT "'\n", a_struct_ptr, a_struct_ptr->b);
+ printf ("(a_struct_t&) a_struct_ref = %p, a_struct_ref.a = '" T_PRINTF_FORMAT "'\n", &a_struct_ref, a_struct_ref.a);
+ printf ("(a_struct_t&) a_struct_ref = %p, a_struct_ref.b = '" T_PRINTF_FORMAT "'\n", &a_struct_ref, a_struct_ref.b);
+
+ printf ("(a_union_zero_t) a_union_zero.a = '" T_PRINTF_FORMAT "'\n", a_union_zero.a);
+ printf ("(a_union_zero_t*) a_union_zero_ptr = %p, a_union_zero_ptr->a = '" T_PRINTF_FORMAT "'\n", a_union_zero_ptr, a_union_zero_ptr->a);
+ printf ("(a_union_zero_t&) a_union_zero_ref = %p, a_union_zero_ref.a = '" T_PRINTF_FORMAT "'\n", &a_union_zero_ref, a_union_zero_ref.a);
+
+ printf ("(a_union_nonzero_t) a_union_nonzero.u.a = '" T_PRINTF_FORMAT "'\n", a_union_nonzero.u.a);
+ printf ("(a_union_nonzero_t*) a_union_nonzero_ptr = %p, a_union_nonzero_ptr->u.a = '" T_PRINTF_FORMAT "'\n", a_union_nonzero_ptr, a_union_nonzero_ptr->u.a);
+ printf ("(a_union_nonzero_t&) a_union_nonzero_ref = %p, a_union_nonzero_ref.u.a = '" T_PRINTF_FORMAT "'\n", &a_union_nonzero_ref, a_union_nonzero_ref.u.a);
+
+ printf ("(a_struct_t[2]) a_struct_array_bounded[0].a = '" T_PRINTF_FORMAT "'\n", a_struct_array_bounded[0].a);
+ printf ("(a_struct_t[2]) a_struct_array_bounded[0].b = '" T_PRINTF_FORMAT "'\n", a_struct_array_bounded[0].b);
+ printf ("(a_struct_t[2]) a_struct_array_bounded[1].a = '" T_PRINTF_FORMAT "'\n", a_struct_array_bounded[1].a);
+ printf ("(a_struct_t[2]) a_struct_array_bounded[1].b = '" T_PRINTF_FORMAT "'\n", a_struct_array_bounded[1].b);
+
+ printf ("(a_struct_t[]) a_struct_array_unbounded[0].a = '" T_PRINTF_FORMAT "'\n", a_struct_array_unbounded[0].a);
+ printf ("(a_struct_t[]) a_struct_array_unbounded[0].b = '" T_PRINTF_FORMAT "'\n", a_struct_array_unbounded[0].b);
+ printf ("(a_struct_t[]) a_struct_array_unbounded[1].a = '" T_PRINTF_FORMAT "'\n", a_struct_array_unbounded[1].a);
+ printf ("(a_struct_t[]) a_struct_array_unbounded[1].b = '" T_PRINTF_FORMAT "'\n", a_struct_array_unbounded[1].b);
+
+ printf ("(a_union_zero_t[2]) a_union_zero_array_bounded[0].a = '" T_PRINTF_FORMAT "'\n", a_union_zero_array_bounded[0].a);
+ printf ("(a_union_zero_t[2]) a_union_zero_array_bounded[1].a = '" T_PRINTF_FORMAT "'\n", a_union_zero_array_bounded[1].a);
+
+ printf ("(a_union_zero_t[]) a_union_zero_array_unbounded[0].a = '" T_PRINTF_FORMAT "'\n", a_union_zero_array_unbounded[0].a);
+ printf ("(a_union_zero_t[]) a_union_zero_array_unbounded[1].a = '" T_PRINTF_FORMAT "'\n", a_union_zero_array_unbounded[1].a);
+
+#endif
+ Puts("About to exit, break here to check values..."); // Set break point at this line.
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/int.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/int.cpp
new file mode 100644
index 000000000000..922398b1c6e3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/int.cpp
@@ -0,0 +1,9 @@
+#define T int
+#define T_CSTR "int"
+#define T_VALUE_1 11001110
+#define T_VALUE_2 22002220
+#define T_VALUE_3 33003330
+#define T_VALUE_4 44004440
+#define T_PRINTF_FORMAT "%i"
+
+#include "basic_type.cpp"
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/Makefile
new file mode 100644
index 000000000000..ad3cb3fadcde
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/Makefile
@@ -0,0 +1,7 @@
+LEVEL = ../../../make
+
+OBJC_SOURCES := main.m
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/TestObjCBreakpoints.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/TestObjCBreakpoints.py
new file mode 100644
index 000000000000..648a0f5ea07c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/TestObjCBreakpoints.py
@@ -0,0 +1,94 @@
+"""
+Test that objective-c constant strings are generated correctly by the expression
+parser.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+import shutil
+import subprocess
+
+@skipUnlessDarwin
+class TestObjCBreakpoints(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test_break(self):
+ """Test setting Objective C specific breakpoints (DWARF in .o files)."""
+ self.build()
+ self.setTearDownCleanup()
+ self.check_objc_breakpoints(False)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside main().
+ self.main_source = "main.m"
+ self.line = line_number(self.main_source, '// Set breakpoint here')
+
+ def check_category_breakpoints(self):
+ name_bp = self.target.BreakpointCreateByName ("myCategoryFunction")
+ selector_bp = self.target.BreakpointCreateByName ("myCategoryFunction", lldb.eFunctionNameTypeSelector, lldb.SBFileSpecList(), lldb.SBFileSpecList())
+ self.assertTrue(name_bp.GetNumLocations() == selector_bp.GetNumLocations(), 'Make sure setting a breakpoint by name "myCategoryFunction" sets a breakpoint even though it is in a category')
+ for bp_loc in selector_bp:
+ function_name = bp_loc.GetAddress().GetSymbol().GetName()
+ self.assertTrue(" myCategoryFunction]" in function_name, 'Make sure all function names have " myCategoryFunction]" in their names')
+
+ category_bp = self.target.BreakpointCreateByName ("-[MyClass(MyCategory) myCategoryFunction]")
+ stripped_bp = self.target.BreakpointCreateByName ("-[MyClass myCategoryFunction]")
+ stripped2_bp = self.target.BreakpointCreateByName ("[MyClass myCategoryFunction]")
+ self.assertTrue(category_bp.GetNumLocations() == 1, "Make sure we can set a breakpoint using a full objective C function name with the category included (-[MyClass(MyCategory) myCategoryFunction])")
+ self.assertTrue(stripped_bp.GetNumLocations() == 1, "Make sure we can set a breakpoint using a full objective C function name without the category included (-[MyClass myCategoryFunction])")
+ self.assertTrue(stripped2_bp.GetNumLocations() == 1, "Make sure we can set a breakpoint using a full objective C function name without the category included ([MyClass myCategoryFunction])")
+
+ def check_objc_breakpoints(self, have_dsym):
+ """Test constant string generation amd comparison by the expression parser."""
+
+ # Set debugger into synchronous mode
+ self.dbg.SetAsync(False)
+
+ # Create a target by the debugger.
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.target = self.dbg.CreateTarget(exe)
+ self.assertTrue(self.target, VALID_TARGET)
+
+ #----------------------------------------------------------------------
+ # Set breakpoints on all selectors whose name is "count". This should
+ # catch breakpoints that are both C functions _and_ anything whose
+ # selector is "count" because just looking at "count" we can't tell
+ # definitively if the name is a selector or a C function
+ #----------------------------------------------------------------------
+ name_bp = self.target.BreakpointCreateByName ("count")
+ selector_bp = self.target.BreakpointCreateByName ("count", lldb.eFunctionNameTypeSelector, lldb.SBFileSpecList(), lldb.SBFileSpecList())
+ self.assertTrue(name_bp.GetNumLocations() >= selector_bp.GetNumLocations(), 'Make sure we get at least the same amount of breakpoints if not more when setting by name "count"')
+ self.assertTrue(selector_bp.GetNumLocations() > 50, 'Make sure we find a lot of "count" selectors') # There are 93 on the latest MacOSX
+ for bp_loc in selector_bp:
+ function_name = bp_loc.GetAddress().GetSymbol().GetName()
+ self.assertTrue(" count]" in function_name, 'Make sure all function names have " count]" in their names')
+
+ #----------------------------------------------------------------------
+ # Set breakpoints on all selectors whose name is "isEqual:". This should
+ # catch breakpoints that are only ObjC selectors because no C function
+ # can end with a :
+ #----------------------------------------------------------------------
+ name_bp = self.target.BreakpointCreateByName ("isEqual:")
+ selector_bp = self.target.BreakpointCreateByName ("isEqual:", lldb.eFunctionNameTypeSelector, lldb.SBFileSpecList(), lldb.SBFileSpecList())
+ self.assertTrue(name_bp.GetNumLocations() == selector_bp.GetNumLocations(), 'Make sure setting a breakpoint by name "isEqual:" only sets selector breakpoints')
+ for bp_loc in selector_bp:
+ function_name = bp_loc.GetAddress().GetSymbol().GetName()
+ self.assertTrue(" isEqual:]" in function_name, 'Make sure all function names have " isEqual:]" in their names')
+
+ self.check_category_breakpoints()
+
+ if have_dsym:
+ shutil.rmtree(exe + ".dSYM")
+ self.assertTrue(subprocess.call(['/usr/bin/strip', '-Sx', exe]) == 0, 'stripping dylib succeeded')
+
+ # Check breakpoints again, this time using the symbol table only
+ self.check_category_breakpoints()
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/main.m b/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/main.m
new file mode 100644
index 000000000000..53567491219b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/main.m
@@ -0,0 +1,98 @@
+#import <Foundation/Foundation.h>
+#include <unistd.h>
+
+@interface MyClass : NSObject
+@end
+
+@implementation MyClass : NSObject
+@end
+
+@implementation MyClass (MyCategory)
+
+
+- (void) myCategoryFunction {
+ NSLog (@"myCategoryFunction");
+}
+
+@end
+
+
+
+int
+Test_Selector ()
+{
+ SEL sel = @selector(length);
+ printf("sel = %p\n", sel);
+ // Expressions to test here for selector:
+ // expression (char *)sel_getName(sel)
+ // The expression above should return "sel" as it should be just
+ // a uniqued C string pointer. We were seeing the result pointer being
+ // truncated with recent LLDBs.
+ return 0; // Break here for selector: tests
+}
+
+int
+Test_NSString (const char *program)
+{
+ NSString *str = [NSString stringWithFormat:@"Hello from '%s'", program];
+ NSLog(@"NSString instance: %@", str);
+ printf("str = '%s'\n", [str cStringUsingEncoding: [NSString defaultCStringEncoding]]);
+ printf("[str length] = %zu\n", (size_t)[str length]);
+ printf("[str description] = %s\n", [[str description] UTF8String]);
+ id str_id = str;
+ // Expressions to test here for NSString:
+ // expression (char *)sel_getName(sel)
+ // expression [str length]
+ // expression [str_id length]
+ // expression [str description]
+ // expression [str_id description]
+ // expression str.length
+ // expression str.description
+ // expression str = @"new"
+ // expression str = [NSString stringWithFormat: @"%cew", 'N']
+ return 0; // Break here for NSString tests
+}
+
+NSString *my_global_str = NULL;
+
+int
+Test_NSArray ()
+{
+ NSMutableArray *nil_mutable_array = nil;
+ NSArray *array1 = [NSArray arrayWithObjects: @"array1 object1", @"array1 object2", @"array1 object3", nil];
+ NSArray *array2 = [NSArray arrayWithObjects: array1, @"array2 object2", @"array2 object3", nil];
+ // Expressions to test here for NSArray:
+ // expression [nil_mutable_array count]
+ // expression [array1 count]
+ // expression array1.count
+ // expression [array2 count]
+ // expression array2.count
+ id obj;
+ // After each object at index call, use expression and validate object
+ obj = [array1 objectAtIndex: 0]; // Break here for NSArray tests
+ obj = [array1 objectAtIndex: 1];
+ obj = [array1 objectAtIndex: 2];
+
+ obj = [array2 objectAtIndex: 0];
+ obj = [array2 objectAtIndex: 1];
+ obj = [array2 objectAtIndex: 2];
+ NSUInteger count = [nil_mutable_array count];
+ return 0;
+}
+
+
+int main (int argc, char const *argv[])
+{
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+ Test_Selector(); // Set breakpoint here
+ Test_NSArray ();
+ Test_NSString (argv[0]);
+ MyClass *my_class = [[MyClass alloc] init];
+ [my_class myCategoryFunction];
+ printf("sizeof(id) = %zu\n", sizeof(id));
+ printf("sizeof(Class) = %zu\n", sizeof(Class));
+ printf("sizeof(SEL) = %zu\n", sizeof(SEL));
+
+ [pool release];
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/command_history/.categories b/packages/Python/lldbsuite/test/functionalities/command_history/.categories
new file mode 100644
index 000000000000..3a3f4df6416b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_history/.categories
@@ -0,0 +1 @@
+cmdline
diff --git a/packages/Python/lldbsuite/test/functionalities/command_history/TestCommandHistory.py b/packages/Python/lldbsuite/test/functionalities/command_history/TestCommandHistory.py
new file mode 100644
index 000000000000..312c91517f98
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_history/TestCommandHistory.py
@@ -0,0 +1,68 @@
+"""
+Test the command history mechanism
+"""
+
+from __future__ import print_function
+
+
+
+import os
+import lldb
+from lldbsuite.test.lldbtest import *
+
+class CommandHistoryTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @no_debug_info_test
+ def test_history(self):
+ self.runCmd('command history --clear', inHistory=False)
+ self.runCmd('breakpoint list', check=False, inHistory=True) #0
+ self.runCmd('register read', check=False, inHistory=True) #1
+ self.runCmd('apropos hello', check=False, inHistory=True) #2
+ self.runCmd('memory write', check=False, inHistory=True) #3
+ self.runCmd('log list', check=False, inHistory=True) #4
+ self.runCmd('disassemble', check=False, inHistory=True) #5
+ self.runCmd('expression 1', check=False, inHistory=True) #6
+ self.runCmd('type summary list -w default', check=False, inHistory=True) #7
+ self.runCmd('version', check=False, inHistory=True) #8
+ self.runCmd('frame select 1', check=False, inHistory=True) #9
+
+ self.expect ("command history -s 3 -c 3", inHistory=True,
+ substrs = ['3: memory write','4: log list','5: disassemble'])
+
+ self.expect ("command history -s 3 -e 3", inHistory=True,
+ substrs = ['3: memory write'])
+
+ self.expect ("command history -s 6 -e 7", inHistory=True,
+ substrs = ['6: expression 1','7: type summary list -w default'])
+
+ self.expect ("command history -c 2", inHistory=True,
+ substrs = ['0: breakpoint list','1: register read'])
+
+ self.expect ("command history -e 3 -c 1", inHistory=True,
+ substrs = ['3: memory write'])
+
+ self.expect ("command history -e 2", inHistory=True,
+ substrs = ['0: breakpoint list','1: register read','2: apropos hello'])
+
+ self.expect ("command history -s 12", inHistory=True,
+ substrs = ['12: command history -s 6 -e 7','13: command history -c 2','14: command history -e 3 -c 1','15: command history -e 2','16: command history -s 12'])
+
+ self.expect ("command history -s end -c 3", inHistory=True,
+ substrs = ['15: command history -e 2','16: command history -s 12','17: command history -s end -c 3'])
+
+ self.expect ("command history -s end -e 15", inHistory=True,
+ substrs = ['15: command history -e 2','16: command history -s 12','17: command history -s end -c 3','command history -s end -e 15'])
+
+ self.expect ("command history -s 5 -c 1", inHistory=True,
+ substrs = ['5: disassemble'])
+
+ self.expect ("command history -c 1 -s 5", inHistory=True,
+ substrs = ['5: disassemble'])
+
+ self.expect ("command history -c 1 -e 3", inHistory=True,
+ substrs = ['3: memory write'])
+
+ self.expect ("command history -c 1 -e 3 -s 5",error=True, inHistory=True,
+ substrs = ['error: --count, --start-index and --end-index cannot be all specified in the same invocation'])
diff --git a/packages/Python/lldbsuite/test/functionalities/command_regex/.categories b/packages/Python/lldbsuite/test/functionalities/command_regex/.categories
new file mode 100644
index 000000000000..3a3f4df6416b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_regex/.categories
@@ -0,0 +1 @@
+cmdline
diff --git a/packages/Python/lldbsuite/test/functionalities/command_regex/TestCommandRegex.py b/packages/Python/lldbsuite/test/functionalities/command_regex/TestCommandRegex.py
new file mode 100644
index 000000000000..2c48efa863b4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_regex/TestCommandRegex.py
@@ -0,0 +1,56 @@
+"""
+Test lldb 'commands regex' command which allows the user to create a regular expression command.
+"""
+
+from __future__ import print_function
+
+
+
+import os
+import lldb
+from lldbsuite.test.lldbtest import *
+
+class CommandRegexTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureHostWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @no_debug_info_test
+ def test_command_regex(self):
+ """Test a simple scenario of 'command regex' invocation and subsequent use."""
+ import pexpect
+ prompt = "(lldb) "
+ regex_prompt = "Enter one of more sed substitution commands in the form: 's/<regex>/<subst>/'.\r\nTerminate the substitution list with an empty line.\r\n"
+ regex_prompt1 = "\r\n"
+
+ child = pexpect.spawn('%s %s' % (lldbtest_config.lldbExec, self.lldbOption))
+ # Turn on logging for what the child sends back.
+ if self.TraceOn():
+ child.logfile_read = sys.stdout
+ # So that the spawned lldb session gets shutdown durng teardown.
+ self.child = child
+
+ # Substitute 'Help!' for 'help' using the 'commands regex' mechanism.
+ child.expect_exact(prompt)
+ child.sendline("command regex 'Help__'")
+ child.expect_exact(regex_prompt)
+ child.sendline('s/^$/help/')
+ child.expect_exact(regex_prompt1)
+ child.sendline('')
+ child.expect_exact(prompt)
+ # Help!
+ child.sendline('Help__')
+ # If we see the familiar 'help' output, the test is done.
+ child.expect('Debugger commands:')
+ # Try and incorrectly remove "Help__" using "command unalias" and verify we fail
+ child.sendline('command unalias Help__')
+ child.expect_exact("error: 'Help__' is not an alias, it is a debugger command which can be removed using the 'command delete' command")
+ child.expect_exact(prompt)
+
+ # Delete the regex command using "command delete"
+ child.sendline('command delete Help__')
+ child.expect_exact(prompt)
+ # Verify the command was removed
+ child.sendline('Help__')
+ child.expect_exact("error: 'Help__' is not a valid command")
+ child.expect_exact(prompt)
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/.categories b/packages/Python/lldbsuite/test/functionalities/command_script/.categories
new file mode 100644
index 000000000000..3a3f4df6416b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/.categories
@@ -0,0 +1 @@
+cmdline
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/Makefile b/packages/Python/lldbsuite/test/functionalities/command_script/Makefile
new file mode 100644
index 000000000000..8a7102e347af
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/TestCommandScript.py b/packages/Python/lldbsuite/test/functionalities/command_script/TestCommandScript.py
new file mode 100644
index 000000000000..542ee7a1e5f3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/TestCommandScript.py
@@ -0,0 +1,142 @@
+"""
+Test lldb Python commands.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+
+class CmdPythonTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test (self):
+ self.build ()
+ self.pycmd_tests ()
+
+ def pycmd_tests (self):
+ self.runCmd("command source py_import")
+
+ # Verify command that specifies eCommandRequiresTarget returns failure
+ # without a target.
+ self.expect('targetname',
+ substrs = ['a.out'], matching=False, error=True)
+
+ exe = os.path.join (os.getcwd(), "a.out")
+ self.expect("file " + exe,
+ patterns = [ "Current executable set to .*a.out" ])
+
+ self.expect('targetname',
+ substrs = ['a.out'], matching=True, error=False)
+
+ # This is the function to remove the custom commands in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('command script delete welcome', check=False)
+ self.runCmd('command script delete targetname', check=False)
+ self.runCmd('command script delete longwait', check=False)
+ self.runCmd('command script delete mysto', check=False)
+ self.runCmd('command script delete tell_sync', check=False)
+ self.runCmd('command script delete tell_async', check=False)
+ self.runCmd('command script delete tell_curr', check=False)
+ self.runCmd('command script delete bug11569', check=False)
+ self.runCmd('command script delete takes_exe_ctx', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # Interact with debugger in synchronous mode
+ self.setAsync(False)
+
+ # We don't want to display the stdout if not in TraceOn() mode.
+ if not self.TraceOn():
+ self.HideStdout()
+
+ self.expect('welcome Enrico',
+ substrs = ['Hello Enrico, welcome to LLDB']);
+
+ self.expect("help welcome",
+ substrs = ['Just a docstring for welcome_impl',
+ 'A command that says hello to LLDB users'])
+
+ self.expect("help",
+ substrs = ['For more information run',
+ 'welcome'])
+
+ self.expect("help -a",
+ substrs = ['For more information run',
+ 'welcome'])
+
+ self.expect("help -u", matching=False,
+ substrs = ['For more information run'])
+
+ self.runCmd("command script delete welcome");
+
+ self.expect('welcome Enrico', matching=False, error=True,
+ substrs = ['Hello Enrico, welcome to LLDB']);
+
+ self.expect('targetname fail', error=True,
+ substrs = ['a test for error in command'])
+
+ self.expect('command script list',
+ substrs = ['targetname',
+ 'For more information run'])
+
+ self.expect("help targetname",
+ substrs = ['This', 'command', 'takes', '\'raw\'', 'input',
+ 'quote', 'stuff'])
+
+ self.expect("longwait",
+ substrs = ['Done; if you saw the delays I am doing OK'])
+
+ self.runCmd("b main")
+ self.runCmd("run")
+ self.runCmd("mysto 3")
+ self.expect("frame variable array",
+ substrs = ['[0] = 79630','[1] = 388785018','[2] = 0'])
+ self.runCmd("mysto 3")
+ self.expect("frame variable array",
+ substrs = ['[0] = 79630','[4] = 388785018','[5] = 0'])
+
+# we cannot use the stepover command to check for async execution mode since LLDB
+# seems to get confused when events start to queue up
+ self.expect("tell_sync",
+ substrs = ['running sync'])
+ self.expect("tell_async",
+ substrs = ['running async'])
+ self.expect("tell_curr",
+ substrs = ['I am running sync'])
+
+# check that the execution context is passed in to commands that ask for it
+ self.expect("takes_exe_ctx", substrs = ["a.out"])
+
+ # Test that a python command can redefine itself
+ self.expect('command script add -f foobar welcome -h "just some help"')
+
+ self.runCmd("command script clear")
+
+ # Test that re-defining an existing command works
+ self.runCmd('command script add my_command --class welcome.WelcomeCommand')
+ self.expect('my_command Blah', substrs = ['Hello Blah, welcome to LLDB'])
+
+ self.runCmd('command script add my_command --class welcome.TargetnameCommand')
+ self.expect('my_command', substrs = ['a.out'])
+
+ self.runCmd("command script clear")
+
+ self.expect('command script list', matching=False,
+ substrs = ['targetname',
+ 'longwait'])
+
+ self.expect('command script add -f foobar frame', error=True,
+ substrs = ['cannot add command'])
+
+ # http://llvm.org/bugs/show_bug.cgi?id=11569
+ # LLDBSwigPythonCallCommand crashes when a command script returns an object
+ self.runCmd('command script add -f bug11569 bug11569')
+ # This should not crash.
+ self.runCmd('bug11569', check=False)
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/bug11569.py b/packages/Python/lldbsuite/test/functionalities/command_script/bug11569.py
new file mode 100644
index 000000000000..93897d88098f
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/bug11569.py
@@ -0,0 +1,7 @@
+def bug11569(debugger, args, result, dict):
+ """
+ http://llvm.org/bugs/show_bug.cgi?id=11569
+ LLDBSwigPythonCallCommand crashes when a command script returns an object.
+ """
+ return ["return", "a", "non-string", "should", "not", "crash", "LLDB"];
+
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/import/Makefile b/packages/Python/lldbsuite/test/functionalities/command_script/import/Makefile
new file mode 100644
index 000000000000..9374aef487fe
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/import/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+EXE := hello_world
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/import/TestImport.py b/packages/Python/lldbsuite/test/functionalities/command_script/import/TestImport.py
new file mode 100644
index 000000000000..691045ae82ed
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/import/TestImport.py
@@ -0,0 +1,73 @@
+"""Test custom import command to import files by path."""
+
+from __future__ import print_function
+
+
+
+import os, sys, time
+import lldb
+from lldbsuite.test.lldbtest import *
+
+class ImportTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @add_test_categories(['pyapi'])
+ @no_debug_info_test
+ def test_import_command(self):
+ """Import some Python scripts by path and test them"""
+ self.run_test()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ def run_test(self):
+ """Import some Python scripts by path and test them."""
+
+ # This is the function to remove the custom commands in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('command script delete foo2cmd', check=False)
+ self.runCmd('command script delete foocmd', check=False)
+ self.runCmd('command script delete foobarcmd', check=False)
+ self.runCmd('command script delete barcmd', check=False)
+ self.runCmd('command script delete barothercmd', check=False)
+ self.runCmd('command script delete TPcommandA', check=False)
+ self.runCmd('command script delete TPcommandB', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.runCmd("command script import ./foo/foo.py --allow-reload")
+ self.runCmd("command script import ./foo/foo2.py --allow-reload")
+ self.runCmd("command script import ./foo/bar/foobar.py --allow-reload")
+ self.runCmd("command script import ./bar/bar.py --allow-reload")
+
+ self.expect("command script import ./nosuchfile.py",
+ error=True, startstr='error: module importing failed')
+ self.expect("command script import ./nosuchfolder/",
+ error=True, startstr='error: module importing failed')
+ self.expect("command script import ./foo/foo.py", error=False)
+
+ self.runCmd("command script import --allow-reload ./thepackage")
+ self.expect("TPcommandA",substrs=["hello world A"])
+ self.expect("TPcommandB",substrs=["hello world B"])
+
+ self.runCmd("script import dummymodule")
+ self.expect("command script import ./dummymodule.py", error=False)
+ self.expect("command script import --allow-reload ./dummymodule.py", error=False)
+
+ self.runCmd("command script add -f foo.foo_function foocmd")
+ self.runCmd("command script add -f foobar.foo_function foobarcmd")
+ self.runCmd("command script add -f bar.bar_function barcmd")
+ self.expect("foocmd hello",
+ substrs = ['foo says', 'hello'])
+ self.expect("foo2cmd hello",
+ substrs = ['foo2 says', 'hello'])
+ self.expect("barcmd hello",
+ substrs = ['barutil says', 'bar told me', 'hello'])
+ self.expect("barothercmd hello",
+ substrs = ['barutil says', 'bar told me', 'hello'])
+ self.expect("foobarcmd hello",
+ substrs = ['foobar says', 'hello'])
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/import/bar/bar.py b/packages/Python/lldbsuite/test/functionalities/command_script/import/bar/bar.py
new file mode 100644
index 000000000000..bbc41f3b217d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/import/bar/bar.py
@@ -0,0 +1,12 @@
+from __future__ import print_function
+
+def bar_function(debugger, args, result, dict):
+ global UtilityModule
+ print(UtilityModule.barutil_function("bar told me " + args), file=result)
+ return None
+
+def __lldb_init_module(debugger, session_dict):
+ global UtilityModule
+ UtilityModule = __import__("barutil")
+ debugger.HandleCommand("command script add -f bar.bar_function barothercmd")
+ return None \ No newline at end of file
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/import/bar/barutil.py b/packages/Python/lldbsuite/test/functionalities/command_script/import/bar/barutil.py
new file mode 100644
index 000000000000..0d3d2eb1b2d7
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/import/bar/barutil.py
@@ -0,0 +1,2 @@
+def barutil_function(x):
+ return "barutil says: " + x
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/import/dummymodule.py b/packages/Python/lldbsuite/test/functionalities/command_script/import/dummymodule.py
new file mode 100644
index 000000000000..dcc724ec9c23
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/import/dummymodule.py
@@ -0,0 +1,2 @@
+def no_useful_code(foo):
+ return foo
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/import/foo/bar/foobar.py b/packages/Python/lldbsuite/test/functionalities/command_script/import/foo/bar/foobar.py
new file mode 100644
index 000000000000..659ded22c901
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/import/foo/bar/foobar.py
@@ -0,0 +1,5 @@
+from __future__ import print_function
+
+def foo_function(debugger, args, result, dict):
+ print("foobar says " + args, file=result)
+ return None
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/import/foo/foo.py b/packages/Python/lldbsuite/test/functionalities/command_script/import/foo/foo.py
new file mode 100644
index 000000000000..51cc0c3bab19
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/import/foo/foo.py
@@ -0,0 +1,5 @@
+from __future__ import print_function
+
+def foo_function(debugger, args, result, dict):
+ print("foo says " + args, file=result)
+ return None
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/import/foo/foo2.py b/packages/Python/lldbsuite/test/functionalities/command_script/import/foo/foo2.py
new file mode 100644
index 000000000000..6863454ca6ef
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/import/foo/foo2.py
@@ -0,0 +1,9 @@
+from __future__ import print_function
+
+def foo2_function(debugger, args, result, dict):
+ print("foo2 says " + args, file=result)
+ return None
+
+def __lldb_init_module(debugger, session_dict):
+ debugger.HandleCommand("command script add -f foo2.foo2_function foo2cmd")
+ return None \ No newline at end of file
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/import/main.c b/packages/Python/lldbsuite/test/functionalities/command_script/import/main.c
new file mode 100644
index 000000000000..dffc8c77b04c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/import/main.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int main(int argc, char const *argv[]) {
+ printf("Hello world.\n"); // Set break point at this line.
+ if (argc == 1)
+ return 0;
+
+ // Waiting to be attached by the debugger, otherwise.
+ char line[100];
+ while (fgets(line, sizeof(line), stdin)) { // Waiting to be attached...
+ printf("input line=>%s\n", line);
+ }
+
+ printf("Exiting now\n");
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/import/rdar-12586188/Makefile b/packages/Python/lldbsuite/test/functionalities/command_script/import/rdar-12586188/Makefile
new file mode 100644
index 000000000000..7913aaa4b746
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/import/rdar-12586188/Makefile
@@ -0,0 +1,3 @@
+LEVEL = ../../../../make
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/import/rdar-12586188/TestRdar12586188.py b/packages/Python/lldbsuite/test/functionalities/command_script/import/rdar-12586188/TestRdar12586188.py
new file mode 100644
index 000000000000..9800a08c06de
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/import/rdar-12586188/TestRdar12586188.py
@@ -0,0 +1,31 @@
+"""Check that we handle an ImportError in a special way when command script importing files."""
+
+from __future__ import print_function
+
+
+
+import os, sys, time
+import lldb
+from lldbsuite.test.lldbtest import *
+
+class Rdar12586188TestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @add_test_categories(['pyapi'])
+ @no_debug_info_test
+ def test_rdar12586188_command(self):
+ """Check that we handle an ImportError in a special way when command script importing files."""
+ self.run_test()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ def run_test(self):
+ """Check that we handle an ImportError in a special way when command script importing files."""
+
+ self.expect("command script import ./fail12586188.py --allow-reload",
+ error=True, substrs = ['raise ImportError("I do not want to be imported")'])
+ self.expect("command script import ./fail212586188.py --allow-reload",
+ error=True, substrs = ['raise ValueError("I do not want to be imported")'])
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/import/rdar-12586188/fail12586188.py b/packages/Python/lldbsuite/test/functionalities/command_script/import/rdar-12586188/fail12586188.py
new file mode 100644
index 000000000000..add85a73f853
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/import/rdar-12586188/fail12586188.py
@@ -0,0 +1,4 @@
+def f(x):
+ return x + 1
+
+raise ImportError("I do not want to be imported")
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/import/rdar-12586188/fail212586188.py b/packages/Python/lldbsuite/test/functionalities/command_script/import/rdar-12586188/fail212586188.py
new file mode 100644
index 000000000000..1549a036590f
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/import/rdar-12586188/fail212586188.py
@@ -0,0 +1,4 @@
+def f(x):
+ return x + 1
+
+raise ValueError("I do not want to be imported")
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/import/thepackage/TPunitA.py b/packages/Python/lldbsuite/test/functionalities/command_script/import/thepackage/TPunitA.py
new file mode 100644
index 000000000000..fb65305d205c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/import/thepackage/TPunitA.py
@@ -0,0 +1,6 @@
+
+import six
+
+def command(debugger, command, result, internal_dict):
+ result.PutCString(six.u("hello world A"))
+ return None
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/import/thepackage/TPunitB.py b/packages/Python/lldbsuite/test/functionalities/command_script/import/thepackage/TPunitB.py
new file mode 100644
index 000000000000..60b31b89f6da
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/import/thepackage/TPunitB.py
@@ -0,0 +1,6 @@
+
+import six
+
+def command(debugger, command, result, internal_dict):
+ result.PutCString(six.u("hello world B"))
+ return None
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/import/thepackage/__init__.py b/packages/Python/lldbsuite/test/functionalities/command_script/import/thepackage/__init__.py
new file mode 100644
index 000000000000..faa4e3b0cbff
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/import/thepackage/__init__.py
@@ -0,0 +1,6 @@
+import TPunitA
+import TPunitB
+
+def __lldb_init_module(debugger,*args):
+ debugger.HandleCommand("command script add -f thepackage.TPunitA.command TPcommandA")
+ debugger.HandleCommand("command script add -f thepackage.TPunitB.command TPcommandB")
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/main.cpp b/packages/Python/lldbsuite/test/functionalities/command_script/main.cpp
new file mode 100644
index 000000000000..0b24cb73a619
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/main.cpp
@@ -0,0 +1,70 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <cstdlib>
+#include <cstring>
+#include <string>
+#include <fstream>
+#include <iostream>
+
+int
+product (int x, int y)
+{
+ int result = x * y;
+ return result;
+}
+
+int
+sum (int a, int b)
+{
+ int result = a + b;
+ return result;
+}
+
+int
+strange_max (int m, int n)
+{
+ if (m > n)
+ return m;
+ else if (n > m)
+ return n;
+ else
+ return 0;
+}
+
+int
+foo (int i, int j)
+{
+ if (strange_max (i, j) == i)
+ return product (i, j);
+ else if (strange_max (i, j) == j)
+ return sum (i, j);
+ else
+ return product (sum (i, i), sum (j, j));
+}
+
+int
+main(int argc, char const *argv[])
+{
+
+ int array[9];
+ memset(array,0,9*sizeof(int));
+
+ array[0] = foo (1238, 78392);
+ array[1] = foo (379265, 23674);
+ array[2] = foo (872934, 234);
+ array[3] = foo (1238, 78392);
+ array[4] = foo (379265, 23674);
+ array[5] = foo (872934, 234);
+ array[6] = foo (1238, 78392);
+ array[7] = foo (379265, 23674);
+ array[8] = foo (872934, 234);
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/mysto.py b/packages/Python/lldbsuite/test/functionalities/command_script/mysto.py
new file mode 100644
index 000000000000..656cd1502930
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/mysto.py
@@ -0,0 +1,23 @@
+from __future__ import print_function
+
+import lldb
+import sys
+import os
+import time
+
+def StepOver(debugger, args, result, dict):
+ """
+ Step over a given number of times instead of only just once
+ """
+ arg_split = args.split(" ")
+ print(type(arg_split))
+ count = int(arg_split[0])
+ for i in range(0,count):
+ debugger.GetSelectedTarget().GetProcess().GetSelectedThread().StepOver(lldb.eOnlyThisThread)
+ print("step<%d>"%i)
+
+def __lldb_init_module(debugger, session_dict):
+ # by default, --synchronicity is set to synchronous
+ debugger.HandleCommand("command script add -f mysto.StepOver mysto")
+ return None
+
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/py_import b/packages/Python/lldbsuite/test/functionalities/command_script/py_import
new file mode 100644
index 000000000000..169daacc1a83
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/py_import
@@ -0,0 +1,12 @@
+script import sys, os
+script sys.path.append(os.path.join(os.getcwd(), os.pardir))
+script import welcome
+script import bug11569
+command script add welcome --class welcome.WelcomeCommand
+command script add targetname --class welcome.TargetnameCommand
+command script add longwait --function welcome.print_wait_impl
+command script import mysto.py --allow-reload
+command script add tell_sync --function welcome.check_for_synchro --synchronicity sync
+command script add tell_async --function welcome.check_for_synchro --synchronicity async
+command script add tell_curr --function welcome.check_for_synchro --synchronicity curr
+command script add takes_exe_ctx --function welcome.takes_exe_ctx
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/welcome.py b/packages/Python/lldbsuite/test/functionalities/command_script/welcome.py
new file mode 100644
index 000000000000..5dbf09fbbec2
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/welcome.py
@@ -0,0 +1,46 @@
+from __future__ import print_function
+import lldb, sys
+
+class WelcomeCommand(object):
+ def __init__(self, debugger, session_dict):
+ pass
+
+ def get_short_help(self):
+ return "Just a docstring for welcome_impl\nA command that says hello to LLDB users"
+
+ def __call__(self, debugger, args, exe_ctx, result):
+ print('Hello ' + args + ', welcome to LLDB', file=result);
+ return None;
+
+class TargetnameCommand(object):
+ def __init__(self, debugger, session_dict):
+ pass
+
+ def __call__(self, debugger, args, exe_ctx, result):
+ target = debugger.GetSelectedTarget()
+ file = target.GetExecutable()
+ print('Current target ' + file.GetFilename(), file=result)
+ if args == 'fail':
+ result.SetError('a test for error in command')
+
+ def get_flags(self):
+ return lldb.eCommandRequiresTarget
+
+def print_wait_impl(debugger, args, result, dict):
+ result.SetImmediateOutputFile(sys.stdout)
+ print('Trying to do long task..', file=result)
+ import time
+ time.sleep(1)
+ print('Still doing long task..', file=result)
+ time.sleep(1)
+ print('Done; if you saw the delays I am doing OK', file=result)
+
+def check_for_synchro(debugger, args, result, dict):
+ if debugger.GetAsync() == True:
+ print('I am running async', file=result)
+ if debugger.GetAsync() == False:
+ print('I am running sync', file=result)
+
+def takes_exe_ctx(debugger, args, exe_ctx, result, dict):
+ print(str(exe_ctx.GetTarget()), file=result)
+
diff --git a/packages/Python/lldbsuite/test/functionalities/command_source/.categories b/packages/Python/lldbsuite/test/functionalities/command_source/.categories
new file mode 100644
index 000000000000..3a3f4df6416b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_source/.categories
@@ -0,0 +1 @@
+cmdline
diff --git a/packages/Python/lldbsuite/test/functionalities/command_source/.lldb b/packages/Python/lldbsuite/test/functionalities/command_source/.lldb
new file mode 100644
index 000000000000..c544523832e7
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_source/.lldb
@@ -0,0 +1 @@
+script import my
diff --git a/packages/Python/lldbsuite/test/functionalities/command_source/TestCommandSource.py b/packages/Python/lldbsuite/test/functionalities/command_source/TestCommandSource.py
new file mode 100644
index 000000000000..013803e698af
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_source/TestCommandSource.py
@@ -0,0 +1,36 @@
+"""
+Test that lldb command "command source" works correctly.
+
+See also http://llvm.org/viewvc/llvm-project?view=rev&revision=109673.
+"""
+
+from __future__ import print_function
+
+
+
+import os, sys
+import lldb
+from lldbsuite.test.lldbtest import *
+
+class CommandSourceTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @no_debug_info_test
+ def test_command_source(self):
+ """Test that lldb command "command source" works correctly."""
+
+ # Sourcing .lldb in the current working directory, which in turn imports
+ # the "my" package that defines the date() function.
+ self.runCmd("command source .lldb")
+
+ # Python should evaluate "my.date()" successfully.
+ command_interpreter = self.dbg.GetCommandInterpreter()
+ self.assertTrue(command_interpreter, VALID_COMMAND_INTERPRETER)
+ result = lldb.SBCommandReturnObject()
+ command_interpreter.HandleCommand("script my.date()", result)
+
+ import datetime
+ self.expect(result.GetOutput(), "script my.date() runs successfully",
+ exe=False,
+ substrs = [str(datetime.date.today())])
diff --git a/packages/Python/lldbsuite/test/functionalities/command_source/my.py b/packages/Python/lldbsuite/test/functionalities/command_source/my.py
new file mode 100644
index 000000000000..cb2fd012e4bd
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_source/my.py
@@ -0,0 +1,6 @@
+from __future__ import print_function
+
+def date():
+ import datetime
+ today = datetime.date.today()
+ print(today)
diff --git a/packages/Python/lldbsuite/test/functionalities/completion/.categories b/packages/Python/lldbsuite/test/functionalities/completion/.categories
new file mode 100644
index 000000000000..3a3f4df6416b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/completion/.categories
@@ -0,0 +1 @@
+cmdline
diff --git a/packages/Python/lldbsuite/test/functionalities/completion/Makefile b/packages/Python/lldbsuite/test/functionalities/completion/Makefile
new file mode 100644
index 000000000000..8a7102e347af
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/completion/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py b/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py
new file mode 100644
index 000000000000..d7aab03c0830
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py
@@ -0,0 +1,324 @@
+"""
+Test the lldb command line completion mechanism.
+"""
+
+from __future__ import print_function
+
+
+
+import os
+import lldb
+from lldbsuite.test.lldbtest import *
+
+class CommandLineCompletionTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @classmethod
+ def classCleanup(cls):
+ """Cleanup the test byproducts."""
+ try:
+ os.remove("child_send.txt")
+ os.remove("child_read.txt")
+ except:
+ pass
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_at(self):
+ """Test that 'at' completes to 'attach '."""
+ self.complete_from_to('at', 'attach ')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_de(self):
+ """Test that 'de' completes to 'detach '."""
+ self.complete_from_to('de', 'detach ')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_process_attach_dash_dash_con(self):
+ """Test that 'process attach --con' completes to 'process attach --continue '."""
+ self.complete_from_to('process attach --con', 'process attach --continue ')
+
+ # <rdar://problem/11052829>
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_infinite_loop_while_completing(self):
+ """Test that 'process print hello\' completes to itself and does not infinite loop."""
+ self.complete_from_to('process print hello\\', 'process print hello\\',
+ turn_off_re_match=True)
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_watchpoint_co(self):
+ """Test that 'watchpoint co' completes to 'watchpoint command '."""
+ self.complete_from_to('watchpoint co', 'watchpoint command ')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_watchpoint_command_space(self):
+ """Test that 'watchpoint command ' completes to ['Available completions:', 'add', 'delete', 'list']."""
+ self.complete_from_to('watchpoint command ', ['Available completions:', 'add', 'delete', 'list'])
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_watchpoint_command_a(self):
+ """Test that 'watchpoint command a' completes to 'watchpoint command add '."""
+ self.complete_from_to('watchpoint command a', 'watchpoint command add ')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_watchpoint_set_variable_dash_w(self):
+ """Test that 'watchpoint set variable -w' completes to 'watchpoint set variable -w '."""
+ self.complete_from_to('watchpoint set variable -w', 'watchpoint set variable -w ')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_watchpoint_set_variable_dash_w_space(self):
+ """Test that 'watchpoint set variable -w ' completes to ['Available completions:', 'read', 'write', 'read_write']."""
+ self.complete_from_to('watchpoint set variable -w ', ['Available completions:', 'read', 'write', 'read_write'])
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_watchpoint_set_ex(self):
+ """Test that 'watchpoint set ex' completes to 'watchpoint set expression '."""
+ self.complete_from_to('watchpoint set ex', 'watchpoint set expression ')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_watchpoint_set_var(self):
+ """Test that 'watchpoint set var' completes to 'watchpoint set variable '."""
+ self.complete_from_to('watchpoint set var', 'watchpoint set variable ')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_watchpoint_set_variable_dash_w_read_underbar(self):
+ """Test that 'watchpoint set variable -w read_' completes to 'watchpoint set variable -w read_write'."""
+ self.complete_from_to('watchpoint set variable -w read_', 'watchpoint set variable -w read_write')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_help_fi(self):
+ """Test that 'help fi' completes to ['Available completions:', 'file', 'finish']."""
+ self.complete_from_to('help fi', ['Available completions:', 'file', 'finish'])
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_help_watchpoint_s(self):
+ """Test that 'help watchpoint s' completes to 'help watchpoint set '."""
+ self.complete_from_to('help watchpoint s', 'help watchpoint set ')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_settings_append_target_er(self):
+ """Test that 'settings append target.er' completes to 'settings append target.error-path'."""
+ self.complete_from_to('settings append target.er', 'settings append target.error-path')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_settings_insert_after_target_en(self):
+ """Test that 'settings insert-after target.env' completes to 'settings insert-after target.env-vars'."""
+ self.complete_from_to('settings insert-after target.env', 'settings insert-after target.env-vars')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_settings_insert_before_target_en(self):
+ """Test that 'settings insert-before target.env' completes to 'settings insert-before target.env-vars'."""
+ self.complete_from_to('settings insert-before target.env', 'settings insert-before target.env-vars')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_settings_replace_target_ru(self):
+ """Test that 'settings replace target.ru' completes to 'settings replace target.run-args'."""
+ self.complete_from_to('settings replace target.ru', 'settings replace target.run-args')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_settings_s(self):
+ """Test that 'settings s' completes to ['Available completions:', 'set', 'show']."""
+ self.complete_from_to('settings s', ['Available completions:', 'set', 'show'])
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_settings_set_th(self):
+ """Test that 'settings set th' completes to 'settings set thread-format'."""
+ self.complete_from_to('settings set th', 'settings set thread-format')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_settings_s_dash(self):
+ """Test that 'settings set -' completes to 'settings set -g'."""
+ self.complete_from_to('settings set -', 'settings set -g')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_settings_clear_th(self):
+ """Test that 'settings clear th' completes to 'settings clear thread-format'."""
+ self.complete_from_to('settings clear th', 'settings clear thread-format')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_settings_set_ta(self):
+ """Test that 'settings set ta' completes to 'settings set target.'."""
+ self.complete_from_to('settings set target.ma', 'settings set target.max-')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_settings_set_target_exec(self):
+ """Test that 'settings set target.exec' completes to 'settings set target.exec-search-paths '."""
+ self.complete_from_to('settings set target.exec', 'settings set target.exec-search-paths')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_settings_set_target_pr(self):
+ """Test that 'settings set target.pr' completes to ['Available completions:',
+ 'target.prefer-dynamic-value', 'target.process.']."""
+ self.complete_from_to('settings set target.pr',
+ ['Available completions:',
+ 'target.prefer-dynamic-value',
+ 'target.process.'])
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_settings_set_target_process(self):
+ """Test that 'settings set target.process' completes to 'settings set target.process.'."""
+ self.complete_from_to('settings set target.process', 'settings set target.process.')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_settings_set_target_process_dot(self):
+ """Test that 'settings set target.process.t' completes to 'settings set target.process.thread.'."""
+ self.complete_from_to('settings set target.process.t', 'settings set target.process.thread.')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_settings_set_target_process_thread_dot(self):
+ """Test that 'settings set target.process.thread.' completes to ['Available completions:',
+ 'target.process.thread.step-avoid-regexp', 'target.process.thread.trace-thread']."""
+ self.complete_from_to('settings set target.process.thread.',
+ ['Available completions:',
+ 'target.process.thread.step-avoid-regexp',
+ 'target.process.thread.trace-thread'])
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_target_space(self):
+ """Test that 'target ' completes to ['Available completions:', 'create', 'delete', 'list',
+ 'modules', 'select', 'stop-hook', 'variable']."""
+ self.complete_from_to('target ',
+ ['Available completions:', 'create', 'delete', 'list',
+ 'modules', 'select', 'stop-hook', 'variable'])
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_target_create_dash_co(self):
+ """Test that 'target create --co' completes to 'target variable --core '."""
+ self.complete_from_to('target create --co', 'target create --core ')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @skipIfFreeBSD # timing out on the FreeBSD buildbot
+ @no_debug_info_test
+ def test_target_va(self):
+ """Test that 'target va' completes to 'target variable '."""
+ self.complete_from_to('target va', 'target variable ')
+
+ @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureDarwin("llvm.org/pr25485")
+ def test_symbol_name(self):
+ self.build()
+ self.complete_from_to('''file a.out
+ breakpoint set -n Fo''',
+ 'breakpoint set -n Foo::Bar(int,\\ int)',
+ turn_off_re_match=True)
+
+ def complete_from_to(self, str_input, patterns, turn_off_re_match=False):
+ """Test that the completion mechanism completes str_input to patterns,
+ where patterns could be a pattern-string or a list of pattern-strings"""
+ import pexpect
+ # Patterns should not be None in order to proceed.
+ self.assertFalse(patterns is None)
+ # And should be either a string or list of strings. Check for list type
+ # below, if not, make a list out of the singleton string. If patterns
+ # is not a string or not a list of strings, there'll be runtime errors
+ # later on.
+ if not isinstance(patterns, list):
+ patterns = [patterns]
+
+ # The default lldb prompt.
+ prompt = "(lldb) "
+
+ # So that the child gets torn down after the test.
+ self.child = pexpect.spawn(lldbtest_config.lldbExec,
+ [self.lldbOption] + ['--no-use-colors'])
+ child = self.child
+ # Turn on logging for input/output to/from the child.
+ with open('child_send.txt', 'w') as f_send:
+ with open('child_read.txt', 'w') as f_read:
+ child.logfile_send = f_send
+ child.logfile_read = f_read
+
+ child.expect_exact(prompt)
+ child.setecho(True)
+ # Sends str_input and a Tab to invoke the completion machinery.
+ child.send("%s\t" % str_input)
+ child.sendline('')
+ child.expect_exact(prompt)
+ child.sendline('')
+ child.expect_exact(prompt)
+
+ # Now that the necessary logging is done, restore logfile to None to
+ # stop further logging.
+ child.logfile_send = None
+ child.logfile_read = None
+
+ with open('child_send.txt', 'r') as fs:
+ if self.TraceOn():
+ print("\n\nContents of child_send.txt:")
+ print(fs.read())
+ with open('child_read.txt', 'r') as fr:
+ from_child = fr.read()
+ if self.TraceOn():
+ print("\n\nContents of child_read.txt:")
+ print(from_child)
+
+ # The matching could be verbatim or using generic re pattern.
+ for p in patterns:
+ # Test that str_input completes to our patterns or substrings.
+ # If each pattern/substring matches from_child, the completion mechanism works!
+ if turn_off_re_match:
+ self.expect(from_child, msg=COMPLETION_MSG(str_input, p), exe=False,
+ substrs = [p])
+ else:
+ self.expect(from_child, msg=COMPLETION_MSG(str_input, p), exe=False,
+ patterns = [p])
diff --git a/packages/Python/lldbsuite/test/functionalities/completion/main.cpp b/packages/Python/lldbsuite/test/functionalities/completion/main.cpp
new file mode 100644
index 000000000000..b408720d2cdc
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/completion/main.cpp
@@ -0,0 +1,14 @@
+class Foo
+{
+public:
+ int Bar(int x, int y)
+ {
+ return x + y;
+ }
+};
+
+int main()
+{
+ Foo f;
+ f.Bar(1, 2);
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/conditional_break/.lldb b/packages/Python/lldbsuite/test/functionalities/conditional_break/.lldb
new file mode 100644
index 000000000000..4be90efee23b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/conditional_break/.lldb
@@ -0,0 +1,3 @@
+breakpoint set -n c
+command script import -r conditional_break.py
+breakpoint command add 1 -F "conditional_break.stop_if_called_from_a"
diff --git a/packages/Python/lldbsuite/test/functionalities/conditional_break/Makefile b/packages/Python/lldbsuite/test/functionalities/conditional_break/Makefile
new file mode 100644
index 000000000000..0d70f2595019
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/conditional_break/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/conditional_break/TestConditionalBreak.py b/packages/Python/lldbsuite/test/functionalities/conditional_break/TestConditionalBreak.py
new file mode 100644
index 000000000000..3ae7a20b4c7d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/conditional_break/TestConditionalBreak.py
@@ -0,0 +1,133 @@
+"""
+Test conditionally break on a function and inspect its variables.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import re
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+# rdar://problem/8532131
+# lldb not able to digest the clang-generated debug info correctly with respect to function name
+#
+# This class currently fails for clang as well as llvm-gcc.
+
+class ConditionalBreakTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @add_test_categories(['pyapi'])
+ def test_with_python(self):
+ """Exercise some thread and frame APIs to break if c() is called by a()."""
+ self.build()
+ self.do_conditional_break()
+
+ def test_with_command(self):
+ """Simulate a user using lldb commands to break on c() if called from a()."""
+ self.build()
+ self.simulate_conditional_break_by_user()
+
+ def do_conditional_break(self):
+ """Exercise some thread and frame APIs to break if c() is called by a()."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ breakpoint = target.BreakpointCreateByName("c", exe)
+ self.assertTrue(breakpoint, VALID_BREAKPOINT)
+
+ # Now launch the process, and do not stop at entry point.
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # The stop reason of the thread should be breakpoint.
+ self.assertTrue(process.GetState() == lldb.eStateStopped,
+ STOPPED_DUE_TO_BREAKPOINT)
+
+ # Find the line number where a's parent frame function is c.
+ line = line_number('main.c',
+ "// Find the line number where c's parent frame is a here.")
+
+ # Suppose we are only interested in the call scenario where c()'s
+ # immediate caller is a() and we want to find out the value passed from
+ # a().
+ #
+ # The 10 in range(10) is just an arbitrary number, which means we would
+ # like to try for at most 10 times.
+ for j in range(10):
+ if self.TraceOn():
+ print("j is: ", j)
+ thread = process.GetThreadAtIndex(0)
+
+ if thread.GetNumFrames() >= 2:
+ frame0 = thread.GetFrameAtIndex(0)
+ name0 = frame0.GetFunction().GetName()
+ frame1 = thread.GetFrameAtIndex(1)
+ name1 = frame1.GetFunction().GetName()
+ #lldbutil.print_stacktrace(thread)
+ self.assertTrue(name0 == "c", "Break on function c()")
+ if (name1 == "a"):
+ # By design, we know that a() calls c() only from main.c:27.
+ # In reality, similar logic can be used to find out the call
+ # site.
+ self.assertTrue(frame1.GetLineEntry().GetLine() == line,
+ "Immediate caller a() at main.c:%d" % line)
+
+ # And the local variable 'val' should have a value of (int) 3.
+ val = frame1.FindVariable("val")
+ self.assertTrue(val.GetTypeName() == "int", "'val' has int type")
+ self.assertTrue(val.GetValue() == "3", "'val' has a value of 3")
+ break
+
+ process.Continue()
+
+ def simulate_conditional_break_by_user(self):
+ """Simulate a user using lldb commands to break on c() if called from a()."""
+
+ # Sourcing .lldb in the current working directory, which sets the main
+ # executable, sets the breakpoint on c(), and adds the callback for the
+ # breakpoint such that lldb only stops when the caller of c() is a().
+ # the "my" package that defines the date() function.
+ if self.TraceOn():
+ print("About to source .lldb")
+
+ if not self.TraceOn():
+ self.HideStdout()
+
+ # Separate out the "file a.out" command from .lldb file, for the sake of
+ # remote testsuite.
+ self.runCmd("file a.out")
+ self.runCmd("command source .lldb")
+
+ self.runCmd ("break list")
+
+ if self.TraceOn():
+ print("About to run.")
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ self.runCmd ("break list")
+
+ if self.TraceOn():
+ print("Done running")
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped', 'stop reason = breakpoint'])
+
+ # The frame info for frame #0 points to a.out`c and its immediate caller
+ # (frame #1) points to a.out`a.
+
+ self.expect("frame info", "We should stop at c()",
+ substrs = ["a.out`c"])
+
+ # Select our parent frame as the current frame.
+ self.runCmd("frame select 1")
+ self.expect("frame info", "The immediate caller should be a()",
+ substrs = ["a.out`a"])
diff --git a/packages/Python/lldbsuite/test/functionalities/conditional_break/conditional_break.py b/packages/Python/lldbsuite/test/functionalities/conditional_break/conditional_break.py
new file mode 100644
index 000000000000..b30a34e56b14
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/conditional_break/conditional_break.py
@@ -0,0 +1,30 @@
+import sys
+import lldb
+
+def stop_if_called_from_a(frame, bp_loc, dict):
+
+ thread = frame.GetThread()
+ process = thread.GetProcess()
+ target = process.GetTarget()
+ dbg = target.GetDebugger()
+
+ # Perform synchronous interaction with the debugger.
+ old_async = dbg.GetAsync()
+ dbg.SetAsync(True)
+
+ # We check the call frames in order to stop only when the immediate caller
+ # of the leaf function c() is a(). If it's not the right caller, we ask the
+ # command interpreter to continue execution.
+
+ should_stop = True
+ if thread.GetNumFrames() >= 2:
+
+ if (thread.frames[0].function.name == 'c' and thread.frames[1].function.name == 'a'):
+ should_stop = True
+ else:
+ should_stop = False
+
+ dbg.SetAsync(old_async)
+ return should_stop
+
+
diff --git a/packages/Python/lldbsuite/test/functionalities/conditional_break/main.c b/packages/Python/lldbsuite/test/functionalities/conditional_break/main.c
new file mode 100644
index 000000000000..1329fd69a2e1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/conditional_break/main.c
@@ -0,0 +1,54 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+// This simple program is to demonstrate the capability of the lldb command
+// "breakpoint command add" to add a set of commands to a breakpoint to be
+// executed when the breakpoint is hit.
+//
+// In particular, we want to break within c(), but only if the immediate caller
+// is a().
+
+int a(int);
+int b(int);
+int c(int);
+
+int a(int val)
+{
+ if (val <= 1)
+ return b(val);
+ else if (val >= 3)
+ return c(val); // Find the line number where c's parent frame is a here.
+
+ return val;
+}
+
+int b(int val)
+{
+ return c(val);
+}
+
+int c(int val)
+{
+ return val + 3;
+}
+
+int main (int argc, char const *argv[])
+{
+ int A1 = a(1); // a(1) -> b(1) -> c(1)
+ printf("a(1) returns %d\n", A1);
+
+ int B2 = b(2); // b(2) -> c(2)
+ printf("b(2) returns %d\n", B2);
+
+ int A3 = a(3); // a(3) -> c(3)
+ printf("a(3) returns %d\n", A3);
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/.categories b/packages/Python/lldbsuite/test/functionalities/data-formatter/.categories
new file mode 100644
index 000000000000..fe1da0247c62
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/.categories
@@ -0,0 +1 @@
+dataformatters
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/Makefile
new file mode 100644
index 000000000000..261658b10ae8
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/Makefile
@@ -0,0 +1,9 @@
+LEVEL = ../../../make
+
+OBJCXX_SOURCES := main.mm
+
+CFLAGS_EXTRAS += -w
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/TestFormattersBoolRefPtr.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/TestFormattersBoolRefPtr.py
new file mode 100644
index 000000000000..94cdfdfeb343
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/TestFormattersBoolRefPtr.py
@@ -0,0 +1,72 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import datetime
+import lldbsuite.test.lldbutil as lldbutil
+
+class DataFormatterBoolRefPtr(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipUnlessDarwin
+ def test_boolrefptr_with_run_command(self):
+ """Test the formatters we use for BOOL& and BOOL* in Objective-C."""
+ self.build()
+ self.boolrefptr_data_formatter_commands()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.mm', '// Set break point at this line.')
+
+ def boolrefptr_data_formatter_commands(self):
+ """Test the formatters we use for BOOL& and BOOL* in Objective-C."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.mm", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 synth clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # Now check that we use the right summary for BOOL&
+ self.expect('frame variable yes_ref',
+ substrs = ['YES'])
+ self.expect('frame variable no_ref',
+ substrs = ['NO'])
+
+
+ # Now check that we use the right summary for BOOL*
+ self.expect('frame variable yes_ptr',
+ substrs = ['YES'])
+ self.expect('frame variable no_ptr',
+ substrs = ['NO'])
+
+
+ # Now check that we use the right summary for BOOL
+ self.expect('frame variable yes',
+ substrs = ['YES'])
+ self.expect('frame variable no',
+ substrs = ['NO'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/main.mm b/packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/main.mm
new file mode 100644
index 000000000000..a2461fd9da91
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/main.mm
@@ -0,0 +1,29 @@
+//===-- main.m ------------------------------------------------*- ObjC -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#import <Foundation/Foundation.h>
+
+int main (int argc, const char * argv[])
+{
+
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+ BOOL yes = YES;
+ BOOL no = NO;
+
+ BOOL &yes_ref = yes;
+ BOOL &no_ref = no;
+
+ BOOL* yes_ptr = &yes;
+ BOOL* no_ptr = &no;
+
+ [pool drain];// Set break point at this line.
+ return 0;
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/compactvectors/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/compactvectors/Makefile
new file mode 100644
index 000000000000..9b06ad7d705a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/compactvectors/Makefile
@@ -0,0 +1,7 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Accelerate \ No newline at end of file
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/compactvectors/TestCompactVectors.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/compactvectors/TestCompactVectors.py
new file mode 100644
index 000000000000..7cd2a49b4717
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/compactvectors/TestCompactVectors.py
@@ -0,0 +1,58 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class CompactVectorsFormattingTestCase(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.')
+
+ @skipUnlessDarwin
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 summary clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.expect('frame variable',
+ substrs = ['(vFloat) valueFL = (1.25, 0, 0.25, 0)',
+ '(int16_t [8]) valueI16 = (1, 0, 4, 0, 0, 1, 0, 4)',
+ '(int32_t [4]) valueI32 = (1, 0, 4, 0)',
+ '(vDouble) valueDL = (1.25, 2.25)',
+ '(vUInt8) valueU8 = (0x01, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)',
+ '(vUInt16) valueU16 = (1, 0, 4, 0, 0, 1, 0, 4)',
+ '(vUInt32) valueU32 = (1, 2, 3, 4)',
+ "(vSInt8) valueS8 = (1, 0, 4, 0, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0)",
+ '(vSInt16) valueS16 = (1, 0, 4, 0, 0, 1, 0, 4)',
+ '(vSInt32) valueS32 = (4, 3, 2, 1)',
+ '(vBool32) valueBool32 = (0, 1, 0, 1)'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/compactvectors/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/compactvectors/main.cpp
new file mode 100644
index 000000000000..bbbd823ec313
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/compactvectors/main.cpp
@@ -0,0 +1,26 @@
+ //===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <Accelerate/Accelerate.h>
+
+int main()
+{
+ vFloat valueFL = {1.25,0,0.25,0};
+ vDouble valueDL = {1.25,2.25};
+ int16_t valueI16[8] = {1,0,4,0,0,1,0,4};
+ int32_t valueI32[4] = {1,0,4,0};
+ vUInt8 valueU8 = {1,0,4,0,0,1,0,4};
+ vUInt16 valueU16 = {1,0,4,0,0,1,0,4};
+ vUInt32 valueU32 = {1,2,3,4};
+ vSInt8 valueS8 = {1,0,4,0,0,1,0,4};
+ vSInt16 valueS16 = {1,0,4,0,0,1,0,4};
+ vSInt32 valueS32 = {4,3,2,1};
+ vBool32 valueBool32 = {false,true,false,true};
+ return 0; // Set break point at this line.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-advanced/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-advanced/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-advanced/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py
new file mode 100644
index 000000000000..8166d1540ca3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py
@@ -0,0 +1,285 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class AdvDataFormatterTestCase(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.')
+
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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("settings set target.max-children-count 256", check=False)
+
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.runCmd("type summary add --summary-string \"pippo\" \"i_am_cool\"")
+
+ self.runCmd("type summary add --summary-string \"pluto\" -x \"i_am_cool[a-z]*\"")
+
+ self.expect("frame variable cool_boy",
+ substrs = ['pippo'])
+
+ self.expect("frame variable cooler_boy",
+ substrs = ['pluto'])
+
+ self.runCmd("type summary delete i_am_cool")
+
+ self.expect("frame variable cool_boy",
+ substrs = ['pluto'])
+
+ self.runCmd("type summary clear")
+
+ self.runCmd("type summary add --summary-string \"${var[]}\" -x \"int \\[[0-9]\\]")
+
+ self.expect("frame variable int_array",
+ substrs = ['1,2,3,4,5'])
+
+ # this will fail if we don't do [] as regex correctly
+ self.runCmd('type summary add --summary-string "${var[].integer}" "i_am_cool[]')
+
+ self.expect("frame variable cool_array",
+ substrs = ['1,1,1,1,6'])
+
+ self.runCmd("type summary clear")
+
+ self.runCmd("type summary add --summary-string \"${var[1-0]%x}\" \"int\"")
+
+ self.expect("frame variable iAmInt",
+ substrs = ['01'])
+
+ self.runCmd("type summary add --summary-string \"${var[0-1]%x}\" \"int\"")
+
+ self.expect("frame variable iAmInt",
+ substrs = ['01'])
+
+ self.runCmd("type summary clear")
+
+ self.runCmd("type summary add --summary-string \"${var[0-1]%x}\" int")
+ self.runCmd("type summary add --summary-string \"${var[0-31]%x}\" float")
+
+ self.expect("frame variable *pointer",
+ substrs = ['0x',
+ '2'])
+
+ # check fix for <rdar://problem/11338654> LLDB crashes when using a "type summary" that uses bitfields with no format
+ self.runCmd("type summary add --summary-string \"${var[0-1]}\" int")
+ self.expect("frame variable iAmInt",
+ substrs = ['9 1'])
+
+ self.expect("frame variable cool_array[3].floating",
+ substrs = ['0x'])
+
+ self.runCmd("type summary add --summary-string \"low bits are ${*var[0-1]} tgt is ${*var}\" \"int *\"")
+
+ self.expect("frame variable pointer",
+ substrs = ['low bits are',
+ 'tgt is 6'])
+
+ self.expect("frame variable int_array --summary-string \"${*var[0-1]}\"",
+ substrs = ['3'])
+
+ self.runCmd("type summary clear")
+
+ self.runCmd('type summary add --summary-string \"${var[0-1]}\" -x \"int \[[0-9]\]\"')
+
+ self.expect("frame variable int_array",
+ substrs = ['1,2'])
+
+ self.runCmd('type summary add --summary-string \"${var[0-1]}\" "int []"')
+
+ self.expect("frame variable int_array",
+ substrs = ['1,2'])
+
+ self.runCmd("type summary clear")
+
+ self.runCmd("type summary add -c -x \"i_am_cool \[[0-9]\]\"")
+ self.runCmd("type summary add -c i_am_cool")
+
+ self.expect("frame variable cool_array",
+ substrs = ['[0]',
+ '[1]',
+ '[2]',
+ '[3]',
+ '[4]',
+ 'integer',
+ 'character',
+ 'floating'])
+
+ self.runCmd("type summary add --summary-string \"int = ${*var.int_pointer}, float = ${*var.float_pointer}\" IWrapPointers")
+
+ self.expect("frame variable wrapper",
+ substrs = ['int = 4',
+ 'float = 1.1'])
+
+ self.runCmd("type summary add --summary-string \"low bits = ${*var.int_pointer[2]}\" IWrapPointers -p")
+
+ self.expect("frame variable wrapper",
+ substrs = ['low bits = 1'])
+
+ self.expect("frame variable *wrap_pointer",
+ substrs = ['low bits = 1'])
+
+ self.runCmd("type summary clear")
+
+ self.expect("frame variable int_array --summary-string \"${var[0][0-2]%hex}\"",
+ substrs = ['0x',
+ '7'])
+
+ self.runCmd("type summary clear")
+
+ self.runCmd("type summary add --summary-string \"${*var[].x[0-3]%hex} is a bitfield on a set of integers\" -x \"SimpleWithPointers \[[0-9]\]\"")
+
+ self.expect("frame variable couple --summary-string \"${*var.sp.x[0-2]} are low bits of integer ${*var.sp.x}. If I pretend it is an array I get ${var.sp.x[0-5]}\"",
+ substrs = ['1 are low bits of integer 9.',
+ 'If I pretend it is an array I get [9,'])
+
+ # if the summary has an error, we still display the value
+ self.expect("frame variable couple --summary-string \"${*var.sp.foo[0-2]\"",
+ substrs = ['(Couple) couple = {','x = 0x','y = 0x','z = 0x','s = 0x'])
+
+
+ self.runCmd("type summary add --summary-string \"${*var.sp.x[0-2]} are low bits of integer ${*var.sp.x}. If I pretend it is an array I get ${var.sp.x[0-5]}\" Couple")
+
+ self.expect("frame variable sparray",
+ substrs = ['[0x0000000f,0x0000000c,0x00000009]'])
+
+ # check that we can format a variable in a summary even if a format is defined for its datatype
+ self.runCmd("type format add -f hex int")
+ self.runCmd("type summary add --summary-string \"x=${var.x%d}\" Simple")
+
+ self.expect("frame variable a_simple_object",
+ substrs = ['x=3'])
+
+ self.expect("frame variable a_simple_object", matching=False,
+ substrs = ['0x0'])
+
+ # now check that the default is applied if we do not hand out a format
+ self.runCmd("type summary add --summary-string \"x=${var.x}\" Simple")
+
+ self.expect("frame variable a_simple_object", matching=False,
+ substrs = ['x=3'])
+
+ self.expect("frame variable a_simple_object", matching=True,
+ substrs = ['x=0x00000003'])
+
+ # check that we can correctly cap the number of children shown
+ self.runCmd("settings set target.max-children-count 5")
+
+ self.expect('frame variable a_long_guy', matching=True,
+ substrs = ['a_1',
+ 'b_1',
+ 'c_1',
+ 'd_1',
+ 'e_1',
+ '...'])
+
+ # check that no further stuff is printed (not ALL values are checked!)
+ self.expect('frame variable a_long_guy', matching=False,
+ substrs = ['f_1',
+ 'g_1',
+ 'h_1',
+ 'i_1',
+ 'j_1',
+ 'q_1',
+ 'a_2',
+ 'f_2',
+ 't_2',
+ 'w_2'])
+
+ self.runCmd("settings set target.max-children-count 1")
+ self.expect('frame variable a_long_guy', matching=True,
+ substrs = ['a_1',
+ '...'])
+ self.expect('frame variable a_long_guy', matching=False,
+ substrs = ['b_1',
+ 'c_1',
+ 'd_1',
+ 'e_1'])
+ self.expect('frame variable a_long_guy', matching=False,
+ substrs = ['f_1',
+ 'g_1',
+ 'h_1',
+ 'i_1',
+ 'j_1',
+ 'q_1',
+ 'a_2',
+ 'f_2',
+ 't_2',
+ 'w_2'])
+
+ self.runCmd("settings set target.max-children-count 30")
+ self.expect('frame variable a_long_guy', matching=True,
+ substrs = ['a_1',
+ 'b_1',
+ 'c_1',
+ 'd_1',
+ 'e_1',
+ 'z_1',
+ 'a_2',
+ 'b_2',
+ 'c_2',
+ 'd_2',
+ '...'])
+ self.expect('frame variable a_long_guy', matching=False,
+ substrs = ['e_2',
+ 'n_2',
+ 'r_2',
+ 'i_2',
+ 'k_2',
+ 'o_2'])
+
+ # override the cap
+ self.expect('frame variable a_long_guy --show-all-children', matching=True,
+ substrs = ['a_1',
+ 'b_1',
+ 'c_1',
+ 'd_1',
+ 'e_1',
+ 'z_1',
+ 'a_2',
+ 'b_2',
+ 'c_2',
+ 'd_2'])
+ self.expect('frame variable a_long_guy --show-all-children', matching=True,
+ substrs = ['e_2',
+ 'n_2',
+ 'r_2',
+ 'i_2',
+ 'k_2',
+ 'o_2'])
+ self.expect('frame variable a_long_guy --show-all-children', matching=False,
+ substrs = ['...'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-advanced/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-advanced/main.cpp
new file mode 100644
index 000000000000..2462e28db127
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-advanced/main.cpp
@@ -0,0 +1,174 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+struct i_am_cool
+{
+ int integer;
+ float floating;
+ char character;
+ i_am_cool(int I, float F, char C) :
+ integer(I), floating(F), character(C) {}
+ i_am_cool() : integer(1), floating(2), character('3') {}
+
+};
+
+struct i_am_cooler
+{
+ i_am_cool first_cool;
+ i_am_cool second_cool;
+ float floating;
+
+ i_am_cooler(int I1, int I2, float F1, float F2, char C1, char C2) :
+ first_cool(I1,F1,C1),
+ second_cool(I2,F2,C2),
+ floating((F1 + F2)/2) {}
+};
+
+struct IWrapPointers
+{
+ int* int_pointer;
+ float* float_pointer;
+ IWrapPointers() : int_pointer(new int(4)), float_pointer(new float(1.111)) {}
+};
+
+struct Simple
+{
+ int x;
+ float y;
+ char z;
+ Simple(int X, float Y, char Z) :
+ x(X),
+ y(Y),
+ z(Z)
+ {}
+};
+
+struct SimpleWithPointers
+{
+ int *x;
+ float *y;
+ char *z;
+ SimpleWithPointers(int X, float Y, char Z) :
+ x(new int (X)),
+ y(new float (Y)),
+ z(new char[2])
+ {
+ z[0] = Z;
+ z[1] = '\0';
+ }
+};
+
+struct Couple
+{
+ SimpleWithPointers sp;
+ Simple* s;
+ Couple(int X, float Y, char Z) : sp(X,Y,Z),
+ s(new Simple(X,Y,Z)) {}
+};
+
+struct VeryLong
+{
+ int a_1;
+ int b_1;
+ int c_1;
+ int d_1;
+ int e_1;
+ int f_1;
+ int g_1;
+ int h_1;
+ int i_1;
+ int j_1;
+ int k_1;
+ int l_1;
+ int m_1;
+ int n_1;
+ int o_1;
+ int p_1;
+ int q_1;
+ int r_1;
+ int s_1;
+ int t_1;
+ int u_1;
+ int v_1;
+ int w_1;
+ int x_1;
+ int y_1;
+ int z_1;
+
+ int a_2;
+ int b_2;
+ int c_2;
+ int d_2;
+ int e_2;
+ int f_2;
+ int g_2;
+ int h_2;
+ int i_2;
+ int j_2;
+ int k_2;
+ int l_2;
+ int m_2;
+ int n_2;
+ int o_2;
+ int p_2;
+ int q_2;
+ int r_2;
+ int s_2;
+ int t_2;
+ int u_2;
+ int v_2;
+ int w_2;
+ int x_2;
+ int y_2;
+ int z_2;
+};
+
+int main (int argc, const char * argv[])
+{
+
+ int iAmInt = 9;
+
+ i_am_cool cool_boy(1,0.5,3);
+ i_am_cooler cooler_boy(1,2,0.1,0.2,'A','B');
+
+ i_am_cool *cool_pointer = new i_am_cool(3,-3.141592,'E');
+
+ i_am_cool cool_array[5];
+
+ cool_array[3].floating = 5.25;
+ cool_array[4].integer = 6;
+ cool_array[2].character = 'Q';
+
+ int int_array[] = {1,2,3,4,5};
+
+ IWrapPointers wrapper;
+
+ *int_array = -1;
+
+ int* pointer = &cool_array[4].integer;
+
+ IWrapPointers *wrap_pointer = &wrapper;
+
+ Couple couple(9,9.99,'X');
+
+ SimpleWithPointers sparray[] =
+ {SimpleWithPointers(-1,-2,'3'),
+ SimpleWithPointers(-4,-5,'6'),
+ SimpleWithPointers(-7,-8,'9')};
+
+ Simple a_simple_object(3,0.14,'E');
+
+ VeryLong a_long_guy;
+
+ return 0; // Set break point at this line.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-categories/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-categories/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-categories/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py
new file mode 100644
index 000000000000..db426cac6e59
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py
@@ -0,0 +1,329 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class CategoriesDataFormatterTestCase(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.')
+
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 (most of these categories do not
+ # exist anymore, but we just make sure we delete all of them)
+ def cleanup():
+ self.runCmd('type format clear', check=False)
+ self.runCmd('type summary clear', check=False)
+ self.runCmd('type category delete Category1', check=False)
+ self.runCmd('type category delete Category2', check=False)
+ self.runCmd('type category delete NewCategory', check=False)
+ self.runCmd("type category delete CircleCategory", check=False)
+ self.runCmd("type category delete RectangleStarCategory", check=False)
+ self.runCmd("type category delete BaseCategory", check=False)
+
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # Add a summary to a new category and check that it works
+ self.runCmd("type summary add Rectangle --summary-string \"ARectangle\" -w NewCategory")
+
+ self.expect("frame variable r1 r2 r3", matching=False,
+ substrs = ['r1 = ARectangle',
+ 'r2 = ARectangle',
+ 'r3 = ARectangle'])
+
+ self.runCmd("type category enable NewCategory")
+
+ self.expect("frame variable r1 r2 r3", matching=True,
+ substrs = ['r1 = ARectangle',
+ 'r2 = ARectangle',
+ 'r3 = ARectangle'])
+
+ # Disable the category and check that the old stuff is there
+ self.runCmd("type category disable NewCategory")
+
+ self.expect("frame variable r1 r2 r3",
+ substrs = ['r1 = {',
+ 'r2 = {',
+ 'r3 = {'])
+
+ # Re-enable the category and check that it works
+ self.runCmd("type category enable NewCategory")
+
+ self.expect("frame variable r1 r2 r3",
+ substrs = ['r1 = ARectangle',
+ 'r2 = ARectangle',
+ 'r3 = ARectangle'])
+
+ # Delete the category and the old stuff should be there
+ self.runCmd("type category delete NewCategory")
+
+ self.expect("frame variable r1 r2 r3",
+ substrs = ['r1 = {',
+ 'r2 = {',
+ 'r3 = {'])
+
+ # Add summaries to two different categories and check that we can switch
+ self.runCmd("type summary add --summary-string \"Width = ${var.w}, Height = ${var.h}\" Rectangle -w Category1")
+ self.runCmd("type summary add --python-script \"return 'Area = ' + str( int(valobj.GetChildMemberWithName('w').GetValue()) * int(valobj.GetChildMemberWithName('h').GetValue()) );\" Rectangle -w Category2")
+
+ # check that enable A B is the same as enable B enable A
+ self.runCmd("type category enable Category1 Category2")
+
+ self.expect("frame variable r1 r2 r3",
+ substrs = ['r1 = Width = ',
+ 'r2 = Width = ',
+ 'r3 = Width = '])
+
+ self.runCmd("type category disable Category1")
+
+ self.expect("frame variable r1 r2 r3",
+ substrs = ['r1 = Area = ',
+ 'r2 = Area = ',
+ 'r3 = Area = '])
+
+ # switch again
+
+ self.runCmd("type category enable Category1")
+
+ self.expect("frame variable r1 r2 r3",
+ substrs = ['r1 = Width = ',
+ 'r2 = Width = ',
+ 'r3 = Width = '])
+
+ # Re-enable the category and show that the preference is persisted
+ self.runCmd("type category disable Category2")
+ self.runCmd("type category enable Category2")
+
+ self.expect("frame variable r1 r2 r3",
+ substrs = ['r1 = Area = ',
+ 'r2 = Area = ',
+ 'r3 = Area = '])
+
+ # Now delete the favorite summary
+ self.runCmd("type summary delete Rectangle -w Category2")
+
+ self.expect("frame variable r1 r2 r3",
+ substrs = ['r1 = Width = ',
+ 'r2 = Width = ',
+ 'r3 = Width = '])
+
+ # Delete the summary from the default category (that does not have it)
+ self.runCmd("type summary delete Rectangle", check=False)
+
+ self.expect("frame variable r1 r2 r3",
+ substrs = ['r1 = Width = ',
+ 'r2 = Width = ',
+ 'r3 = Width = '])
+
+ # Now add another summary to another category and switch back and forth
+ self.runCmd("type category delete Category1 Category2")
+
+ self.runCmd("type summary add Rectangle -w Category1 --summary-string \"Category1\"")
+ self.runCmd("type summary add Rectangle -w Category2 --summary-string \"Category2\"")
+
+ self.runCmd("type category enable Category2")
+ self.runCmd("type category enable Category1")
+
+ self.runCmd("type summary list -w Category1")
+
+ self.expect("frame variable r1 r2 r3",
+ substrs = ['r1 = Category1',
+ 'r2 = Category1',
+ 'r3 = Category1'])
+
+ self.runCmd("type category disable Category1")
+
+ self.expect("frame variable r1 r2 r3",
+ substrs = ['r1 = Category2',
+ 'r2 = Category2',
+ 'r3 = Category2'])
+
+ # Check that re-enabling an enabled category works
+ self.runCmd("type category enable Category1")
+
+ self.expect("frame variable r1 r2 r3",
+ substrs = ['r1 = Category1',
+ 'r2 = Category1',
+ 'r3 = Category1'])
+
+ self.runCmd("type category delete Category1")
+ self.runCmd("type category delete Category2")
+
+ self.expect("frame variable r1 r2 r3",
+ substrs = ['r1 = {',
+ 'r2 = {',
+ 'r3 = {'])
+
+ # Check that multiple summaries can go into one category
+ self.runCmd("type summary add -w Category1 --summary-string \"Width = ${var.w}, Height = ${var.h}\" Rectangle")
+ self.runCmd("type summary add -w Category1 --summary-string \"Radius = ${var.r}\" Circle")
+
+ self.runCmd("type category enable Category1")
+
+ self.expect("frame variable r1 r2 r3",
+ substrs = ['r1 = Width = ',
+ 'r2 = Width = ',
+ 'r3 = Width = '])
+
+ self.expect("frame variable c1 c2 c3",
+ substrs = ['c1 = Radius = ',
+ 'c2 = Radius = ',
+ 'c3 = Radius = '])
+
+ self.runCmd("type summary delete Circle -w Category1")
+
+ self.expect("frame variable c1 c2 c3",
+ substrs = ['c1 = {',
+ 'c2 = {',
+ 'c3 = {'])
+
+ # Add a regex based summary to a category
+ self.runCmd("type summary add -w Category1 --summary-string \"Radius = ${var.r}\" -x Circle")
+
+ self.expect("frame variable r1 r2 r3",
+ substrs = ['r1 = Width = ',
+ 'r2 = Width = ',
+ 'r3 = Width = '])
+
+ self.expect("frame variable c1 c2 c3",
+ substrs = ['c1 = Radius = ',
+ 'c2 = Radius = ',
+ 'c3 = Radius = '])
+
+ # Delete it
+ self.runCmd("type summary delete Circle -w Category1")
+
+ self.expect("frame variable c1 c2 c3",
+ substrs = ['c1 = {',
+ 'c2 = {',
+ 'c3 = {'])
+
+ # Change a summary inside a category and check that the change is reflected
+ self.runCmd("type summary add Circle -w Category1 --summary-string \"summary1\"")
+
+ self.expect("frame variable c1 c2 c3",
+ substrs = ['c1 = summary1',
+ 'c2 = summary1',
+ 'c3 = summary1'])
+
+ self.runCmd("type summary add Circle -w Category1 --summary-string \"summary2\"")
+
+ self.expect("frame variable c1 c2 c3",
+ substrs = ['c1 = summary2',
+ 'c2 = summary2',
+ 'c3 = summary2'])
+
+ # Check that our order of priority works. Start by clearing categories
+ self.runCmd("type category delete Category1")
+
+ self.runCmd("type summary add Shape -w BaseCategory --summary-string \"AShape\"")
+ self.runCmd("type category enable BaseCategory")
+
+ self.expect("print (Shape*)&c1",
+ substrs = ['AShape'])
+ self.expect("print (Shape*)&r1",
+ substrs = ['AShape'])
+ self.expect("print (Shape*)c_ptr",
+ substrs = ['AShape'])
+ self.expect("print (Shape*)r_ptr",
+ substrs = ['AShape'])
+
+ self.runCmd("type summary add Circle -w CircleCategory --summary-string \"ACircle\"")
+ self.runCmd("type summary add Rectangle -w RectangleCategory --summary-string \"ARectangle\"")
+ self.runCmd("type category enable CircleCategory")
+
+ self.expect("frame variable c1",
+ substrs = ['ACircle'])
+ self.expect("frame variable c_ptr",
+ substrs = ['ACircle'])
+
+ self.runCmd("type summary add \"Rectangle *\" -w RectangleStarCategory --summary-string \"ARectangleStar\"")
+ self.runCmd("type category enable RectangleStarCategory")
+
+ self.expect("frame variable c1 r1 c_ptr r_ptr",
+ substrs = ['ACircle',
+ 'ARectangleStar'])
+
+ self.runCmd("type category enable RectangleCategory")
+
+ self.expect("frame variable c1 r1 c_ptr r_ptr",
+ substrs = ['ACircle',
+ 'ACircle',
+ 'ARectangle'])
+
+ # Check that abruptly deleting an enabled category does not crash us
+ self.runCmd("type category delete RectangleCategory")
+
+ self.expect("frame variable c1 r1 c_ptr r_ptr",
+ substrs = ['ACircle',
+ '(Rectangle) r1 = ', 'w = 5', 'h = 6',
+ 'ACircle',
+ 'ARectangleStar'])
+
+ # check that list commands work
+ self.expect("type category list",
+ substrs = ['RectangleStarCategory (enabled)'])
+
+ self.expect("type summary list",
+ substrs = ['ARectangleStar'])
+
+ # Disable a category and check that it fallsback
+ self.runCmd("type category disable CircleCategory")
+
+ # check that list commands work
+ self.expect("type category list",
+ substrs = ['CircleCategory (disabled'])
+
+ self.expect("frame variable c1 r_ptr",
+ substrs = ['AShape',
+ 'ARectangleStar'])
+
+ # check that filters work into categories
+ self.runCmd("type filter add Rectangle --child w --category RectangleCategory")
+ self.runCmd("type category enable RectangleCategory")
+ self.runCmd("type summary add Rectangle --category RectangleCategory --summary-string \" \" -e")
+ self.expect('frame variable r2',
+ substrs = ['w = 9'])
+ self.runCmd("type summary add Rectangle --summary-string \" \" -e")
+ self.expect('frame variable r2', matching=False,
+ substrs = ['h = 16'])
+
+ # Now delete all categories
+ self.runCmd("type category delete CircleCategory RectangleStarCategory BaseCategory RectangleCategory")
+
+ # check that a deleted category with filter does not blow us up
+ self.expect('frame variable r2',
+ substrs = ['w = 9',
+ 'h = 16'])
+
+ # and also validate that one can print formatters for a language
+ self.expect('type summary list -l c++', substrs=['vector', 'map', 'list', 'string'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-categories/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-categories/main.cpp
new file mode 100644
index 000000000000..b51dd45a7f60
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-categories/main.cpp
@@ -0,0 +1,46 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+struct Shape
+{
+ bool dummy;
+ Shape() : dummy(true) {}
+};
+
+struct Rectangle : public Shape {
+ int w;
+ int h;
+ Rectangle(int W = 3, int H = 5) : w(W), h(H) {}
+};
+
+struct Circle : public Shape {
+ int r;
+ Circle(int R = 6) : r(R) {}
+};
+
+int main (int argc, const char * argv[])
+{
+ Rectangle r1(5,6);
+ Rectangle r2(9,16);
+ Rectangle r3(4,4);
+
+ Circle c1(5);
+ Circle c2(6);
+ Circle c3(7);
+
+ Circle *c_ptr = new Circle(8);
+ Rectangle *r_ptr = new Rectangle(9,7);
+
+ return 0; // Set break point at this line.
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-cpp/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-cpp/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-cpp/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py
new file mode 100644
index 000000000000..2ca737156a1a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py
@@ -0,0 +1,265 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class CppDataFormatterTestCase(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.')
+
+ @expectedFailureWindows("llvm.org/pr24462") # Data formatters have problems on Windows
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ self.expect("frame variable",
+ substrs = ['(Speed) SPILookHex = 5.55' # Speed by default is 5.55.
+ ]);
+
+ # 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)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.runCmd("type format add -C yes -f x Speed BitField")
+ self.runCmd("type format add -C no -f c RealNumber")
+ self.runCmd("type format add -C no -f x Type2")
+ self.runCmd("type format add -C yes -f c Type1")
+
+ # The type format list should show our custom formats.
+ self.expect("type format list",
+ substrs = ['RealNumber',
+ 'Speed',
+ 'BitField',
+ 'Type1',
+ 'Type2'])
+
+ self.expect("frame variable",
+ patterns = ['\(Speed\) SPILookHex = 0x[0-9a-f]+' # Speed should look hex-ish now.
+ ]);
+
+ # gcc4.2 on Mac OS X skips typedef chains in the DWARF output
+ if self.getCompiler() in ['clang', 'llvm-gcc']:
+ self.expect("frame variable",
+ patterns = ['\(SignalMask\) SMILookHex = 0x[0-9a-f]+' # SignalMask should look hex-ish now.
+ ]);
+ self.expect("frame variable", matching=False,
+ patterns = ['\(Type4\) T4ILookChar = 0x[0-9a-f]+' # Type4 should NOT look hex-ish now.
+ ]);
+
+ # Now let's delete the 'Speed' custom format.
+ self.runCmd("type format delete Speed")
+
+ # The type format list should not show 'Speed' at this point.
+ self.expect("type format list", matching=False,
+ substrs = ['Speed'])
+
+ # Delete type format for 'Speed', we should expect an error message.
+ self.expect("type format delete Speed", error=True,
+ substrs = ['no custom formatter for Speed'])
+
+ self.runCmd("type summary add --summary-string \"arr = ${var%s}\" -x \"char \\[[0-9]+\\]\" -v")
+
+ self.expect("frame variable strarr",
+ substrs = ['arr = "Hello world!"'])
+
+ self.runCmd("type summary clear")
+
+ self.runCmd("type summary add --summary-string \"ptr = ${var%s}\" \"char *\" -v")
+
+ self.expect("frame variable strptr",
+ substrs = ['ptr = "Hello world!"'])
+
+ self.runCmd("type summary add --summary-string \"arr = ${var%s}\" -x \"char \\[[0-9]+\\]\" -v")
+
+ self.expect("frame variable strarr",
+ substrs = ['arr = "Hello world!'])
+
+ # check that rdar://problem/10011145 (Standard summary format for char[] doesn't work as the result of "expr".) is solved
+ self.expect("p strarr",
+ substrs = ['arr = "Hello world!'])
+
+ self.expect("frame variable strptr",
+ substrs = ['ptr = "Hello world!"'])
+
+ self.expect("p strptr",
+ substrs = ['ptr = "Hello world!"'])
+
+ self.expect("p (char*)\"1234567890123456789012345678901234567890123456789012345678901234ABC\"",
+ substrs = ['(char *) $', ' = ptr = ', ' "1234567890123456789012345678901234567890123456789012345678901234ABC"'])
+
+ self.runCmd("type summary add -c Point")
+
+ self.expect("frame variable iAmSomewhere",
+ substrs = ['x = 4',
+ 'y = 6'])
+
+ self.expect("type summary list",
+ substrs = ['Point',
+ 'one-line'])
+
+ self.runCmd("type summary add --summary-string \"y=${var.y%x}\" Point")
+
+ self.expect("frame variable iAmSomewhere",
+ substrs = ['y=0x'])
+
+ self.runCmd("type summary add --summary-string \"y=${var.y},x=${var.x}\" Point")
+
+ self.expect("frame variable iAmSomewhere",
+ substrs = ['y=6',
+ 'x=4'])
+
+ self.runCmd("type summary add --summary-string \"hello\" Point -e")
+
+ self.expect("type summary list",
+ substrs = ['Point',
+ 'show children'])
+
+ self.expect("frame variable iAmSomewhere",
+ substrs = ['hello',
+ 'x = 4',
+ '}'])
+
+ self.runCmd("type summary add --summary-string \"Sign: ${var[31]%B} Exponent: ${var[23-30]%x} Mantissa: ${var[0-22]%u}\" ShowMyGuts")
+
+ self.expect("frame variable cool_pointer->floating",
+ substrs = ['Sign: true',
+ 'Exponent: 0x',
+ '80'])
+
+ self.runCmd("type summary add --summary-string \"a test\" i_am_cool")
+
+ self.expect("frame variable cool_pointer",
+ substrs = ['a test'])
+
+ self.runCmd("type summary add --summary-string \"a test\" i_am_cool --skip-pointers")
+
+ self.expect("frame variable cool_pointer",
+ substrs = ['a test'],
+ matching = False)
+
+ self.runCmd("type summary add --summary-string \"${var[1-3]}\" \"int [5]\"")
+
+ self.expect("frame variable int_array",
+ substrs = ['2',
+ '3',
+ '4'])
+
+ self.runCmd("type summary clear")
+
+ self.runCmd("type summary add --summary-string \"${var[0-2].integer}\" \"i_am_cool *\"")
+ self.runCmd("type summary add --summary-string \"${var[2-4].integer}\" \"i_am_cool [5]\"")
+
+ self.expect("frame variable cool_array",
+ substrs = ['1,1,6'])
+
+ self.expect("frame variable cool_pointer",
+ substrs = ['3,0,0'])
+
+ # test special symbols for formatting variables into summaries
+ self.runCmd("type summary add --summary-string \"cool object @ ${var%L}\" i_am_cool")
+ self.runCmd("type summary delete \"i_am_cool [5]\"")
+
+ # this test might fail if the compiler tries to store
+ # these values into registers.. hopefully this is not
+ # going to be the case
+ self.expect("frame variable cool_array",
+ substrs = ['[0] = cool object @ 0x',
+ '[1] = cool object @ 0x',
+ '[2] = cool object @ 0x',
+ '[3] = cool object @ 0x',
+ '[4] = cool object @ 0x'])
+
+ # test getting similar output by exploiting ${var} = 'type @ location' for aggregates
+ self.runCmd("type summary add --summary-string \"${var}\" i_am_cool")
+
+ # this test might fail if the compiler tries to store
+ # these values into registers.. hopefully this is not
+ # going to be the case
+ self.expect("frame variable cool_array",
+ substrs = ['[0] = i_am_cool @ 0x',
+ '[1] = i_am_cool @ 0x',
+ '[2] = i_am_cool @ 0x',
+ '[3] = i_am_cool @ 0x',
+ '[4] = i_am_cool @ 0x'])
+
+
+ # test getting same output by exploiting %T and %L together for aggregates
+ self.runCmd("type summary add --summary-string \"${var%T} @ ${var%L}\" i_am_cool")
+
+ # this test might fail if the compiler tries to store
+ # these values into registers.. hopefully this is not
+ # going to be the case
+ self.expect("frame variable cool_array",
+ substrs = ['[0] = i_am_cool @ 0x',
+ '[1] = i_am_cool @ 0x',
+ '[2] = i_am_cool @ 0x',
+ '[3] = i_am_cool @ 0x',
+ '[4] = i_am_cool @ 0x'])
+
+ self.runCmd("type summary add --summary-string \"goofy\" i_am_cool")
+ self.runCmd("type summary add --summary-string \"${var.second_cool%S}\" i_am_cooler")
+
+ self.expect("frame variable the_coolest_guy",
+ substrs = ['(i_am_cooler) the_coolest_guy = goofy'])
+
+ # check that unwanted type specifiers are removed
+ self.runCmd("type summary delete i_am_cool")
+ self.runCmd("type summary add --summary-string \"goofy\" \"class i_am_cool\"")
+ self.expect("frame variable the_coolest_guy",
+ substrs = ['(i_am_cooler) the_coolest_guy = goofy'])
+
+ self.runCmd("type summary delete i_am_cool")
+ self.runCmd("type summary add --summary-string \"goofy\" \"enum i_am_cool\"")
+ self.expect("frame variable the_coolest_guy",
+ substrs = ['(i_am_cooler) the_coolest_guy = goofy'])
+
+ self.runCmd("type summary delete i_am_cool")
+ self.runCmd("type summary add --summary-string \"goofy\" \"struct i_am_cool\"")
+ self.expect("frame variable the_coolest_guy",
+ substrs = ['(i_am_cooler) the_coolest_guy = goofy'])
+
+ # many spaces, but we still do the right thing
+ self.runCmd("type summary delete i_am_cool")
+ self.runCmd("type summary add --summary-string \"goofy\" \"union i_am_cool\"")
+ self.expect("frame variable the_coolest_guy",
+ substrs = ['(i_am_cooler) the_coolest_guy = goofy'])
+
+ # but that not *every* specifier is removed
+ self.runCmd("type summary delete i_am_cool")
+ self.runCmd("type summary add --summary-string \"goofy\" \"wrong i_am_cool\"")
+ self.expect("frame variable the_coolest_guy", matching=False,
+ substrs = ['(i_am_cooler) the_coolest_guy = goofy'])
+
+ # check that formats are not sticking since that is the behavior we want
+ self.expect("frame variable iAmInt --format hex", substrs = ['(int) iAmInt = 0x00000001'])
+ self.expect("frame variable iAmInt", matching=False, substrs = ['(int) iAmInt = 0x00000001'])
+ self.expect("frame variable iAmInt", substrs = ['(int) iAmInt = 1'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-cpp/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-cpp/main.cpp
new file mode 100644
index 000000000000..5bcfbfd4d46e
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-cpp/main.cpp
@@ -0,0 +1,121 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+typedef float RealNumber; // should show as char
+typedef RealNumber Temperature; // should show as float
+typedef RealNumber Speed; // should show as hex
+
+typedef int Counter; // should show as int
+typedef int BitField; // should show as hex
+
+typedef BitField SignalMask; // should show as hex
+typedef BitField Modifiers; // should show as hex
+
+typedef Counter Accumulator; // should show as int
+
+typedef int Type1; // should show as char
+typedef Type1 Type2; // should show as hex
+typedef Type2 Type3; // should show as char
+typedef Type3 Type4; // should show as char
+
+typedef int ChildType; // should show as int
+typedef int AnotherChildType; // should show as int
+
+struct Point {
+ int x;
+ int y;
+ Point(int X = 3, int Y = 2) : x(X), y(Y) {}
+};
+
+typedef float ShowMyGuts;
+
+struct i_am_cool
+{
+ int integer;
+ ShowMyGuts floating;
+ char character;
+ i_am_cool(int I, ShowMyGuts F, char C) :
+ integer(I), floating(F), character(C) {}
+ i_am_cool() : integer(1), floating(2), character('3') {}
+
+};
+
+struct i_am_cooler
+{
+ i_am_cool first_cool;
+ i_am_cool second_cool;
+ ShowMyGuts floating;
+
+ i_am_cooler(int I1, int I2, float F1, float F2, char C1, char C2) :
+ first_cool(I1,F1,C1),
+ second_cool(I2,F2,C2),
+ floating((F1 + F2)/2) {}
+};
+
+struct IUseCharStar
+{
+ const char* pointer;
+ IUseCharStar() : pointer("Hello world") {}
+};
+
+int main (int argc, const char * argv[])
+{
+
+ int iAmInt = 1;
+ const float& IAmFloat = float(2.45);
+
+ RealNumber RNILookChar = 3.14;
+ Temperature TMILookFloat = 4.97;
+ Speed SPILookHex = 5.55;
+
+ Counter CTILookInt = 6;
+ BitField BFILookHex = 7;
+ SignalMask SMILookHex = 8;
+ Modifiers MFILookHex = 9;
+
+ Accumulator* ACILookInt = new Accumulator(10);
+
+ const Type1& T1ILookChar = 11;
+ Type2 T2ILookHex = 12;
+ Type3 T3ILookChar = 13;
+ Type4 T4ILookChar = 14;
+
+ AnotherChildType AHILookInt = 15;
+
+ Speed* SPPtrILookHex = new Speed(16);
+
+ Point iAmSomewhere(4,6);
+
+ i_am_cool *cool_pointer = (i_am_cool*)malloc(sizeof(i_am_cool)*3);
+ cool_pointer[0] = i_am_cool(3,-3.141592,'E');
+ cool_pointer[1] = i_am_cool(0,-3.141592,'E');
+ cool_pointer[2] = i_am_cool(0,-3.141592,'E');
+
+ i_am_cool cool_array[5];
+
+ cool_array[3].floating = 5.25;
+ cool_array[4].integer = 6;
+ cool_array[2].character = 'Q';
+
+ int int_array[] = {1,2,3,4,5};
+
+ IUseCharStar iEncapsulateCharStar;
+
+ char strarr[32] = "Hello world!";
+ char* strptr = "Hello world!";
+
+ i_am_cooler the_coolest_guy(1,2,3.14,6.28,'E','G');
+
+ return 0; // Set break point at this line.
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-disabling/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-disabling/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-disabling/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-disabling/TestDataFormatterDisabling.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-disabling/TestDataFormatterDisabling.py
new file mode 100644
index 000000000000..0f254a67d5a6
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-disabling/TestDataFormatterDisabling.py
@@ -0,0 +1,80 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class DataFormatterDisablingTestCase(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.')
+
+ @expectedFailureWindows("llvm.org/pr24462") # Data formatters have problems on Windows
+ def test_with_run_command(self):
+ """Check that we can properly disable all data formatter categories."""
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 category enable *', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ #self.runCmd('type category enable system VectorTypes libcxx gnu-libstdc++ CoreGraphics CoreServices AppKit CoreFoundation objc default', check=False)
+
+ self.expect('type category list', substrs = ['system','enabled',])
+
+ self.expect("frame variable numbers",
+ substrs = ['[0] = 1', '[3] = 1234'])
+
+ self.expect('frame variable string1', substrs = ['hello world'])
+
+ # now disable them all and check that nothing is formatted
+ self.runCmd('type category disable *')
+
+ self.expect("frame variable numbers", matching=False,
+ substrs = ['[0] = 1', '[3] = 1234'])
+
+ self.expect('frame variable string1', matching=False, substrs = ['hello world'])
+
+ self.expect('type category list', substrs = ['system','disabled',])
+
+ # now enable and check that we are back to normal
+ self.runCmd("type category enable *")
+
+ self.expect('type category list', substrs = ['system','enabled'])
+
+ self.expect("frame variable numbers",
+ substrs = ['[0] = 1', '[3] = 1234'])
+
+ self.expect('frame variable string1', substrs = ['hello world'])
+
+ self.expect('type category list', substrs = ['system','enabled'])
+
+ # last check - our cleanup will re-enable everything
+ self.runCmd('type category disable *')
+ self.expect('type category list', substrs = ['system','disabled'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-disabling/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-disabling/main.cpp
new file mode 100644
index 000000000000..9374642fb0d2
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-disabling/main.cpp
@@ -0,0 +1,18 @@
+#include <vector>
+
+int main()
+{
+
+ const char* string1 = "hello world";
+
+ std::vector<int> numbers;
+ numbers.push_back(1);
+ numbers.push_back(12);
+ numbers.push_back(123);
+ numbers.push_back(1234);
+ numbers.push_back(12345);
+ numbers.push_back(123456);
+ numbers.push_back(1234567); // Set break point at this line.
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-enum-format/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-enum-format/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-enum-format/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-enum-format/TestDataFormatterEnumFormat.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-enum-format/TestDataFormatterEnumFormat.py
new file mode 100644
index 000000000000..1659ade74a06
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-enum-format/TestDataFormatterEnumFormat.py
@@ -0,0 +1,65 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class EnumFormatTestCase(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.')
+
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ self.expect("frame variable",
+ substrs = ['(Foo) f = Case45',
+ '(int) x = 1',
+ '(int) y = 45',
+ '(int) z = 43'
+ ]);
+
+ # 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)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.runCmd("type format add --type Foo int")
+
+ # The type format list should show our custom formats.
+ self.expect("type format list -w default",
+ substrs = ['int: as type Foo'])
+
+ self.expect("frame variable",
+ substrs = ['(Foo) f = Case45',
+ '(int) x = Case1',
+ '(int) y = Case45',
+ '(int) z = 43'
+ ]);
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-enum-format/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-enum-format/main.cpp
new file mode 100644
index 000000000000..6a8074ff9fbe
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-enum-format/main.cpp
@@ -0,0 +1,13 @@
+enum Foo {
+ Case1 = 1,
+ Case2 = 2,
+ Case45 = 45
+};
+
+int main() {
+ Foo f = Case45;
+ int x = 1;
+ int y = 45;
+ int z = 43;
+ return 1; // Set break point at this line.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-globals/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-globals/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-globals/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-globals/TestDataFormatterGlobals.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-globals/TestDataFormatterGlobals.py
new file mode 100644
index 000000000000..df3bef091c89
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-globals/TestDataFormatterGlobals.py
@@ -0,0 +1,67 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class GlobalsDataFormatterTestCase(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.')
+
+ 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, loc_exact=True)
+
+ # 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)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.runCmd("type summary add --summary-string \"JustATest\" Point")
+
+ # Simply check we can get at global variables
+ self.expect("target variable g_point",
+ substrs = ['JustATest'])
+
+ self.expect("target variable g_point_pointer",
+ substrs = ['(Point *) g_point_pointer ='])
+
+ # Print some information about the variables
+ # (we ignore the actual values)
+ self.runCmd("type summary add --summary-string \"(x=${var.x},y=${var.y})\" Point")
+
+ self.expect("target variable g_point",
+ substrs = ['x=',
+ 'y='])
+
+ self.expect("target variable g_point_pointer",
+ substrs = ['(Point *) g_point_pointer ='])
+
+ # Test Python code on resulting SBValue
+ self.runCmd("type summary add --python-script \"return 'x=' + str(valobj.GetChildMemberWithName('x').GetValue());\" Point")
+
+ self.expect("target variable g_point",
+ substrs = ['x='])
+
+ self.expect("target variable g_point_pointer",
+ substrs = ['(Point *) g_point_pointer ='])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-globals/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-globals/main.cpp
new file mode 100644
index 000000000000..521f7a6931e9
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-globals/main.cpp
@@ -0,0 +1,27 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+struct Point {
+ int x;
+ int y;
+ Point(int X = 3, int Y = 2) : x(X), y(Y) {}
+};
+
+Point g_point(3,4);
+Point* g_point_pointer = new Point(7,5);
+
+int main (int argc, const char * argv[])
+{
+ return 0; // Set break point at this line.
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-named-summaries/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-named-summaries/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-named-summaries/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py
new file mode 100644
index 000000000000..94df520d29b3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py
@@ -0,0 +1,122 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class NamedSummariesDataFormatterTestCase(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.')
+
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.runCmd("type summary add --summary-string \"AllUseIt: x=${var.x} {y=${var.y}} {z=${var.z}}\" --name AllUseIt")
+ self.runCmd("type summary add --summary-string \"First: x=${var.x} y=${var.y} dummy=${var.dummy}\" First")
+ self.runCmd("type summary add --summary-string \"Second: x=${var.x} y=${var.y%hex}\" Second")
+ self.runCmd("type summary add --summary-string \"Third: x=${var.x} z=${var.z}\" Third")
+
+ self.expect("frame variable first",
+ substrs = ['First: x=12'])
+
+ self.expect("frame variable first --summary AllUseIt",
+ substrs = ['AllUseIt: x=12'])
+
+ # We *DO NOT* remember the summary choice anymore
+ self.expect("frame variable first", matching=False,
+ substrs = ['AllUseIt: x=12'])
+ self.expect("frame variable first",
+ substrs = ['First: x=12'])
+
+ self.runCmd("thread step-over") # 2
+
+ self.expect("frame variable first",
+ substrs = ['First: x=12'])
+
+ self.expect("frame variable first --summary AllUseIt",
+ substrs = ['AllUseIt: x=12',
+ 'y=34'])
+
+ self.expect("frame variable second --summary AllUseIt",
+ substrs = ['AllUseIt: x=65',
+ 'y=43.25'])
+
+ self.expect("frame variable third --summary AllUseIt",
+ substrs = ['AllUseIt: x=96',
+ 'z=',
+ 'E'])
+
+ self.runCmd("thread step-over") # 3
+
+ self.expect("frame variable second",
+ substrs = ['Second: x=65',
+ 'y=0x'])
+
+ # <rdar://problem/11576143> decided that invalid summaries will raise an error
+ # instead of just defaulting to the base summary
+ self.expect("frame variable second --summary NoSuchSummary",error=True,
+ substrs = ['must specify a valid named summary'])
+
+ self.runCmd("thread step-over")
+
+ self.runCmd("type summary add --summary-string \"FirstAndFriends: x=${var.x} {y=${var.y}} {z=${var.z}}\" First --name FirstAndFriends")
+
+ self.expect("frame variable first",
+ substrs = ['FirstAndFriends: x=12',
+ 'y=34'])
+
+ self.runCmd("type summary delete First")
+
+ self.expect("frame variable first --summary FirstAndFriends",
+ substrs = ['FirstAndFriends: x=12',
+ 'y=34'])
+
+ self.expect("frame variable first", matching=True,
+ substrs = ['x = 12',
+ 'y = 34'])
+
+ self.runCmd("type summary delete FirstAndFriends")
+ self.expect("type summary delete NoSuchSummary", error=True)
+ self.runCmd("type summary delete AllUseIt")
+
+ self.expect("frame variable first", matching=False,
+ substrs = ['FirstAndFriends'])
+
+ self.runCmd("thread step-over") # 4
+
+ self.expect("frame variable first",matching=False,
+ substrs = ['FirstAndFriends: x=12',
+ 'y=34'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-named-summaries/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-named-summaries/main.cpp
new file mode 100644
index 000000000000..fdec5fecd3a2
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-named-summaries/main.cpp
@@ -0,0 +1,59 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+struct First
+{
+ int x;
+ int y;
+ float dummy;
+ First(int X, int Y) :
+ x(X),
+ y(Y),
+ dummy(3.14)
+ {}
+};
+
+struct Second
+{
+ int x;
+ float y;
+ Second(int X, float Y) :
+ x(X),
+ y(Y)
+ {}
+};
+
+struct Third
+{
+ int x;
+ char z;
+ Third(int X, char Z) :
+ x(X),
+ z(Z)
+ {}
+};
+
+int main (int argc, const char * argv[])
+{
+ First first(12,34);
+ Second second(65,43.25);
+ Third *third = new Third(96,'E');
+
+ first.dummy = 1; // Set break point at this line.
+ first.dummy = 2;
+ first.dummy = 3;
+ first.dummy = 4;
+ first.dummy = 5;
+
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/.categories b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/.categories
new file mode 100644
index 000000000000..6326dbcec91b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/.categories
@@ -0,0 +1 @@
+dataformatters,objc
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/Makefile
new file mode 100644
index 000000000000..9f7fb1ca6231
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/Makefile
@@ -0,0 +1,9 @@
+LEVEL = ../../../make
+
+OBJC_SOURCES := main.m
+
+CFLAGS_EXTRAS += -w
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py
new file mode 100644
index 000000000000..e12ddca2eea7
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py
@@ -0,0 +1,464 @@
+# encoding: utf-8
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import datetime
+import lldbsuite.test.lldbutil as lldbutil
+
+class ObjCDataFormatterTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipUnlessDarwin
+ def test_plain_objc_with_run_command(self):
+ """Test basic ObjC formatting behavior."""
+ self.build()
+ self.plain_data_formatter_commands()
+
+ def appkit_tester_impl(self,commands):
+ self.build()
+ self.appkit_common_data_formatters_command()
+ commands()
+
+ @skipUnlessDarwin
+ def test_nsnumber_with_run_command(self):
+ """Test formatters for NSNumber."""
+ self.appkit_tester_impl(self.nsnumber_data_formatter_commands)
+
+ @skipUnlessDarwin
+ def test_nscontainers_with_run_command(self):
+ """Test formatters for NS container classes."""
+ self.appkit_tester_impl(self.nscontainers_data_formatter_commands)
+
+ @skipUnlessDarwin
+ def test_nsdata_with_run_command(self):
+ """Test formatters for NSData."""
+ self.appkit_tester_impl(self.nsdata_data_formatter_commands)
+
+ @skipUnlessDarwin
+ def test_nsurl_with_run_command(self):
+ """Test formatters for NSURL."""
+ self.appkit_tester_impl(self.nsurl_data_formatter_commands)
+
+
+ @skipUnlessDarwin
+ def test_nserror_with_run_command(self):
+ """Test formatters for NSError."""
+ self.appkit_tester_impl(self.nserror_data_formatter_commands)
+
+
+ @skipUnlessDarwin
+ def test_nsbundle_with_run_command(self):
+ """Test formatters for NSBundle."""
+ self.appkit_tester_impl(self.nsbundle_data_formatter_commands)
+
+
+ @skipUnlessDarwin
+ def test_nsexception_with_run_command(self):
+ """Test formatters for NSException."""
+ self.appkit_tester_impl(self.nsexception_data_formatter_commands)
+
+ @skipUnlessDarwin
+ def test_nsmisc_with_run_command(self):
+ """Test formatters for misc NS classes."""
+ self.appkit_tester_impl(self.nsmisc_data_formatter_commands)
+
+
+ @skipUnlessDarwin
+ def test_nsdate_with_run_command(self):
+ """Test formatters for NSDate."""
+ self.appkit_tester_impl(self.nsdate_data_formatter_commands)
+
+ @skipUnlessDarwin
+ def test_coreframeworks_and_run_command(self):
+ """Test formatters for Core OSX frameworks."""
+ self.build()
+ self.cf_data_formatter_commands()
+
+ @skipUnlessDarwin
+ def test_kvo_with_run_command(self):
+ """Test the behavior of formatters when KVO is in use."""
+ self.build()
+ self.kvo_data_formatter_commands()
+
+ @skipUnlessDarwin
+ def test_expr_with_run_command(self):
+ """Test common cases of expression parser <--> formatters interaction."""
+ self.build()
+ self.expr_objc_data_formatter_commands()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.m', '// Set break point at this line.')
+
+ def plain_data_formatter_commands(self):
+ """Test basic ObjC formatting behavior."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 synth clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.runCmd("type summary add --summary-string \"${var%@}\" MyClass")
+
+ self.expect("frame variable object2",
+ substrs = ['MyOtherClass']);
+
+ self.expect("frame variable *object2",
+ substrs = ['MyOtherClass']);
+
+ # Now let's delete the 'MyClass' custom summary.
+ self.runCmd("type summary delete MyClass")
+
+ # The type format list should not show 'MyClass' at this point.
+ self.expect("type summary list", matching=False,
+ substrs = ['MyClass'])
+
+ self.runCmd("type summary add --summary-string \"a test\" MyClass")
+
+ self.expect("frame variable *object2",
+ substrs = ['*object2 =',
+ 'MyClass = a test',
+ 'backup = ']);
+
+ self.expect("frame variable object2", matching=False,
+ substrs = ['a test']);
+
+ self.expect("frame variable object",
+ substrs = ['a test']);
+
+ self.expect("frame variable *object",
+ substrs = ['a test']);
+
+ self.expect('frame variable myclass',
+ substrs = ['(Class) myclass = NSValue'])
+ self.expect('frame variable myclass2',
+ substrs = ['(Class) myclass2 = ','NS','String'])
+ self.expect('frame variable myclass3',
+ substrs = ['(Class) myclass3 = Molecule'])
+ self.expect('frame variable myclass4',
+ substrs = ['(Class) myclass4 = NSMutableArray'])
+ self.expect('frame variable myclass5',
+ substrs = ['(Class) myclass5 = nil'])
+
+ def appkit_common_data_formatters_command(self):
+ """Test formatters for AppKit classes."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 synth clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ def nsnumber_data_formatter_commands(self):
+ # Now enable AppKit and check we are displaying Cocoa classes correctly
+ self.expect('frame variable num1 num2 num3 num4 num5 num6 num7 num8_Y num8_N num9',
+ substrs = ['(NSNumber *) num1 = ',' (int)5',
+ '(NSNumber *) num2 = ',' (float)3.1',
+ '(NSNumber *) num3 = ',' (double)3.14',
+ '(NSNumber *) num4 = ',' (long)-2',
+ '(NSNumber *) num5 = ',' (char)65',
+ '(NSNumber *) num6 = ',' (long)255',
+ '(NSNumber *) num7 = ','2000000',
+ '(NSNumber *) num8_Y = ',' @"1"',
+ '(NSNumber *) num8_N = ',' @"0"',
+ '(NSNumber *) num9 = ',' (short)-31616'])
+
+ self.expect('frame variable decimal_one',
+ substrs = ['(NSDecimalNumber *) decimal_one = 0x','1'])
+
+ self.expect('frame variable num_at1 num_at2 num_at3 num_at4',
+ substrs = ['(NSNumber *) num_at1 = ',' (int)12',
+ '(NSNumber *) num_at2 = ',' (int)-12',
+ '(NSNumber *) num_at3 = ',' (double)12.5',
+ '(NSNumber *) num_at4 = ',' (double)-12.5'])
+
+ def nscontainers_data_formatter_commands(self):
+ self.expect('frame variable newArray newDictionary newMutableDictionary cfdict_ref mutable_dict_ref cfarray_ref mutable_array_ref',
+ substrs = ['(NSArray *) newArray = ','@"50 elements"',
+ '(NSDictionary *) newDictionary = ',' 12 key/value pairs',
+ '(NSDictionary *) newMutableDictionary = ',' 21 key/value pairs',
+ '(CFDictionaryRef) cfdict_ref = ','3 key/value pairs',
+ '(CFMutableDictionaryRef) mutable_dict_ref = ','12 key/value pairs',
+ '(CFArrayRef) cfarray_ref = ','@"3 elements"',
+ '(CFMutableArrayRef) mutable_array_ref = ','@"11 elements"'])
+
+ self.expect('frame variable nscounted_set',
+ substrs = ['(NSCountedSet *) nscounted_set = ','5 elements'])
+
+ self.expect('frame variable iset1 iset2 imset',
+ substrs = ['4 indexes','512 indexes','10 indexes'])
+
+ self.expect('frame variable mutable_bag_ref cfbag_ref binheap_ref',
+ substrs = ['(CFMutableBagRef) mutable_bag_ref = ','@"17 values"',
+ '(CFBagRef) cfbag_ref = ','@"15 values"',
+ '(CFBinaryHeapRef) binheap_ref = ','@"21 items"'])
+
+ self.expect('expression -d run -- [NSArray new]', substrs=['@"0 elements"'])
+
+ def nsdata_data_formatter_commands(self):
+ self.expect('frame variable immutableData mutableData data_ref mutable_data_ref mutable_string_ref',
+ substrs = ['(NSData *) immutableData = ',' 4 bytes',
+ '(NSData *) mutableData = ',' 14 bytes',
+ '(CFDataRef) data_ref = ','@"5 bytes"',
+ '(CFMutableDataRef) mutable_data_ref = ','@"5 bytes"',
+ '(CFMutableStringRef) mutable_string_ref = ',' @"Wish ya knew"'])
+
+ def nsurl_data_formatter_commands(self):
+ self.expect('frame variable cfurl_ref cfchildurl_ref cfgchildurl_ref',
+ substrs = ['(CFURLRef) cfurl_ref = ','@"http://www.foo.bar',
+ 'cfchildurl_ref = ','@"page.html -- http://www.foo.bar',
+ '(CFURLRef) cfgchildurl_ref = ','@"?whatever -- http://www.foo.bar/page.html"'])
+
+ self.expect('frame variable nsurl nsurl2 nsurl3',
+ substrs = ['(NSURL *) nsurl = ','@"http://www.foo.bar',
+ '(NSURL *) nsurl2 =','@"page.html -- http://www.foo.bar',
+ '(NSURL *) nsurl3 = ','@"?whatever -- http://www.foo.bar/page.html"'])
+
+ def nserror_data_formatter_commands(self):
+ self.expect('frame variable nserror',
+ substrs = ['domain: @"Foobar" - code: 12'])
+
+ self.expect('frame variable nserror->_userInfo',
+ substrs = ['2 key/value pairs'])
+
+ self.expect('frame variable nserror->_userInfo --ptr-depth 1 -d run-target',
+ substrs = ['@"a"','@"b"',"1","2"])
+
+ def nsbundle_data_formatter_commands(self):
+ self.expect('frame variable bundle_string bundle_url main_bundle',
+ substrs = ['(NSBundle *) bundle_string = ',' @"/System/Library/Frameworks/Accelerate.framework"',
+ '(NSBundle *) bundle_url = ',' @"/System/Library/Frameworks/Cocoa.framework"',
+ '(NSBundle *) main_bundle = ','data-formatter-objc'])
+
+ def nsexception_data_formatter_commands(self):
+ self.expect('frame variable except0 except1 except2 except3',
+ substrs = ['(NSException *) except0 = ','name:@"TheGuyWhoHasNoName" reason:@"cuz it\'s funny"',
+ '(NSException *) except1 = ','name:@"TheGuyWhoHasNoName~1" reason:@"cuz it\'s funny"',
+ '(NSException *) except2 = ','name:@"TheGuyWhoHasNoName`2" reason:@"cuz it\'s funny"',
+ '(NSException *) except3 = ','name:@"TheGuyWhoHasNoName/3" reason:@"cuz it\'s funny"'])
+
+ def nsmisc_data_formatter_commands(self):
+ self.expect('frame variable localhost',
+ substrs = ['<NSHost ','> localhost ((','"127.0.0.1"'])
+
+ if self.getArchitecture() in ['i386', 'x86_64']:
+ self.expect('frame variable my_task',
+ substrs = ['<NS','Task: 0x'])
+
+ self.expect('frame variable range_value',
+ substrs = ['NSRange: {4, 4}'])
+
+ self.expect('frame variable port',
+ substrs = ['(NSMachPort *) port = ',' mach port: '])
+
+ def nsdate_data_formatter_commands(self):
+ self.expect('frame variable date1 date2',
+ patterns = ['(1985-04-10|1985-04-11)','(2011-01-01|2010-12-31)'])
+
+ # this test might fail if we hit the breakpoint late on December 31st of some given year
+ # and midnight comes between hitting the breakpoint and running this line of code
+ # hopefully the output will be revealing enough in that case :-)
+ now_year = str(datetime.datetime.now().year)
+
+ self.expect('frame variable date3 date4',
+ substrs = [now_year,'1970'])
+
+ self.expect('frame variable date1_abs date2_abs',
+ substrs = ['1985-04','2011-01'])
+
+ self.expect('frame variable date3_abs date4_abs',
+ substrs = [now_year,'1970'])
+
+ self.expect('frame variable cupertino home europe',
+ substrs = ['@"America/Los_Angeles"',
+ '@"Europe/Rome"',
+ '@"Europe/Paris"'])
+
+ self.expect('frame variable cupertino_ns home_ns europe_ns',
+ substrs = ['@"America/Los_Angeles"',
+ '@"Europe/Rome"',
+ '@"Europe/Paris"'])
+
+ self.expect('frame variable mut_bv',
+ substrs = ['(CFMutableBitVectorRef) mut_bv = ', '1110 0110 1011 0000 1101 1010 1000 1111 0011 0101 1101 0001 00'])
+
+
+ def expr_objc_data_formatter_commands(self):
+ """Test common cases of expression parser <--> formatters interaction."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 synth clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # check that the formatters are able to deal safely and correctly
+ # with ValueObjects that the expression parser returns
+ self.expect('expression ((id)@"Hello for long enough to avoid short string types")', matching=False,
+ substrs = ['Hello for long enough to avoid short string types'])
+
+ self.expect('expression -d run -- ((id)@"Hello for long enough to avoid short string types")',
+ substrs = ['Hello for long enough to avoid short string types'])
+
+ self.expect('expr -d run -- label1',
+ substrs = ['Process Name'])
+
+ self.expect('expr -d run -- @"Hello for long enough to avoid short string types"',
+ substrs = ['Hello for long enough to avoid short string types'])
+
+ self.expect('expr -d run --object-description -- @"Hello for long enough to avoid short string types"',
+ substrs = ['Hello for long enough to avoid short string types'])
+ self.expect('expr -d run --object-description -- @"Hello"', matching=False,
+ substrs = ['@"Hello" Hello'])
+
+
+ def cf_data_formatter_commands(self):
+ """Test formatters for Core OSX frameworks."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 synth clear', check=False)
+ self.runCmd('log timers disable', check=False)
+
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # check formatters for common Objective-C types
+ expect_strings = ['(CFGregorianUnits) cf_greg_units = 1 years, 3 months, 5 days, 12 hours, 5 minutes 7 seconds',
+ '(CFRange) cf_range = location=4 length=4',
+ '(NSPoint) ns_point = (x = 4, y = 4)',
+ '(NSRange) ns_range = location=4, length=4',
+ '(NSRect) ns_rect = (origin = (x = 1, y = 1), size = (width = 5, height = 5))',
+ '(NSRectArray) ns_rect_arr = ((x = 1, y = 1), (width = 5, height = 5)), ...',
+ '(NSSize) ns_size = (width = 5, height = 7)',
+ '(CGSize) cg_size = (width = 1, height = 6)',
+ '(CGPoint) cg_point = (x = 2, y = 7)',
+ '(CGRect) cg_rect = (origin = (x = 1, y = 2), size = (width = 7, height = 7))',
+ '(Rect) rect = (t=4, l=8, b=4, r=7)',
+ '(Rect *) rect_ptr = (t=4, l=8, b=4, r=7)',
+ '(Point) point = (v=7, h=12)',
+ '(Point *) point_ptr = (v=7, h=12)',
+ 'name:@"TheGuyWhoHasNoName" reason:@"cuz it\'s funny"',
+ '1985',
+ 'foo_selector_impl'];
+
+ if self.getArchitecture() in ['i386', 'x86_64']:
+ expect_strings.append('(HIPoint) hi_point = (x=7, y=12)')
+ expect_strings.append('(HIRect) hi_rect = origin=(x = 3, y = 5) size=(width = 4, height = 6)')
+ expect_strings.append('(RGBColor) rgb_color = red=3 green=56 blue=35')
+ expect_strings.append('(RGBColor *) rgb_color_ptr = red=3 green=56 blue=35')
+
+ self.expect("frame variable",
+ substrs = expect_strings)
+
+
+ def kvo_data_formatter_commands(self):
+ """Test the behavior of formatters when KVO is in use."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 synth clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # as long as KVO is implemented by subclassing, this test should succeed
+ # we should be able to dynamically figure out that the KVO implementor class
+ # is a subclass of Molecule, and use the appropriate summary for it
+ self.runCmd("type summary add -s JustAMoleculeHere Molecule")
+ self.expect('frame variable molecule', substrs = ['JustAMoleculeHere'])
+ self.runCmd("next")
+ self.expect("thread list",
+ substrs = ['stopped',
+ 'step over'])
+ self.expect('frame variable molecule', substrs = ['JustAMoleculeHere'])
+
+ self.runCmd("next")
+ # check that NSMutableDictionary's formatter is not confused when dealing with a KVO'd dictionary
+ self.expect('frame variable newMutableDictionary', substrs = ['(NSDictionary *) newMutableDictionary = ',' 21 key/value pairs'])
+
+ lldbutil.run_break_set_by_regexp (self, 'setAtoms')
+
+ self.runCmd("continue")
+ self.expect("frame variable _cmd",substrs = ['setAtoms:'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/main.m b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/main.m
new file mode 100644
index 000000000000..6eb7e021f70b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/main.m
@@ -0,0 +1,694 @@
+//===-- main.m ------------------------------------------------*- ObjC -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#import <Foundation/Foundation.h>
+
+#if defined(__APPLE__)
+#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
+#define IOS
+#endif
+#endif
+
+#if defined(IOS)
+#import <Foundation/NSGeometry.h>
+#else
+#import <Carbon/Carbon.h>
+#endif
+
+@interface MyClass : NSObject
+{
+ int i;
+ char c;
+ float f;
+}
+
+- (id)initWithInt: (int)x andFloat:(float)y andChar:(char)z;
+- (int)doIncrementByInt: (int)x;
+
+@end
+
+@interface MyOtherClass : MyClass
+{
+ int i2;
+ MyClass *backup;
+}
+- (id)initWithInt: (int)x andFloat:(float)y andChar:(char)z andOtherInt:(int)q;
+
+@end
+
+@implementation MyClass
+
+- (id)initWithInt: (int)x andFloat:(float)y andChar:(char)z
+{
+ self = [super init];
+ if (self) {
+ self->i = x;
+ self->f = y;
+ self->c = z;
+ }
+ return self;
+}
+
+- (int)doIncrementByInt: (int)x
+{
+ self->i += x;
+ return self->i;
+}
+
+@end
+
+@implementation MyOtherClass
+
+- (id)initWithInt: (int)x andFloat:(float)y andChar:(char)z andOtherInt:(int)q
+{
+ self = [super initWithInt:x andFloat:y andChar:z];
+ if (self) {
+ self->i2 = q;
+ self->backup = [[MyClass alloc] initWithInt:x andFloat:y andChar:z];
+ }
+ return self;
+}
+
+@end
+
+@interface Atom : NSObject {
+ float mass;
+}
+-(void)setMass:(float)newMass;
+-(float)mass;
+@end
+
+@interface Molecule : NSObject {
+ NSArray *atoms;
+}
+-(void)setAtoms:(NSArray *)newAtoms;
+-(NSArray *)atoms;
+@end
+
+@implementation Atom
+
+-(void)setMass:(float)newMass
+{
+ mass = newMass;
+}
+-(float)mass
+{
+ return mass;
+}
+
+@end
+
+@implementation Molecule
+
+-(void)setAtoms:(NSArray *)newAtoms
+{
+ atoms = newAtoms;
+}
+-(NSArray *)atoms
+{
+ return atoms;
+}
+@end
+
+@interface My_KVO_Observer : NSObject
+-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change
+ context:(void *)context;
+- (id) init;
+- (void) dealloc;
+@end
+
+@implementation My_KVO_Observer
+-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change
+ context:(void *)context {
+ // we do not really care about KVO'ing - do nothing
+ return;
+}
+- (id) init
+{
+ self = [super init];
+ return self;
+}
+
+- (void) dealloc
+{
+ [super dealloc];
+}
+@end
+
+int main (int argc, const char * argv[])
+{
+
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+ MyClass *object = [[MyClass alloc] initWithInt:1 andFloat:3.14 andChar: 'E'];
+
+ [object doIncrementByInt:3];
+
+ MyOtherClass *object2 = [[MyOtherClass alloc] initWithInt:2 andFloat:6.28 andChar: 'G' andOtherInt:-1];
+
+ [object2 doIncrementByInt:3];
+
+ NSNumber* num1 = [NSNumber numberWithInt:5];
+ NSNumber* num2 = [NSNumber numberWithFloat:3.14];
+ NSNumber* num3 = [NSNumber numberWithDouble:3.14];
+ NSNumber* num4 = [NSNumber numberWithUnsignedLongLong:0xFFFFFFFFFFFFFFFE];
+ NSNumber* num5 = [NSNumber numberWithChar:'A'];
+ NSNumber* num6 = [NSNumber numberWithUnsignedLongLong:0xFF];
+ NSNumber* num7 = [NSNumber numberWithLong:0x1E8480];
+ NSNumber* num8_Y = [NSNumber numberWithBool:YES];
+ NSNumber* num8_N = [NSNumber numberWithBool:NO];
+ NSNumber* num9 = [NSNumber numberWithShort:0x1E8480];
+ NSNumber* num_at1 = @12;
+ NSNumber* num_at2 = @-12;
+ NSNumber* num_at3 = @12.5;
+ NSNumber* num_at4 = @-12.5;
+
+ NSDecimalNumber* decimal_one = [NSDecimalNumber one];
+
+ NSString *str0 = [num6 stringValue];
+
+ NSString *str1 = [NSString stringWithCString:"A rather short ASCII NSString object is here" encoding:NSASCIIStringEncoding];
+
+ NSString *str2 = [NSString stringWithUTF8String:"A rather short UTF8 NSString object is here"];
+
+ NSString *str3 = @"A string made with the at sign is here";
+
+ NSString *str4 = [NSString stringWithFormat:@"This is string number %ld right here", (long)4];
+
+ NSRect ns_rect_4str = {{1,1},{5,5}};
+
+ NSString* str5 = NSStringFromRect(ns_rect_4str);
+
+ NSString* str6 = [@"/usr/doc/README.1ST" pathExtension];
+
+ const unichar myCharacters[] = {0x03C3,'x','x'};
+ NSString *str7 = [NSString stringWithCharacters: myCharacters
+ length: sizeof myCharacters / sizeof *myCharacters];
+
+ NSString* str8 = [@"/usr/doc/file.hasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTime" pathExtension];
+
+ const unichar myOtherCharacters[] = {'a',' ', 'v','e','r','y',' ',
+ 'm','u','c','h',' ','b','o','r','i','n','g',' ','t','a','s','k',
+ ' ','t','o',' ','w','r','i','t','e', ' ', 'a', ' ', 's', 't', 'r', 'i', 'n', 'g', ' ',
+ 't','h','i','s',' ','w','a','y','!','!',0x03C3, 0};
+ NSString *str9 = [NSString stringWithCharacters: myOtherCharacters
+ length: sizeof myOtherCharacters / sizeof *myOtherCharacters];
+
+ const unichar myNextCharacters[] = {0x03C3, 0x0000};
+
+ NSString *str10 = [NSString stringWithFormat:@"This is a Unicode string %S number %ld right here", myNextCharacters, (long)4];
+
+ NSString *str11 = NSStringFromClass([str10 class]);
+
+ NSString *label1 = @"Process Name: ";
+ NSString *label2 = @"Process Id: ";
+ NSString *processName = [[NSProcessInfo processInfo] processName];
+ NSString *processID = [NSString stringWithFormat:@"%d", [[NSProcessInfo processInfo] processIdentifier]];
+ NSString *str12 = [NSString stringWithFormat:@"%@ %@ %@ %@", label1, processName, label2, processID];
+
+ NSString *strA1 = [NSString stringWithCString:"A rather short ASCII NSString object is here" encoding:NSASCIIStringEncoding];
+
+ NSString *strA2 = [NSString stringWithUTF8String:"A rather short UTF8 NSString object is here"];
+
+ NSString *strA3 = @"A string made with the at sign is here";
+
+ NSString *strA4 = [NSString stringWithFormat:@"This is string number %ld right here", (long)4];
+
+ NSString* strA5 = NSStringFromRect(ns_rect_4str);
+
+ NSString* strA6 = [@"/usr/doc/README.1ST" pathExtension];
+
+ NSString *strA7 = [NSString stringWithCharacters: myCharacters
+ length: sizeof myCharacters / sizeof *myCharacters];
+
+ NSString* strA8 = [@"/usr/doc/file.hasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTime" pathExtension];
+
+ NSString *strA9 = [NSString stringWithCharacters: myOtherCharacters
+ length: sizeof myOtherCharacters / sizeof *myOtherCharacters];
+
+ NSString *strA10 = [NSString stringWithFormat:@"This is a Unicode string %S number %ld right here", myNextCharacters, (long)4];
+
+ NSString *strA11 = NSStringFromClass([str10 class]);
+
+ NSString *strA12 = [NSString stringWithFormat:@"%@ %@ %@ %@", label1, processName, label2, processID];
+
+ NSString *strB1 = [NSString stringWithCString:"A rather short ASCII NSString object is here" encoding:NSASCIIStringEncoding];
+
+ NSString *strB2 = [NSString stringWithUTF8String:"A rather short UTF8 NSString object is here"];
+
+ NSString *strB3 = @"A string made with the at sign is here";
+
+ NSString *strB4 = [NSString stringWithFormat:@"This is string number %ld right here", (long)4];
+
+ NSString* strB5 = NSStringFromRect(ns_rect_4str);
+
+ NSString* strB6 = [@"/usr/doc/README.1ST" pathExtension];
+
+ NSString *strB7 = [NSString stringWithCharacters: myCharacters
+ length: sizeof myCharacters / sizeof *myCharacters];
+
+ NSString* strB8 = [@"/usr/doc/file.hasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTime" pathExtension];
+
+ NSString *strB9 = [NSString stringWithCharacters: myOtherCharacters
+ length: sizeof myOtherCharacters / sizeof *myOtherCharacters];
+
+ NSString *strB10 = [NSString stringWithFormat:@"This is a Unicode string %S number %ld right here", myNextCharacters, (long)4];
+
+ NSString *strB11 = NSStringFromClass([str10 class]);
+
+ NSString *strB12 = [NSString stringWithFormat:@"%@ %@ %@ %@", label1, processName, label2, processID];
+
+ NSString *strC11 = NSStringFromClass([str10 class]);
+
+ NSString *strC12 = [NSString stringWithFormat:@"%@ %@ %@ %@", label1, processName, label2, processID];
+
+ NSString *strC1 = [NSString stringWithCString:"A rather short ASCII NSString object is here" encoding:NSASCIIStringEncoding];
+
+ NSString *strC2 = [NSString stringWithUTF8String:"A rather short UTF8 NSString object is here"];
+
+ NSString *strC3 = @"A string made with the at sign is here";
+
+ NSString *strC4 = [NSString stringWithFormat:@"This is string number %ld right here", (long)4];
+
+ NSString* strC5 = NSStringFromRect(ns_rect_4str);
+
+ NSString* strC6 = [@"/usr/doc/README.1ST" pathExtension];
+
+ NSString *strC7 = [NSString stringWithCharacters: myCharacters
+ length: sizeof myCharacters / sizeof *myCharacters];
+
+ NSString* strC8 = [@"/usr/doc/file.hasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTime" pathExtension];
+
+ NSString *strC9 = [NSString stringWithCharacters: myOtherCharacters
+ length: sizeof myOtherCharacters / sizeof *myOtherCharacters];
+
+ NSString *strC10 = [NSString stringWithFormat:@"This is a Unicode string %S number %ld right here", myNextCharacters, (long)4];
+
+ NSString *strD11 = NSStringFromClass([str10 class]);
+
+ NSString *strD12 = [NSString stringWithFormat:@"%@ %@ %@ %@", label1, processName, label2, processID];
+
+ NSString *eAcute = [NSString stringWithFormat: @"%C", 0x00E9];
+ NSString *randomHaziChar = [NSString stringWithFormat: @"%C", 0x9DC5];
+ NSString *japanese = @"色は匂へど散りぬるを";
+ NSString *italian = @"L'Italia è una Repubblica democratica, fondata sul lavoro. La sovranità appartiene al popolo, che la esercita nelle forme e nei limiti della Costituzione.";
+ NSString* french = @"Que veut cette horde d'esclaves, De traîtres, de rois conjurés?";
+ NSString* german = @"Über-Ich und aus den Ansprüchen der sozialen Umwelt";
+
+ void* data_set[3] = {str1,str2,str3};
+
+ NSString *hebrew = [NSString stringWithString:@"לילה טוב"];
+
+ NSArray* newArray = [[NSMutableArray alloc] init];
+ [newArray addObject:str1];
+ [newArray addObject:str2];
+ [newArray addObject:str3];
+ [newArray addObject:str4];
+ [newArray addObject:str5];
+ [newArray addObject:str6];
+ [newArray addObject:str7];
+ [newArray addObject:str8];
+ [newArray addObject:str9];
+ [newArray addObject:str10];
+ [newArray addObject:str11];
+ [newArray addObject:str12];
+ [newArray addObject:strA1];
+ [newArray addObject:strA2];
+ [newArray addObject:strA3];
+ [newArray addObject:strA4];
+ [newArray addObject:strA5];
+ [newArray addObject:strA6];
+ [newArray addObject:strA7];
+ [newArray addObject:strA8];
+ [newArray addObject:strA9];
+ [newArray addObject:strA10];
+ [newArray addObject:strA11];
+ [newArray addObject:strA12];
+ [newArray addObject:strB1];
+ [newArray addObject:strB2];
+ [newArray addObject:strB3];
+ [newArray addObject:strB4];
+ [newArray addObject:strB5];
+ [newArray addObject:strB6];
+ [newArray addObject:strB7];
+ [newArray addObject:strB8];
+ [newArray addObject:strB9];
+ [newArray addObject:strB10];
+ [newArray addObject:strB11];
+ [newArray addObject:strB12];
+ [newArray addObject:strC1];
+ [newArray addObject:strC2];
+ [newArray addObject:strC3];
+ [newArray addObject:strC4];
+ [newArray addObject:strC5];
+ [newArray addObject:strC6];
+ [newArray addObject:strC7];
+ [newArray addObject:strC8];
+ [newArray addObject:strC9];
+ [newArray addObject:strC10];
+ [newArray addObject:strC11];
+ [newArray addObject:strC12];
+ [newArray addObject:strD11];
+ [newArray addObject:strD12];
+
+ NSDictionary* newDictionary = [[NSDictionary alloc] initWithObjects:newArray forKeys:newArray];
+ NSDictionary *newMutableDictionary = [[NSMutableDictionary alloc] init];
+ [newMutableDictionary setObject:@"foo" forKey:@"bar0"];
+ [newMutableDictionary setObject:@"foo" forKey:@"bar1"];
+ [newMutableDictionary setObject:@"foo" forKey:@"bar2"];
+ [newMutableDictionary setObject:@"foo" forKey:@"bar3"];
+ [newMutableDictionary setObject:@"foo" forKey:@"bar4"];
+ [newMutableDictionary setObject:@"foo" forKey:@"bar5"];
+ [newMutableDictionary setObject:@"foo" forKey:@"bar6"];
+ [newMutableDictionary setObject:@"foo" forKey:@"bar7"];
+ [newMutableDictionary setObject:@"foo" forKey:@"bar8"];
+ [newMutableDictionary setObject:@"foo" forKey:@"bar9"];
+ [newMutableDictionary setObject:@"foo" forKey:@"bar10"];
+ [newMutableDictionary setObject:@"foo" forKey:@"bar11"];
+ [newMutableDictionary setObject:@"foo" forKey:@"bar12"];
+ [newMutableDictionary setObject:@"foo" forKey:@"bar13"];
+ [newMutableDictionary setObject:@"foo" forKey:@"bar14"];
+ [newMutableDictionary setObject:@"foo" forKey:@"bar15"];
+ [newMutableDictionary setObject:@"foo" forKey:@"bar16"];
+ [newMutableDictionary setObject:@"foo" forKey:@"bar17"];
+ [newMutableDictionary setObject:@"foo" forKey:@"bar18"];
+ [newMutableDictionary setObject:@"foo" forKey:@"bar19"];
+ [newMutableDictionary setObject:@"foo" forKey:@"bar20"];
+
+ NSAttributedString* attrString = [[NSAttributedString alloc] initWithString:@"hello world from foo" attributes:newDictionary];
+ [attrString isEqual:nil];
+ NSAttributedString* mutableAttrString = [[NSMutableAttributedString alloc] initWithString:@"hello world from foo" attributes:newDictionary];
+ [mutableAttrString isEqual:nil];
+
+ NSString* mutableString = [[NSMutableString alloc] initWithString:@"foo"];
+ [mutableString insertString:@"foo said this string needs to be very long so much longer than whatever other string has been seen ever before by anyone of the mankind that of course this is still not long enough given what foo our friend foo our lovely dearly friend foo desired of us so i am adding more stuff here for the sake of it and for the joy of our friend who is named guess what just foo. hence, dear friend foo, stay safe, your string is now long enough to accommodate your testing need and I will make sure that if not we extend it with even more fuzzy random meaningless words pasted one after the other from a long tiresome friday evening spent working in my office. my office mate went home but I am still randomly typing just for the fun of seeing what happens of the length of a Mutable String in Cocoa if it goes beyond one byte.. so be it, dear " atIndex:0];
+
+ NSString* mutableGetConst = [NSString stringWithCString:[mutableString cString]];
+
+ [mutableGetConst length];
+
+ NSData *immutableData = [[NSData alloc] initWithBytes:"HELLO" length:4];
+ NSData *mutableData = [[NSMutableData alloc] initWithBytes:"NODATA" length:6];
+
+ [mutableData appendBytes:"MOREDATA" length:8];
+
+ [immutableData length];
+ [mutableData length];
+
+ NSSet* nsset = [[NSSet alloc] initWithObjects:str1,str2,str3,nil];
+ NSSet *nsmutableset = [[NSMutableSet alloc] initWithObjects:str1,str2,str3,nil];
+ [nsmutableset addObject:str4];
+
+ CFDataRef data_ref = CFDataCreate(kCFAllocatorDefault, [immutableData bytes], 5);
+
+ CFMutableDataRef mutable_data_ref = CFDataCreateMutable(kCFAllocatorDefault, 8);
+ CFDataAppendBytes(mutable_data_ref, [mutableData bytes], 5);
+
+ CFMutableStringRef mutable_string_ref = CFStringCreateMutable(NULL,100);
+ CFStringAppend(mutable_string_ref, CFSTR("Wish ya knew"));
+
+ CFStringRef cfstring_ref = CFSTR("HELLO WORLD");
+
+
+ CFSetRef set_ref = CFSetCreate(NULL, data_set, 3, NULL);
+
+ CFMutableSetRef mutable_set_ref = CFSetCreateMutable(NULL, 5, NULL);
+
+ CFSetAddValue(mutable_set_ref, str1);
+ CFSetAddValue(mutable_set_ref, str2);
+ CFSetAddValue(mutable_set_ref, str3);
+ CFSetAddValue(mutable_set_ref, str4);
+ CFSetAddValue(mutable_set_ref, str5);
+ CFSetAddValue(mutable_set_ref, str6);
+ CFSetAddValue(mutable_set_ref, str7);
+ CFSetAddValue(mutable_set_ref, str8);
+ CFSetAddValue(mutable_set_ref, str9);
+ CFSetAddValue(mutable_set_ref, str10);
+ CFSetAddValue(mutable_set_ref, str11);
+ CFSetAddValue(mutable_set_ref, str12);
+
+
+ CFDictionaryRef cfdict_ref = CFDictionaryCreate(NULL, data_set, data_set, 3, NULL, NULL);
+ CFMutableDictionaryRef mutable_dict_ref = CFDictionaryCreateMutable(NULL, 16, NULL, NULL);
+
+ CFDictionarySetValue(mutable_dict_ref, str1, str1);
+ CFDictionarySetValue(mutable_dict_ref, str2, str2);
+ CFDictionarySetValue(mutable_dict_ref, str3, str3);
+ CFDictionarySetValue(mutable_dict_ref, str4, str1);
+ CFDictionarySetValue(mutable_dict_ref, str5, str2);
+ CFDictionarySetValue(mutable_dict_ref, str6, str3);
+ CFDictionarySetValue(mutable_dict_ref, str7, str1);
+ CFDictionarySetValue(mutable_dict_ref, str8, str2);
+ CFDictionarySetValue(mutable_dict_ref, str9, str3);
+ CFDictionarySetValue(mutable_dict_ref, str10, str1);
+ CFDictionarySetValue(mutable_dict_ref, str11, str2);
+ CFDictionarySetValue(mutable_dict_ref, str12, str3);
+
+ CFArrayRef cfarray_ref = CFArrayCreate(NULL, data_set, 3, NULL);
+ CFMutableArrayRef mutable_array_ref = CFArrayCreateMutable(NULL, 16, NULL);
+
+ CFArraySetValueAtIndex(mutable_array_ref, 0, str1);
+ CFArraySetValueAtIndex(mutable_array_ref, 1, str2);
+ CFArraySetValueAtIndex(mutable_array_ref, 2, str3);
+ CFArraySetValueAtIndex(mutable_array_ref, 3, str4);
+ CFArraySetValueAtIndex(mutable_array_ref, 0, str5); // replacing value at 0!!
+ CFArraySetValueAtIndex(mutable_array_ref, 4, str6);
+ CFArraySetValueAtIndex(mutable_array_ref, 5, str7);
+ CFArraySetValueAtIndex(mutable_array_ref, 6, str8);
+ CFArraySetValueAtIndex(mutable_array_ref, 7, str9);
+ CFArraySetValueAtIndex(mutable_array_ref, 8, str10);
+ CFArraySetValueAtIndex(mutable_array_ref, 9, str11);
+ CFArraySetValueAtIndex(mutable_array_ref, 10, str12);
+
+ CFMutableBagRef mutable_bag_ref = CFBagCreateMutable(NULL, 15, NULL);
+
+ CFBagSetValue(mutable_bag_ref, strB10);
+ CFBagSetValue(mutable_bag_ref, str1);
+ CFBagSetValue(mutable_bag_ref, str2);
+ CFBagSetValue(mutable_bag_ref, str3);
+ CFBagSetValue(mutable_bag_ref, str4);
+ CFBagSetValue(mutable_bag_ref, str5);
+ CFBagSetValue(mutable_bag_ref, str6);
+ CFBagSetValue(mutable_bag_ref, str7);
+ CFBagSetValue(mutable_bag_ref, str8);
+ CFBagSetValue(mutable_bag_ref, str9);
+ CFBagSetValue(mutable_bag_ref, str10);
+ CFBagSetValue(mutable_bag_ref, str11);
+ CFBagSetValue(mutable_bag_ref, str12);
+ CFBagSetValue(mutable_bag_ref, strA1);
+ CFBagSetValue(mutable_bag_ref, strA2);
+ CFBagSetValue(mutable_bag_ref, strA3);
+
+ CFBagRef cfbag_ref = CFBagCreateCopy(NULL, mutable_bag_ref);
+
+ CFBagSetValue(mutable_bag_ref, strB8);
+ CFBagSetValue(mutable_bag_ref, strC4);
+
+
+ CFBinaryHeapRef binheap_ref = CFBinaryHeapCreate(NULL, 15, &kCFStringBinaryHeapCallBacks, NULL);
+ CFBinaryHeapAddValue(binheap_ref, str1);
+ CFBinaryHeapAddValue(binheap_ref, str2);
+ CFBinaryHeapAddValue(binheap_ref, str3);
+ CFBinaryHeapAddValue(binheap_ref, str4);
+ CFBinaryHeapAddValue(binheap_ref, str5);
+ CFBinaryHeapAddValue(binheap_ref, str6);
+ CFBinaryHeapAddValue(binheap_ref, str7);
+ CFBinaryHeapAddValue(binheap_ref, str8);
+ CFBinaryHeapAddValue(binheap_ref, str9);
+ CFBinaryHeapAddValue(binheap_ref, str10);
+ CFBinaryHeapAddValue(binheap_ref, str11);
+ CFBinaryHeapAddValue(binheap_ref, str12);
+ CFBinaryHeapAddValue(binheap_ref, strA1);
+ CFBinaryHeapAddValue(binheap_ref, strB1);
+ CFBinaryHeapAddValue(binheap_ref, strC1);
+ CFBinaryHeapAddValue(binheap_ref, strA11);
+ CFBinaryHeapAddValue(binheap_ref, strB11);
+ CFBinaryHeapAddValue(binheap_ref, strC11);
+ CFBinaryHeapAddValue(binheap_ref, strB12);
+ CFBinaryHeapAddValue(binheap_ref, strC12);
+ CFBinaryHeapAddValue(binheap_ref, strA12);
+
+ CFURLRef cfurl_ref = CFURLCreateWithString(NULL, CFSTR("http://www.foo.bar/"), NULL);
+ CFURLRef cfchildurl_ref = CFURLCreateWithString(NULL, CFSTR("page.html"), cfurl_ref);
+ CFURLRef cfgchildurl_ref = CFURLCreateWithString(NULL, CFSTR("?whatever"), cfchildurl_ref);
+
+ NSDictionary *error_userInfo = @{@"a": @1, @"b" : @2};
+ NSError *nserror = [[NSError alloc] initWithDomain:@"Foobar" code:12 userInfo:error_userInfo];
+
+ NSBundle* bundle_string = [[NSBundle alloc] initWithPath:@"/System/Library/Frameworks/Accelerate.framework"];
+ NSBundle* bundle_url = [[NSBundle alloc] initWithURL:[[NSURL alloc] initWithString:@"file://localhost/System/Library/Frameworks/Cocoa.framework"]];
+
+ NSBundle* main_bundle = [NSBundle mainBundle];
+
+ NSArray* bundles = [NSBundle allBundles];
+
+ NSURL *nsurl0;
+
+ for (NSBundle* bundle in bundles)
+ {
+ nsurl0 = [bundle bundleURL];
+ }
+
+ NSException* except0 = [[NSException alloc] initWithName:@"TheGuyWhoHasNoName" reason:@"cuz it's funny" userInfo:nil];
+ NSException* except1 = [[NSException alloc] initWithName:@"TheGuyWhoHasNoName~1" reason:@"cuz it's funny" userInfo:nil];
+ NSException* except2 = [[NSException alloc] initWithName:@"TheGuyWhoHasNoName`2" reason:@"cuz it's funny" userInfo:nil];
+ NSException* except3 = [[NSException alloc] initWithName:@"TheGuyWhoHasNoName/3" reason:@"cuz it's funny" userInfo:nil];
+
+ NSMachPort *port = [NSMachPort port];
+
+ NSURL *nsurl = [[NSURL alloc] initWithString:@"http://www.foo.bar"];
+ NSURL *nsurl2 = [NSURL URLWithString:@"page.html" relativeToURL:nsurl];
+ NSURL *nsurl3 = [NSURL URLWithString:@"?whatever" relativeToURL:nsurl2];
+
+ NSDate *date1 = [NSDate dateWithNaturalLanguageString:@"6pm April 10, 1985"];
+ NSDate *date2 = [NSDate dateWithNaturalLanguageString:@"12am January 1, 2011"];
+ NSDate *date3 = [NSDate date];
+ NSDate *date4 = [NSDate dateWithTimeIntervalSince1970:24*60*60];
+
+ CFAbsoluteTime date1_abs = CFDateGetAbsoluteTime(date1);
+ CFAbsoluteTime date2_abs = CFDateGetAbsoluteTime(date2);
+ CFAbsoluteTime date3_abs = CFDateGetAbsoluteTime(date3);
+ CFAbsoluteTime date4_abs = CFDateGetAbsoluteTime(date4);
+
+ NSCountedSet *nscounted_set = [[NSCountedSet alloc] initWithCapacity:5];
+
+ [nscounted_set addObject:str0];
+ [nscounted_set addObject:str1];
+ [nscounted_set addObject:str0];
+ [nscounted_set addObject:str0];
+ [nscounted_set addObject:@"foo1"];
+ [nscounted_set addObject:@"foo2"];
+ [nscounted_set addObject:@"foo3"];
+
+ NSIndexSet *iset1 = [[NSIndexSet alloc] initWithIndexesInRange:NSMakeRange(1, 4)];
+ NSIndexSet *iset2 = [[NSIndexSet alloc] initWithIndexesInRange:NSMakeRange(1, 512)];
+
+ NSMutableIndexSet *imset = [[NSMutableIndexSet alloc] init];
+ [imset addIndex:1936];
+ [imset addIndex:7];
+ [imset addIndex:9];
+ [imset addIndex:11];
+ [imset addIndex:24];
+ [imset addIndex:41];
+ [imset addIndex:58];
+ [imset addIndex:61];
+ [imset addIndex:62];
+ [imset addIndex:63];
+
+ CFTimeZoneRef cupertino = CFTimeZoneCreateWithName (
+ NULL,
+ CFSTR("PST"),
+ YES);
+ CFTimeZoneRef home = CFTimeZoneCreateWithName (
+ NULL,
+ CFSTR("Europe/Rome"),
+ YES);
+ CFTimeZoneRef europe = CFTimeZoneCreateWithName (
+ NULL,
+ CFSTR("CET"),
+ YES);
+
+ NSTimeZone *cupertino_ns = [NSTimeZone timeZoneWithAbbreviation:@"PST"];
+ NSTimeZone *home_ns = [NSTimeZone timeZoneWithName:@"Europe/Rome"];
+ NSTimeZone *europe_ns = [NSTimeZone timeZoneWithAbbreviation:@"CET"];
+
+ NSHost *localhost = [NSHost hostWithAddress:@"127.0.0.1"];
+
+#ifndef IOS
+ NSTask *my_task = [[NSTask alloc] init];
+#endif
+
+
+ CFGregorianUnits cf_greg_units = {1,3,5,12,5,7};
+ CFGregorianDate cf_greg_date = CFAbsoluteTimeGetGregorianDate(CFDateGetAbsoluteTime(date1), NULL);
+ CFRange cf_range = {4,4};
+ NSPoint ns_point = {4,4};
+ NSRange ns_range = {4,4};
+
+ NSValue *range_value = [NSValue valueWithRange:ns_range];
+
+ NSRect ns_rect = {{1,1},{5,5}};
+ NSRect* ns_rect_ptr = &ns_rect;
+ NSRectArray ns_rect_arr = &ns_rect;
+ NSSize ns_size = {5,7};
+ NSSize* ns_size_ptr = &ns_size;
+
+ CGSize cg_size = {1,6};
+ CGPoint cg_point = {2,7};
+ CGRect cg_rect = {{1,2}, {7,7}};
+
+#ifndef IOS
+ RGBColor rgb_color = {3,56,35};
+ RGBColor* rgb_color_ptr = &rgb_color;
+#endif
+
+ Rect rect = {4,8,4,7};
+ Rect* rect_ptr = &rect;
+
+ Point point = {7,12};
+ Point* point_ptr = &point;
+
+#ifndef IOS
+ HIPoint hi_point = {7,12};
+ HIRect hi_rect = {{3,5},{4,6}};
+#endif
+
+ SEL foo_selector = @selector(foo_selector_impl);
+
+ CFMutableBitVectorRef mut_bv = CFBitVectorCreateMutable(NULL, 64);
+ CFBitVectorSetCount(mut_bv, 50);
+ CFBitVectorSetBitAtIndex(mut_bv, 0, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 1, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 2, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 5, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 6, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 8, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 10, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 11, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 16, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 17, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 19, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 20, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 22, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 24, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 28, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 29, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 30, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 30, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 31, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 34, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 35, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 37, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 39, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 40, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 41, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 43, 1);
+ CFBitVectorSetBitAtIndex(mut_bv, 47, 1);
+
+ Molecule *molecule = [Molecule new];
+
+ Class myclass = NSClassFromString(@"NSValue");
+ Class myclass2 = [str0 class];
+ Class myclass3 = [molecule class];
+ Class myclass4 = NSClassFromString(@"NSMutableArray");
+ Class myclass5 = [nil class];
+
+ NSArray *components = @[@"usr", @"blah", @"stuff"];
+ NSString *path = [NSString pathWithComponents: components];
+
+ [molecule addObserver:[My_KVO_Observer new] forKeyPath:@"atoms" options:0 context:NULL]; // Set break point at this line.
+ [newMutableDictionary addObserver:[My_KVO_Observer new] forKeyPath:@"weirdKeyToKVO" options:NSKeyValueObservingOptionNew context:NULL];
+
+ [molecule setAtoms:nil];
+ [molecule setAtoms:[NSMutableArray new]];
+
+ [pool drain];
+ return 0;
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/nsstring/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/nsstring/Makefile
new file mode 100644
index 000000000000..0d94c2247f14
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/nsstring/Makefile
@@ -0,0 +1,9 @@
+LEVEL = ../../../../make
+
+OBJC_SOURCES := main.m
+
+CFLAGS_EXTRAS += -w
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/nsstring/TestDataFormatterNSString.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/nsstring/TestDataFormatterNSString.py
new file mode 100644
index 000000000000..e11c45e9038e
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/nsstring/TestDataFormatterNSString.py
@@ -0,0 +1,107 @@
+# encoding: utf-8
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import datetime
+import lldbsuite.test.lldbutil as lldbutil
+
+class NSStringDataFormatterTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def appkit_tester_impl(self,commands):
+ self.build()
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 synth clear', check=False)
+
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+ commands()
+
+ @skipUnlessDarwin
+ def test_nsstring_with_run_command(self):
+ """Test formatters for NSString."""
+ self.appkit_tester_impl(self.nsstring_data_formatter_commands)
+
+ @skipUnlessDarwin
+ def test_rdar11106605_with_run_command(self):
+ """Check that Unicode characters come out of CFString summary correctly."""
+ self.appkit_tester_impl(self.rdar11106605_commands)
+
+ @skipUnlessDarwin
+ def test_nsstring_withNULS_with_run_command(self):
+ """Test formatters for NSString."""
+ self.appkit_tester_impl(self.nsstring_withNULs_commands)
+
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.m', '// break here')
+
+ def rdar11106605_commands(self):
+ """Check that Unicode characters come out of CFString summary correctly."""
+ self.expect('frame variable italian', substrs = ['L\'Italia è una Repubblica democratica, fondata sul lavoro. La sovranità appartiene al popolo, che la esercita nelle forme e nei limiti della Costituzione.'])
+ self.expect('frame variable french', substrs = ['Que veut cette horde d\'esclaves, De traîtres, de rois conjurés?'])
+ self.expect('frame variable german', substrs = ['Über-Ich und aus den Ansprüchen der sozialen Umwelt'])
+ self.expect('frame variable japanese', substrs = ['色は匂へど散りぬるを'])
+ self.expect('frame variable hebrew', substrs = ['לילה טוב'])
+
+ def nsstring_data_formatter_commands(self):
+ self.expect('frame variable str0 str1 str2 str3 str4 str5 str6 str8 str9 str10 str11 label1 label2 processName str12',
+ substrs = ['(NSString *) str1 = ',' @"A rather short ASCII NSString object is here"',
+ # '(NSString *) str0 = ',' @"255"',
+ '(NSString *) str1 = ',' @"A rather short ASCII NSString object is here"',
+ '(NSString *) str2 = ',' @"A rather short UTF8 NSString object is here"',
+ '(NSString *) str3 = ',' @"A string made with the at sign is here"',
+ '(NSString *) str4 = ',' @"This is string number 4 right here"',
+ '(NSString *) str5 = ',' @"{{1, 1}, {5, 5}}"',
+ '(NSString *) str6 = ',' @"1ST"',
+ '(NSString *) str8 = ',' @"hasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTime',
+ '(NSString *) str9 = ',' @"a very much boring task to write a string this way!!',
+ '(NSString *) str10 = ',' @"This is a Unicode string σ number 4 right here"',
+ '(NSString *) str11 = ',' @"__NSCFString"',
+ '(NSString *) label1 = ',' @"Process Name: "',
+ '(NSString *) label2 = ',' @"Process Id: "',
+ '(NSString *) str12 = ',' @"Process Name: a.out Process Id:'])
+ self.expect('frame variable attrString mutableAttrString mutableGetConst',
+ substrs = ['(NSAttributedString *) attrString = ',' @"hello world from foo"',
+ '(NSAttributedString *) mutableAttrString = ',' @"hello world from foo"',
+ '(NSString *) mutableGetConst = ',' @"foo said this string needs to be very long so much longer than whatever other string has been seen ever before by anyone of the mankind that of course this is still not long enough given what foo our friend foo our lovely dearly friend foo desired of us so i am adding more stuff here for the sake of it and for the joy of our friend who is named guess what just foo. hence, dear friend foo, stay safe, your string is now long enough to accommodate your testing need and I will make sure that if not we extend it with even more fuzzy random meaningless words pasted one after the other from a long tiresome friday evening spent working in my office. my office mate went home but I am still randomly typing just for the fun of seeing what happens of the length of a Mutable String in Cocoa if it goes beyond one byte.. so be it, dear foo"'])
+
+ self.expect('expr -d run-target -- path',substrs = ['usr/blah/stuff'])
+ self.expect('frame variable path',substrs = ['usr/blah/stuff'])
+
+ def nsstring_withNULs_commands(self):
+ """Check that the NSString formatter supports embedded NULs in the text"""
+ self.expect('po strwithNULs', substrs=['a very much boring task to write'])
+ self.expect('expr [strwithNULs length]', substrs=['54'])
+ self.expect('frame variable strwithNULs', substrs=['@"a very much boring task to write\\0a string this way!!'])
+ self.expect('po strwithNULs2', substrs=['a very much boring task to write'])
+ self.expect('expr [strwithNULs2 length]', substrs=['52'])
+ self.expect('frame variable strwithNULs2', substrs=['@"a very much boring task to write\\0a string this way!!'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/nsstring/main.m b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/nsstring/main.m
new file mode 100644
index 000000000000..7b8c3785a18c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/nsstring/main.m
@@ -0,0 +1,99 @@
+//===-- main.m ------------------------------------------------*- ObjC -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#import <Foundation/Foundation.h>
+
+#if defined(__APPLE__)
+#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
+#define IOS
+#endif
+#endif
+
+#if defined(IOS)
+#import <Foundation/NSGeometry.h>
+#else
+#import <Carbon/Carbon.h>
+#endif
+
+int main (int argc, const char * argv[])
+{
+
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+ NSString *str0 = [[NSNumber numberWithUnsignedLongLong:0xFF] stringValue];
+ NSString *str1 = [NSString stringWithCString:"A rather short ASCII NSString object is here" encoding:NSASCIIStringEncoding];
+ NSString *str2 = [NSString stringWithUTF8String:"A rather short UTF8 NSString object is here"];
+ NSString *str3 = @"A string made with the at sign is here";
+ NSString *str4 = [NSString stringWithFormat:@"This is string number %ld right here", (long)4];
+ NSRect ns_rect_4str = {{1,1},{5,5}};
+ NSString* str5 = NSStringFromRect(ns_rect_4str);
+ NSString* str6 = [@"/usr/doc/README.1ST" pathExtension];
+ const unichar myCharacters[] = {0x03C3,'x','x'};
+ NSString *str7 = [NSString stringWithCharacters: myCharacters
+ length: sizeof myCharacters / sizeof *myCharacters];
+ NSString* str8 = [@"/usr/doc/file.hasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTimehasVeryLongExtensionThisTime" pathExtension];
+ const unichar myOtherCharacters[] = {'a',' ', 'v','e','r','y',' ',
+ 'm','u','c','h',' ','b','o','r','i','n','g',' ','t','a','s','k',
+ ' ','t','o',' ','w','r','i','t','e', ' ', 'a', ' ', 's', 't', 'r', 'i', 'n', 'g', ' ',
+ 't','h','i','s',' ','w','a','y','!','!',0x03C3, 0};
+ NSString *str9 = [NSString stringWithCharacters: myOtherCharacters
+ length: sizeof myOtherCharacters / sizeof *myOtherCharacters];
+ const unichar myNextCharacters[] = {0x03C3, 0x0000};
+ NSString *str10 = [NSString stringWithFormat:@"This is a Unicode string %S number %ld right here", myNextCharacters, (long)4];
+ NSString *str11 = NSStringFromClass([str10 class]);
+ NSString *label1 = @"Process Name: ";
+ NSString *label2 = @"Process Id: ";
+ NSString *processName = [[NSProcessInfo processInfo] processName];
+ NSString *processID = [NSString stringWithFormat:@"%d", [[NSProcessInfo processInfo] processIdentifier]];
+ NSString *str12 = [NSString stringWithFormat:@"%@ %@ %@ %@", label1, processName, label2, processID];
+ NSString *eAcute = [NSString stringWithFormat: @"%C", 0x00E9];
+ NSString *randomHaziChar = [NSString stringWithFormat: @"%C", 0x9DC5];
+ NSString *japanese = @"色は匂へど散りぬるを";
+ NSString *italian = @"L'Italia è una Repubblica democratica, fondata sul lavoro. La sovranità appartiene al popolo, che la esercita nelle forme e nei limiti della Costituzione.";
+ NSString* french = @"Que veut cette horde d'esclaves, De traîtres, de rois conjurés?";
+ NSString* german = @"Über-Ich und aus den Ansprüchen der sozialen Umwelt";
+ void* data_set[3] = {str1,str2,str3};
+ NSString *hebrew = [NSString stringWithString:@"לילה טוב"];
+
+ NSAttributedString* attrString = [[NSAttributedString alloc] initWithString:@"hello world from foo" attributes:[NSDictionary new]];
+ [attrString isEqual:nil];
+ NSAttributedString* mutableAttrString = [[NSMutableAttributedString alloc] initWithString:@"hello world from foo" attributes:[NSDictionary new]];
+ [mutableAttrString isEqual:nil];
+
+ NSString* mutableString = [[NSMutableString alloc] initWithString:@"foo"];
+ [mutableString insertString:@"foo said this string needs to be very long so much longer than whatever other string has been seen ever before by anyone of the mankind that of course this is still not long enough given what foo our friend foo our lovely dearly friend foo desired of us so i am adding more stuff here for the sake of it and for the joy of our friend who is named guess what just foo. hence, dear friend foo, stay safe, your string is now long enough to accommodate your testing need and I will make sure that if not we extend it with even more fuzzy random meaningless words pasted one after the other from a long tiresome friday evening spent working in my office. my office mate went home but I am still randomly typing just for the fun of seeing what happens of the length of a Mutable String in Cocoa if it goes beyond one byte.. so be it, dear " atIndex:0];
+
+ NSString* mutableGetConst = [NSString stringWithCString:[mutableString cString]];
+
+ [mutableGetConst length];
+ CFMutableStringRef mutable_string_ref = CFStringCreateMutable(NULL,100);
+ CFStringAppend(mutable_string_ref, CFSTR("Wish ya knew"));
+ CFStringRef cfstring_ref = CFSTR("HELLO WORLD");
+
+ NSArray *components = @[@"usr", @"blah", @"stuff"];
+ NSString *path = [NSString pathWithComponents: components];
+
+ const unichar someOfTheseAreNUL[] = {'a',' ', 'v','e','r','y',' ',
+ 'm','u','c','h',' ','b','o','r','i','n','g',' ','t','a','s','k',
+ ' ','t','o',' ','w','r','i','t','e', 0, 'a', ' ', 's', 't', 'r', 'i', 'n', 'g', ' ',
+ 't','h','i','s',' ','w','a','y','!','!', 0x03C3, 0};
+ NSString *strwithNULs = [NSString stringWithCharacters: someOfTheseAreNUL
+ length: sizeof someOfTheseAreNUL / sizeof *someOfTheseAreNUL];
+
+ const unichar someOfTheseAreNUL2[] = {'a',' ', 'v','e','r','y',' ',
+ 'm','u','c','h',' ','b','o','r','i','n','g',' ','t','a','s','k',
+ ' ','t','o',' ','w','r','i','t','e', 0, 'a', ' ', 's', 't', 'r', 'i', 'n', 'g', ' ',
+ 't','h','i','s',' ','w','a','y','!','!'};
+ NSString *strwithNULs2 = [NSString stringWithCharacters: someOfTheseAreNUL2
+ length: sizeof someOfTheseAreNUL2 / sizeof *someOfTheseAreNUL2];
+
+ [pool drain]; // break here
+ return 0;
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/Makefile
new file mode 100644
index 000000000000..9f7fb1ca6231
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/Makefile
@@ -0,0 +1,9 @@
+LEVEL = ../../../make
+
+OBJC_SOURCES := main.m
+
+CFLAGS_EXTRAS += -w
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/TestFormattersOneIsSingular.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/TestFormattersOneIsSingular.py
new file mode 100644
index 000000000000..1281f17ab58a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/TestFormattersOneIsSingular.py
@@ -0,0 +1,90 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import datetime
+import lldbsuite.test.lldbutil as lldbutil
+
+class DataFormatterOneIsSingularTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipUnlessDarwin
+ def test_one_is_singular_with_run_command(self):
+ """Test that 1 item is not as reported as 1 items."""
+ self.build()
+ self.oneness_data_formatter_commands()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.m', '// Set break point at this line.')
+
+ def oneness_data_formatter_commands(self):
+ """Test that 1 item is not as reported as 1 items."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 synth clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # Now check that we are displaying Cocoa classes correctly
+ self.expect('frame variable key',
+ substrs = ['@"1 element"'])
+ self.expect('frame variable key', matching=False,
+ substrs = ['1 elements'])
+ self.expect('frame variable value',
+ substrs = ['@"1 element"'])
+ self.expect('frame variable value', matching=False,
+ substrs = ['1 elements'])
+ self.expect('frame variable dict',
+ substrs = ['1 key/value pair'])
+ self.expect('frame variable dict', matching=False,
+ substrs = ['1 key/value pairs'])
+ self.expect('frame variable mutable_bag_ref',
+ substrs = ['@"1 value"'])
+ self.expect('frame variable mutable_bag_ref', matching=False,
+ substrs = ['1 values'])
+ self.expect('frame variable nscounted_set',
+ substrs = ['1 element'])
+ self.expect('frame variable nscounted_set', matching=False,
+ substrs = ['1 elements'])
+ self.expect('frame variable imset',
+ substrs = ['1 index'])
+ self.expect('frame variable imset', matching=False,
+ substrs = ['1 indexes'])
+ self.expect('frame variable binheap_ref',
+ substrs = ['@"1 item"'])
+ self.expect('frame variable binheap_ref', matching=False,
+ substrs = ['1 items'])
+ self.expect('frame variable nsset',
+ substrs = ['1 element'])
+ self.expect('frame variable nsset', matching=False,
+ substrs = ['1 elements'])
+ self.expect('frame variable immutableData',
+ substrs = ['1 byte'])
+ self.expect('frame variable immutableData', matching=False,
+ substrs = ['1 bytes'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/main.m b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/main.m
new file mode 100644
index 000000000000..7204d3c7b202
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/main.m
@@ -0,0 +1,42 @@
+//===-- main.m ------------------------------------------------*- ObjC -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#import <Foundation/Foundation.h>
+
+int main (int argc, const char * argv[])
+{
+
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+
+ NSArray* key = [NSArray arrayWithObjects:@"foo",nil];
+ NSArray* value = [NSArray arrayWithObjects:@"key",nil];
+ NSDictionary *dict = [NSDictionary dictionaryWithObjects:value forKeys:key];
+
+ CFMutableBagRef mutable_bag_ref = CFBagCreateMutable(NULL, 15, NULL);
+ CFBagSetValue(mutable_bag_ref, CFSTR("Hello world"));
+
+ NSCountedSet *nscounted_set = [[NSCountedSet alloc] initWithCapacity:5];
+ [nscounted_set addObject:@"foo"];
+
+ NSMutableIndexSet *imset = [[NSMutableIndexSet alloc] init];
+ [imset addIndex:4];
+
+ CFBinaryHeapRef binheap_ref = CFBinaryHeapCreate(NULL, 15, &kCFStringBinaryHeapCallBacks, NULL);
+ CFBinaryHeapAddValue(binheap_ref, CFSTR("Hello world"));
+
+ NSSet* nsset = [[NSSet alloc] initWithObjects:@"foo",nil];
+
+ NSData *immutableData = [[NSData alloc] initWithBytes:"HELLO" length:1];
+
+
+ [pool drain];// Set break point at this line.
+ return 0;
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-ptr-to-array/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-ptr-to-array/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-ptr-to-array/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-ptr-to-array/TestPtrToArrayFormatting.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-ptr-to-array/TestPtrToArrayFormatting.py
new file mode 100644
index 000000000000..86cd3c427288
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-ptr-to-array/TestPtrToArrayFormatting.py
@@ -0,0 +1,57 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class PtrToArrayDataFormatterTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test_with_run_command(self):
+ """Test that LLDB handles the clang typeclass Paren correctly."""
+ self.build()
+ self.data_formatter_commands()
+
+ 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.')
+
+ def data_formatter_commands(self):
+ """Test that LLDB handles the clang typeclass Paren correctly."""
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 delete hex', check=False)
+ self.runCmd('type summary clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.expect('p *(int (*)[3])foo',
+ substrs = ['(int [3]) $','[0] = 1','[1] = 2','[2] = 3'])
+
+ self.expect('p *(int (*)[3])foo', matching=False,
+ substrs = ['01 00 00 00 02 00 00 00 03 00 00 00'])
+ self.expect('p *(int (*)[3])foo', matching=False,
+ substrs = ['0x000000030000000200000001'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-ptr-to-array/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-ptr-to-array/main.cpp
new file mode 100644
index 000000000000..15fa5614d7fd
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-ptr-to-array/main.cpp
@@ -0,0 +1,17 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+bool bar(int const *foo) {
+ return foo != 0; // Set break point at this line.
+}
+
+int main() {
+ int foo[] = {1,2,3};
+ return bar(foo);
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
new file mode 100644
index 000000000000..d202ff5d64e1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
@@ -0,0 +1,252 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class PythonSynthDataFormatterTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipIfFreeBSD # llvm.org/pr20545 bogus output confuses buildbot parser
+ def test_with_run_command(self):
+ """Test data formatter commands."""
+ self.build()
+ self.data_formatter_commands()
+
+ def test_rdar10960550_with_run_command(self):
+ """Test data formatter commands."""
+ self.build()
+ self.rdar10960550_formatter_commands()
+
+
+ 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 cast break point at this line.')
+ self.line3 = line_number('main.cpp', '// Set second cast break point at this line.')
+
+ def data_formatter_commands(self):
+ """Test using Python synthetic children provider."""
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # print the f00_1 variable without a synth
+ self.expect("frame variable f00_1",
+ substrs = ['a = 0',
+ 'b = 1',
+ 'r = 33']);
+
+ # now set up the synth
+ self.runCmd("script from fooSynthProvider import *")
+ self.runCmd("type synth add -l fooSynthProvider foo")
+
+ # check that we get the two real vars and the fake_a variables
+ self.expect("frame variable f00_1",
+ substrs = ['r = 33',
+ 'fake_a = 16777216',
+ 'a = 0']);
+
+ # check that we do not get the extra vars
+ self.expect("frame variable f00_1", matching=False,
+ substrs = ['b = 1']);
+
+ # check access to members by name
+ self.expect('frame variable f00_1.fake_a',
+ substrs = ['16777216'])
+
+ # check access to members by index
+ self.expect('frame variable f00_1[1]',
+ substrs = ['16777216'])
+
+ # put synthetic children in summary in several combinations
+ self.runCmd("type summary add --summary-string \"fake_a=${svar.fake_a}\" foo")
+ self.expect('frame variable f00_1',
+ substrs = ['fake_a=16777216'])
+ self.runCmd("type summary add --summary-string \"fake_a=${svar[1]}\" foo")
+ self.expect('frame variable f00_1',
+ substrs = ['fake_a=16777216'])
+
+ # clear the summary
+ self.runCmd("type summary delete foo")
+
+ # check that the caching does not span beyond the stopoint
+ self.runCmd("n")
+
+ self.expect("frame variable f00_1",
+ substrs = ['r = 33',
+ 'fake_a = 16777216',
+ 'a = 1']);
+
+ # check that altering the object also alters fake_a
+ self.runCmd("expr f00_1.a = 280")
+ self.expect("frame variable f00_1",
+ substrs = ['r = 33',
+ 'fake_a = 16777217',
+ 'a = 280']);
+
+ # check that expanding a pointer does the right thing
+ self.expect("frame variable --ptr-depth 1 f00_ptr",
+ substrs = ['r = 45',
+ 'fake_a = 218103808',
+ 'a = 12'])
+
+ # now add a filter.. it should fail
+ self.expect("type filter add foo --child b --child j", error=True,
+ substrs = ['cannot add'])
+
+ # we get the synth again..
+ self.expect('frame variable f00_1', matching=False,
+ substrs = ['b = 1',
+ 'j = 17'])
+ self.expect("frame variable --ptr-depth 1 f00_ptr",
+ substrs = ['r = 45',
+ 'fake_a = 218103808',
+ 'a = 12'])
+
+ # now delete the synth and add the filter
+ self.runCmd("type synth delete foo")
+ self.runCmd("type filter add foo --child b --child j")
+
+ self.expect('frame variable f00_1',
+ substrs = ['b = 1',
+ 'j = 17'])
+ self.expect("frame variable --ptr-depth 1 f00_ptr", matching=False,
+ substrs = ['r = 45',
+ 'fake_a = 218103808',
+ 'a = 12'])
+
+ # now add the synth and it should fail
+ self.expect("type synth add -l fooSynthProvider foo", error=True,
+ substrs = ['cannot add'])
+
+ # check the listing
+ self.expect('type synth list', matching=False,
+ substrs = ['foo',
+ 'Python class fooSynthProvider'])
+ self.expect('type filter list',
+ substrs = ['foo',
+ '.b',
+ '.j'])
+
+ # delete the filter, add the synth
+ self.runCmd("type filter delete foo")
+ self.runCmd("type synth add -l fooSynthProvider foo")
+
+ self.expect('frame variable f00_1', matching=False,
+ substrs = ['b = 1',
+ 'j = 17'])
+ self.expect("frame variable --ptr-depth 1 f00_ptr",
+ substrs = ['r = 45',
+ 'fake_a = 218103808',
+ 'a = 12'])
+
+ # check the listing
+ self.expect('type synth list',
+ substrs = ['foo',
+ 'Python class fooSynthProvider'])
+ self.expect('type filter list', matching=False,
+ substrs = ['foo',
+ '.b',
+ '.j'])
+
+ # delete the synth and check that we get good output
+ self.runCmd("type synth delete foo")
+
+ self.expect("frame variable f00_1",
+ substrs = ['a = 280',
+ 'b = 1',
+ 'j = 17']);
+
+ self.expect("frame variable f00_1", matching=False,
+ substrs = ['fake_a = '])
+
+ def rdar10960550_formatter_commands(self):
+ """Test that synthetic children persist stoppoints."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ # The second breakpoint is on a multi-line expression, so the comment can't be on the right line...
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line2, num_expected_locations=1, loc_exact=False)
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line3, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.runCmd("command script import ./ftsp.py --allow-reload")
+ self.runCmd("type synth add -l ftsp.ftsp wrapint")
+
+ # we need to check that the VO is properly updated so that the same synthetic children are reused
+ # but their values change correctly across stop-points - in order to do this, self.runCmd("next")
+ # does not work because it forces a wipe of the stack frame - this is why we are using this more contrived
+ # mechanism to achieve our goal of preserving test_cast as a VO
+ test_cast = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('test_cast')
+
+ str_cast = str(test_cast)
+
+ if self.TraceOn():
+ print(str_cast)
+
+ self.assertTrue(str_cast.find('A') != -1, 'could not find A in output')
+ self.assertTrue(str_cast.find('B') != -1, 'could not find B in output')
+ self.assertTrue(str_cast.find('C') != -1, 'could not find C in output')
+ self.assertTrue(str_cast.find('D') != -1, 'could not find D in output')
+ self.assertTrue(str_cast.find("4 = '\\0'") != -1, 'could not find item 4 == 0')
+
+ self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().StepOver()
+
+ str_cast = str(test_cast)
+
+ if self.TraceOn():
+ print(str_cast)
+
+ # we detect that all the values of the child objects have changed - but the counter-generated item
+ # is still fixed at 0 because it is cached - this would fail if update(self): in ftsp returned False
+ # or if synthetic children were not being preserved
+ self.assertTrue(str_cast.find('Q') != -1, 'could not find Q in output')
+ self.assertTrue(str_cast.find('X') != -1, 'could not find X in output')
+ self.assertTrue(str_cast.find('T') != -1, 'could not find T in output')
+ self.assertTrue(str_cast.find('F') != -1, 'could not find F in output')
+ self.assertTrue(str_cast.find("4 = '\\0'") != -1, 'could not find item 4 == 0')
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py
new file mode 100644
index 000000000000..0dc2c233e2a6
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py
@@ -0,0 +1,23 @@
+import lldb
+class fooSynthProvider:
+ def __init__(self, valobj, dict):
+ self.valobj = valobj;
+ self.int_type = valobj.GetType().GetBasicType(lldb.eBasicTypeInt)
+ def num_children(self):
+ return 3;
+ def get_child_at_index(self, index):
+ if index == 0:
+ child = self.valobj.GetChildMemberWithName('a');
+ if index == 1:
+ child = self.valobj.CreateChildAtOffset ('fake_a', 1, self.int_type);
+ if index == 2:
+ child = self.valobj.GetChildMemberWithName('r');
+ return child;
+ def get_child_index(self, name):
+ if name == 'a':
+ return 0;
+ if name == 'fake_a':
+ return 1;
+ return 2;
+ def update(self):
+ return True \ No newline at end of file
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/ftsp.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/ftsp.py
new file mode 100644
index 000000000000..d162b00db329
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/ftsp.py
@@ -0,0 +1,32 @@
+import lldb
+
+counter = 0
+
+class ftsp:
+ def __init__(self, valobj, dict):
+ self.valobj = valobj;
+ def num_children(self):
+ if self.char.IsValid():
+ return 5;
+ return 0;
+ def get_child_index(self,name):
+ return 0;
+ def get_child_at_index(self,index):
+ if index == 0:
+ return self.x.Cast(self.char)
+ if index == 4:
+ return self.valobj.CreateValueFromExpression(str(index),'(char)('+str(self.count)+')')
+ return self.x.CreateChildAtOffset(str(index),
+ index,
+ self.char);
+ def update(self):
+ self.x = self.valobj.GetChildMemberWithName('x');
+ self.char = self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar)
+ global counter
+ self.count = counter
+ counter = counter + 1
+ return True # important: if we return False here, or fail to return, the test will fail
+
+def __lldb_init_module(debugger, dict):
+ global counter
+ counter = 0 \ No newline at end of file
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp
new file mode 100644
index 000000000000..48b29dcfd6e4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp
@@ -0,0 +1,66 @@
+struct foo
+{
+ int a;
+ int b;
+ int c;
+ int d;
+ int e;
+ int f;
+ int g;
+ int h;
+ int i;
+ int j;
+ int k;
+ int l;
+ int m;
+ int n;
+ int o;
+ int p;
+ int q;
+ int r;
+
+ foo(int X) :
+ a(X),
+ b(X+1),
+ c(X+3),
+ d(X+5),
+ e(X+7),
+ f(X+9),
+ g(X+11),
+ h(X+13),
+ i(X+15),
+ j(X+17),
+ k(X+19),
+ l(X+21),
+ m(X+23),
+ n(X+25),
+ o(X+27),
+ p(X+29),
+ q(X+31),
+ r(X+33) {}
+};
+
+struct wrapint
+{
+ int x;
+ wrapint(int X) : x(X) {}
+};
+
+int main()
+{
+ foo f00_1(0);
+ foo *f00_ptr = new foo(12);
+
+ f00_1.a++; // Set break point at this line.
+
+ wrapint test_cast('A' +
+ 256*'B' +
+ 256*256*'C'+
+ 256*256*256*'D');
+ // Set cast break point at this line.
+ test_cast.x = 'Q' +
+ 256*'X' +
+ 256*256*'T'+
+ 256*256*256*'F';
+ return 0; // Set second cast break point at this line.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-script/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-script/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-script/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py
new file mode 100644
index 000000000000..324b372cb11e
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py
@@ -0,0 +1,170 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class ScriptDataFormatterTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test_with_run_command(self):
+ """Test data formatter commands."""
+ self.build()
+ self.data_formatter_commands()
+
+ 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.')
+
+ def data_formatter_commands(self):
+ """Test that that file and class static variables display correctly."""
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # Set the script here to ease the formatting
+ script = 'a = valobj.GetChildMemberWithName(\'integer\'); a_val = a.GetValue(); str = \'Hello from Python, \' + a_val + \' time\'; return str + (\'!\' if a_val == \'1\' else \'s!\');'
+
+ self.runCmd("type summary add i_am_cool --python-script \"%s\"" % script)
+
+ self.expect("frame variable one",
+ substrs = ['Hello from Python',
+ '1 time!'])
+
+ self.expect("frame variable two",
+ substrs = ['Hello from Python',
+ '4 times!'])
+
+ self.runCmd("n"); # skip ahead to make values change
+
+ self.expect("frame variable three",
+ substrs = ['Hello from Python, 10 times!',
+ 'Hello from Python, 4 times!'])
+
+ self.runCmd("n"); # skip ahead to make values change
+
+ self.expect("frame variable two",
+ substrs = ['Hello from Python',
+ '1 time!'])
+
+ script = 'a = valobj.GetChildMemberWithName(\'integer\'); a_val = a.GetValue(); str = \'int says \' + a_val; return str;'
+
+ # Check that changes in the script are immediately reflected
+ self.runCmd("type summary add i_am_cool --python-script \"%s\"" % script)
+
+ self.expect("frame variable two",
+ substrs = ['int says 1'])
+
+ self.expect("frame variable twoptr",
+ substrs = ['int says 1'])
+
+ # Change the summary
+ self.runCmd("type summary add --summary-string \"int says ${var.integer}, and float says ${var.floating}\" i_am_cool")
+
+ self.expect("frame variable two",
+ substrs = ['int says 1',
+ 'and float says 2.71'])
+ # Try it for pointers
+ self.expect("frame variable twoptr",
+ substrs = ['int says 1',
+ 'and float says 2.71'])
+
+ # Force a failure for pointers
+ self.runCmd("type summary add i_am_cool -p --python-script \"%s\"" % script)
+
+ self.expect("frame variable twoptr", matching=False,
+ substrs = ['and float says 2.71'])
+
+ script = 'return \'Python summary\'';
+
+ self.runCmd("type summary add --name test_summary --python-script \"%s\"" % script)
+
+ # attach the Python named summary to someone
+ self.expect("frame variable one --summary test_summary",
+ substrs = ['Python summary'])
+
+ # should not bind to the type
+ self.expect("frame variable two", matching=False,
+ substrs = ['Python summary'])
+
+ # and should not stick to the variable
+ self.expect("frame variable one",matching=False,
+ substrs = ['Python summary'])
+
+ self.runCmd("type summary add i_am_cool --summary-string \"Text summary\"")
+
+ # should be temporary only
+ self.expect("frame variable one",matching=False,
+ substrs = ['Python summary'])
+
+ # use the type summary
+ self.expect("frame variable two",
+ substrs = ['Text summary'])
+
+ self.runCmd("n"); # skip ahead to make values change
+
+ # both should use the type summary now
+ self.expect("frame variable one",
+ substrs = ['Text summary'])
+
+ self.expect("frame variable two",
+ substrs = ['Text summary'])
+
+ # disable type summary for pointers, and make a Python regex summary
+ self.runCmd("type summary add i_am_cool -p --summary-string \"Text summary\"")
+ self.runCmd("type summary add -x cool --python-script \"%s\"" % script)
+
+ # variables should stick to the type summary
+ self.expect("frame variable one",
+ substrs = ['Text summary'])
+
+ self.expect("frame variable two",
+ substrs = ['Text summary'])
+
+ # array and pointer should match the Python one
+ self.expect("frame variable twoptr",
+ substrs = ['Python summary'])
+
+ self.expect("frame variable array",
+ substrs = ['Python summary'])
+
+ # return pointers to the type summary
+ self.runCmd("type summary add i_am_cool --summary-string \"Text summary\"")
+
+ self.expect("frame variable one",
+ substrs = ['Text summary'])
+
+ self.expect("frame variable two",
+ substrs = ['Text summary'])
+
+ self.expect("frame variable twoptr",
+ substrs = ['Text summary'])
+
+ self.expect("frame variable array",
+ substrs = ['Python summary'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-script/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-script/main.cpp
new file mode 100644
index 000000000000..aaccb6329acf
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-script/main.cpp
@@ -0,0 +1,53 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+struct i_am_cool
+{
+ int integer;
+ float floating;
+ char character;
+ i_am_cool(int I, float F, char C) :
+ integer(I), floating(F), character(C) {}
+ i_am_cool() : integer(1), floating(2), character('3') {}
+
+};
+
+struct i_am_cooler
+{
+ i_am_cool first_cool;
+ i_am_cool second_cool;
+ float floating;
+
+ i_am_cooler(int I1, int I2, float F1, float F2, char C1, char C2) :
+ first_cool(I1,F1,C1),
+ second_cool(I2,F2,C2),
+ floating((F1 + F2)/2) {}
+};
+
+int main (int argc, const char * argv[])
+{
+ i_am_cool one(1,3.14,'E');
+ i_am_cool two(4,2.71,'G');
+
+ i_am_cool* twoptr = &two;
+
+ i_am_cool array[5];
+
+ i_am_cooler three(10,4,1985,1/1/2011,'B','E'); // Set break point at this line.
+
+ two.integer = 1;
+
+ int dummy = 1;
+
+ return 0;
+} \ No newline at end of file
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/Makefile
new file mode 100644
index 000000000000..b438bbb970f6
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/Makefile
@@ -0,0 +1,19 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+# clang-3.5+ outputs FullDebugInfo by default for Darwin/FreeBSD
+# targets. Other targets do not, which causes this test to fail.
+# This flag enables FullDebugInfo for all targets.
+ifneq (,$(findstring clang,$(CC)))
+ CFLAGS_EXTRAS += -fno-limit-debug-info
+endif
+
+include $(LEVEL)/Makefile.rules
+
+CXXFLAGS += -O0
+
+ifeq (,$(findstring gcc,$(CC)))
+CXXFLAGS += -stdlib=libstdc++
+LDFLAGS += -stdlib=libstdc++
+endif
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py
new file mode 100644
index 000000000000..38e700812d05
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py
@@ -0,0 +1,175 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class SkipSummaryDataFormatterTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureFreeBSD("llvm.org/pr20548") # fails to build on lab.llvm.org buildbot
+ @expectedFailureWindows("llvm.org/pr24462") # Data formatters have problems on Windows
+ def test_with_run_command(self):
+ """Test data formatter commands."""
+ self.build()
+ self.data_formatter_commands()
+
+ 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.')
+
+ def data_formatter_commands(self):
+ """Test that that file and class static variables display correctly."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ #import lldbsuite.test.lldbutil as lldbutil
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
+
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # Setup the summaries for this scenario
+ #self.runCmd("type summary add --summary-string \"${var._M_dataplus._M_p}\" std::string")
+ self.runCmd("type summary add --summary-string \"Level 1\" \"DeepData_1\"")
+ self.runCmd("type summary add --summary-string \"Level 2\" \"DeepData_2\" -e")
+ self.runCmd("type summary add --summary-string \"Level 3\" \"DeepData_3\"")
+ self.runCmd("type summary add --summary-string \"Level 4\" \"DeepData_4\"")
+ self.runCmd("type summary add --summary-string \"Level 5\" \"DeepData_5\"")
+
+ # Default case, just print out summaries
+ self.expect('frame variable',
+ substrs = ['(DeepData_1) data1 = Level 1',
+ '(DeepData_2) data2 = Level 2 {',
+ 'm_child1 = Level 3',
+ 'm_child2 = Level 3',
+ 'm_child3 = Level 3',
+ 'm_child4 = Level 3',
+ '}'])
+
+ # Skip the default (should be 1) levels of summaries
+ self.expect('frame variable --no-summary-depth',
+ substrs = ['(DeepData_1) data1 = {',
+ 'm_child1 = 0x',
+ '}',
+ '(DeepData_2) data2 = {',
+ 'm_child1 = Level 3',
+ 'm_child2 = Level 3',
+ 'm_child3 = Level 3',
+ 'm_child4 = Level 3',
+ '}'])
+
+ # Now skip 2 levels of summaries
+ self.expect('frame variable --no-summary-depth=2',
+ substrs = ['(DeepData_1) data1 = {',
+ 'm_child1 = 0x',
+ '}',
+ '(DeepData_2) data2 = {',
+ 'm_child1 = {',
+ 'm_child1 = 0x',
+ 'Level 4',
+ 'm_child2 = {',
+ 'm_child3 = {',
+ '}'])
+
+ # Check that no "Level 3" comes out
+ self.expect('frame variable data1.m_child1 --no-summary-depth=2', matching=False,
+ substrs = ['Level 3'])
+
+ # Now expand a pointer with 2 level of skipped summaries
+ self.expect('frame variable data1.m_child1 --no-summary-depth=2',
+ substrs = ['(DeepData_2 *) data1.m_child1 = 0x'])
+
+ # Deref and expand said pointer
+ self.expect('frame variable *data1.m_child1 --no-summary-depth=2',
+ substrs = ['(DeepData_2) *data1.m_child1 = {',
+ 'm_child2 = {',
+ 'm_child1 = 0x',
+ 'Level 4',
+ '}'])
+
+ # Expand an expression, skipping 2 layers of summaries
+ self.expect('frame variable data1.m_child1->m_child2 --no-summary-depth=2',
+ substrs = ['(DeepData_3) data1.m_child1->m_child2 = {',
+ 'm_child2 = {',
+ 'm_child1 = Level 5',
+ 'm_child2 = Level 5',
+ 'm_child3 = Level 5',
+ '}'])
+
+ # Expand same expression, skipping only 1 layer of summaries
+ self.expect('frame variable data1.m_child1->m_child2 --no-summary-depth=1',
+ substrs = ['(DeepData_3) data1.m_child1->m_child2 = {',
+ 'm_child1 = 0x',
+ 'Level 4',
+ 'm_child2 = Level 4',
+ '}'])
+
+ # Bad debugging info on SnowLeopard gcc (Apple Inc. build 5666).
+ # Skip the following tests if the condition is met.
+ if self.getCompiler().endswith('gcc') and not self.getCompiler().endswith('llvm-gcc'):
+ import re
+ gcc_version_output = system([[lldbutil.which(self.getCompiler()), "-v"]])[1]
+ #print("my output:", gcc_version_output)
+ for line in gcc_version_output.split(os.linesep):
+ m = re.search('\(Apple Inc\. build ([0-9]+)\)', line)
+ #print("line:", line)
+ if m:
+ gcc_build = int(m.group(1))
+ #print("gcc build:", gcc_build)
+ if gcc_build >= 5666:
+ # rdar://problem/9804600"
+ self.skipTest("rdar://problem/9804600 wrong namespace for std::string in debug info")
+
+ # Expand same expression, skipping 3 layers of summaries
+ self.expect('frame variable data1.m_child1->m_child2 --show-types --no-summary-depth=3',
+ substrs = ['(DeepData_3) data1.m_child1->m_child2 = {',
+ 'm_some_text = "Just a test"',
+ 'm_child2 = {',
+ 'm_some_text = "Just a test"'])
+
+ # Expand within a standard string (might depend on the implementation of the C++ stdlib you use)
+ self.expect('frame variable data1.m_child1->m_child2.m_child1.m_child2 --no-summary-depth=2',
+ substrs = ['(DeepData_5) data1.m_child1->m_child2.m_child1.m_child2 = {',
+ 'm_some_text = {',
+ '_M_dataplus = (_M_p = "Just a test")'])
+
+ # Repeat the above, but only skip 1 level of summaries
+ self.expect('frame variable data1.m_child1->m_child2.m_child1.m_child2 --no-summary-depth=1',
+ substrs = ['(DeepData_5) data1.m_child1->m_child2.m_child1.m_child2 = {',
+ 'm_some_text = "Just a test"',
+ '}'])
+
+ # Change summary and expand, first without --no-summary-depth then with --no-summary-depth
+ self.runCmd("type summary add --summary-string \"${var.m_some_text}\" DeepData_5")
+
+ self.expect('fr var data2.m_child4.m_child2.m_child2',
+ substrs = ['(DeepData_5) data2.m_child4.m_child2.m_child2 = "Just a test"'])
+
+ self.expect('fr var data2.m_child4.m_child2.m_child2 --no-summary-depth',
+ substrs = ['(DeepData_5) data2.m_child4.m_child2.m_child2 = {',
+ 'm_some_text = "Just a test"',
+ '}'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/main.cpp
new file mode 100644
index 000000000000..82ffb2c20d47
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/main.cpp
@@ -0,0 +1,57 @@
+#include <string>
+
+struct DeepData_5
+{
+ std::string m_some_text;
+ DeepData_5() :
+ m_some_text("Just a test") {}
+};
+
+struct DeepData_4
+{
+ DeepData_5 m_child1;
+ DeepData_5 m_child2;
+ DeepData_5 m_child3;
+};
+
+struct DeepData_3
+{
+ DeepData_4& m_child1;
+ DeepData_4 m_child2;
+
+ DeepData_3() : m_child1(* (new DeepData_4())), m_child2(DeepData_4()) {}
+};
+
+struct DeepData_2
+{
+ DeepData_3 m_child1;
+ DeepData_3 m_child2;
+ DeepData_3 m_child3;
+ DeepData_3 m_child4;
+};
+
+struct DeepData_1
+{
+ DeepData_2 *m_child1;
+
+ DeepData_1() :
+ m_child1(new DeepData_2())
+ {}
+};
+
+/*
+ type summary add -f "${var._M_dataplus._M_p}" std::string
+ type summary add -f "Level 1" "DeepData_1"
+ type summary add -f "Level 2" "DeepData_2" -e
+ type summary add -f "Level 3" "DeepData_3"
+ type summary add -f "Level 4" "DeepData_4"
+ type summary add -f "Level 5" "DeepData_5"
+ */
+
+int main()
+{
+ DeepData_1 data1;
+ DeepData_2 data2;
+
+ return 0; // Set break point at this line.
+} \ No newline at end of file
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-smart-array/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-smart-array/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-smart-array/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py
new file mode 100644
index 000000000000..ca8858dbad9b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py
@@ -0,0 +1,348 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class SmartArrayDataFormatterTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureWindows("llvm.org/pr24462") # Data formatters have problems on Windows
+ def test_with_run_command(self):
+ """Test data formatter commands."""
+ self.build()
+ self.data_formatter_commands()
+
+ 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.')
+
+ def data_formatter_commands(self):
+ """Test that that file and class static variables display correctly."""
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+# check that we are not looping here
+ self.runCmd("type summary add --summary-string \"${var%V}\" SomeData")
+
+ self.expect("frame variable data",
+ substrs = ['SomeData @ 0x'])
+# ${var%s}
+ self.runCmd("type summary add --summary-string \"ptr = ${var%s}\" \"char *\"")
+
+ self.expect("frame variable strptr",
+ substrs = ['ptr = \"',
+ 'Hello world!'])
+
+ self.expect("frame variable other.strptr",
+ substrs = ['ptr = \"',
+ 'Nested Hello world!'])
+
+ self.runCmd("type summary add --summary-string \"arr = ${var%s}\" -x \"char \\[[0-9]+\\]\"")
+
+ self.expect("frame variable strarr",
+ substrs = ['arr = \"',
+ 'Hello world!'])
+
+ self.expect("frame variable other.strarr",
+ substrs = ['arr = \"',
+ 'Nested Hello world!'])
+
+ self.expect("p strarr",
+ substrs = ['arr = \"',
+ 'Hello world!'])
+
+ self.expect("p other.strarr",
+ substrs = ['arr = \"',
+ 'Nested Hello world!'])
+
+# ${var%c}
+ self.runCmd("type summary add --summary-string \"ptr = ${var%c}\" \"char *\"")
+
+ self.expect("frame variable strptr",
+ substrs = ['ptr = \"',
+ 'Hello world!'])
+
+ self.expect("frame variable other.strptr",
+ substrs = ['ptr = \"',
+ 'Nested Hello world!'])
+
+ self.expect("p strptr",
+ substrs = ['ptr = \"',
+ 'Hello world!'])
+
+ self.expect("p other.strptr",
+ substrs = ['ptr = \"',
+ 'Nested Hello world!'])
+
+ self.runCmd("type summary add --summary-string \"arr = ${var%c}\" -x \"char \\[[0-9]+\\]\"")
+
+ self.expect("frame variable strarr",
+ substrs = ['arr = \"',
+ 'Hello world!'])
+
+ self.expect("frame variable other.strarr",
+ substrs = ['arr = \"',
+ 'Nested Hello world!'])
+
+ self.expect("p strarr",
+ substrs = ['arr = \"',
+ 'Hello world!'])
+
+ self.expect("p other.strarr",
+ substrs = ['arr = \"',
+ 'Nested Hello world!'])
+
+# ${var%char[]}
+ self.runCmd("type summary add --summary-string \"arr = ${var%char[]}\" -x \"char \\[[0-9]+\\]\"")
+
+ self.expect("frame variable strarr",
+ substrs = ['arr = \"',
+ 'Hello world!'])
+
+ self.expect("frame variable other.strarr",
+ substrs = ['arr = ',
+ 'Nested Hello world!'])
+
+ self.expect("p strarr",
+ substrs = ['arr = \"',
+ 'Hello world!'])
+
+ self.expect("p other.strarr",
+ substrs = ['arr = ',
+ 'Nested Hello world!'])
+
+ self.runCmd("type summary add --summary-string \"ptr = ${var%char[]}\" \"char *\"")
+
+ self.expect("frame variable strptr",
+ substrs = ['ptr = \"',
+ 'Hello world!'])
+
+ self.expect("frame variable other.strptr",
+ substrs = ['ptr = \"',
+ 'Nested Hello world!'])
+
+ self.expect("p strptr",
+ substrs = ['ptr = \"',
+ 'Hello world!'])
+
+ self.expect("p other.strptr",
+ substrs = ['ptr = \"',
+ 'Nested Hello world!'])
+
+# ${var%a}
+ self.runCmd("type summary add --summary-string \"arr = ${var%a}\" -x \"char \\[[0-9]+\\]\"")
+
+ self.expect("frame variable strarr",
+ substrs = ['arr = \"',
+ 'Hello world!'])
+
+ self.expect("frame variable other.strarr",
+ substrs = ['arr = ',
+ 'Nested Hello world!'])
+
+ self.expect("p strarr",
+ substrs = ['arr = \"',
+ 'Hello world!'])
+
+ self.expect("p other.strarr",
+ substrs = ['arr = ',
+ 'Nested Hello world!'])
+
+ self.runCmd("type summary add --summary-string \"ptr = ${var%a}\" \"char *\"")
+
+ self.expect("frame variable strptr",
+ substrs = ['ptr = \"',
+ 'Hello world!'])
+
+ self.expect("frame variable other.strptr",
+ substrs = ['ptr = \"',
+ 'Nested Hello world!'])
+
+ self.expect("p strptr",
+ substrs = ['ptr = \"',
+ 'Hello world!'])
+
+ self.expect("p other.strptr",
+ substrs = ['ptr = \"',
+ 'Nested Hello world!'])
+
+ self.runCmd("type summary add --summary-string \"ptr = ${var[]%char[]}\" \"char *\"")
+
+# I do not know the size of the data, but you are asking for a full array slice..
+# use the ${var%char[]} to obtain a string as result
+ self.expect("frame variable strptr", matching=False,
+ substrs = ['ptr = \"',
+ 'Hello world!'])
+
+ self.expect("frame variable other.strptr", matching=False,
+ substrs = ['ptr = \"',
+ 'Nested Hello world!'])
+
+ self.expect("p strptr", matching=False,
+ substrs = ['ptr = \"',
+ 'Hello world!'])
+
+ self.expect("p other.strptr", matching=False,
+ substrs = ['ptr = \"',
+ 'Nested Hello world!'])
+
+# You asked an array-style printout...
+ self.runCmd("type summary add --summary-string \"ptr = ${var[0-1]%char[]}\" \"char *\"")
+
+ self.expect("frame variable strptr",
+ substrs = ['ptr = ',
+ '[{H},{e}]'])
+
+ self.expect("frame variable other.strptr",
+ substrs = ['ptr = ',
+ '[{N},{e}]'])
+
+ self.expect("p strptr",
+ substrs = ['ptr = ',
+ '[{H},{e}]'])
+
+ self.expect("p other.strptr",
+ substrs = ['ptr = ',
+ '[{N},{e}]'])
+
+# using [] is required here
+ self.runCmd("type summary add --summary-string \"arr = ${var%x}\" \"int [5]\"")
+
+ self.expect("frame variable intarr",matching=False,
+ substrs = ['0x00000001,0x00000001,0x00000002,0x00000003,0x00000005'])
+
+ self.expect("frame variable other.intarr", matching=False,
+ substrs = ['0x00000009,0x00000008,0x00000007,0x00000006,0x00000005'])
+
+ self.runCmd("type summary add --summary-string \"arr = ${var[]%x}\" \"int [5]\"")
+
+ self.expect("frame variable intarr",
+ substrs = ['intarr = arr =',
+ '0x00000001,0x00000001,0x00000002,0x00000003,0x00000005'])
+
+ self.expect("frame variable other.intarr",
+ substrs = ['intarr = arr =',
+ '0x00000009,0x00000008,0x00000007,0x00000006,0x00000005'])
+
+# printing each array item as an array
+ self.runCmd("type summary add --summary-string \"arr = ${var[]%uint32_t[]}\" \"int [5]\"")
+
+ self.expect("frame variable intarr",
+ substrs = ['intarr = arr =',
+ '{0x00000001},{0x00000001},{0x00000002},{0x00000003},{0x00000005}'])
+
+ self.expect("frame variable other.intarr",
+ substrs = ['intarr = arr = ',
+ '{0x00000009},{0x00000008},{0x00000007},{0x00000006},{0x00000005}'])
+
+# printing full array as an array
+ self.runCmd("type summary add --summary-string \"arr = ${var%uint32_t[]}\" \"int [5]\"")
+
+ self.expect("frame variable intarr",
+ substrs = ['intarr = arr =',
+ '0x00000001,0x00000001,0x00000002,0x00000003,0x00000005'])
+
+ self.expect("frame variable other.intarr",
+ substrs = ['intarr = arr =',
+ '0x00000009,0x00000008,0x00000007,0x00000006,0x00000005'])
+
+# printing each array item as an array
+ self.runCmd("type summary add --summary-string \"arr = ${var[]%float32[]}\" \"float [7]\"")
+
+ self.expect("frame variable flarr",
+ substrs = ['flarr = arr =',
+ '{78.5},{77.25},{78},{76.125},{76.75},{76.875},{77}'])
+
+ self.expect("frame variable other.flarr",
+ substrs = ['flarr = arr = ',
+ '{25.5},{25.25},{25.125},{26.75},{27.375},{27.5},{26.125}'])
+
+# printing full array as an array
+ self.runCmd("type summary add --summary-string \"arr = ${var%float32[]}\" \"float [7]\"")
+
+ self.expect("frame variable flarr",
+ substrs = ['flarr = arr =',
+ '78.5,77.25,78,76.125,76.75,76.875,77'])
+
+ self.expect("frame variable other.flarr",
+ substrs = ['flarr = arr =',
+ '25.5,25.25,25.125,26.75,27.375,27.5,26.125'])
+
+# using array smart summary strings for pointers should make no sense
+ self.runCmd("type summary add --summary-string \"arr = ${var%float32[]}\" \"float *\"")
+ self.runCmd("type summary add --summary-string \"arr = ${var%int32_t[]}\" \"int *\"")
+
+ self.expect("frame variable flptr", matching=False,
+ substrs = ['78.5,77.25,78,76.125,76.75,76.875,77'])
+
+ self.expect("frame variable intptr", matching=False,
+ substrs = ['1,1,2,3,5'])
+
+# use y and Y
+ self.runCmd("type summary add --summary-string \"arr = ${var%y}\" \"float [7]\"")
+ self.runCmd("type summary add --summary-string \"arr = ${var%y}\" \"int [5]\"")
+
+ self.expect("frame variable flarr",
+ substrs = ['flarr = arr =',
+ '00 00 9d 42,00 80 9a 42,00 00 9c 42,00 40 98 42,00 80 99 42,00 c0 99 42,00 00 9a 42'])
+
+ self.expect("frame variable other.flarr",
+ substrs = ['flarr = arr =',
+ '00 00 cc 41,00 00 ca 41,00 00 c9 41,00 00 d6 41,00 00 db 41,00 00 dc 41,00 00 d1 41'])
+
+ self.expect("frame variable intarr",
+ substrs = ['intarr = arr =',
+ '01 00 00 00,01 00 00 00,02 00 00 00,03 00 00 00,05 00 00 00'])
+
+ self.expect("frame variable other.intarr",
+ substrs = ['intarr = arr = ',
+ '09 00 00 00,08 00 00 00,07 00 00 00,06 00 00 00,05 00 00 00'])
+
+ self.runCmd("type summary add --summary-string \"arr = ${var%Y}\" \"float [7]\"")
+ self.runCmd("type summary add --summary-string \"arr = ${var%Y}\" \"int [5]\"")
+
+ self.expect("frame variable flarr",
+ substrs = ['flarr = arr =',
+ '00 00 9d 42 ...B,00 80 9a 42 ...B,00 00 9c 42 ...B,00 40 98 42 .@.B,00 80 99 42 ...B,00 c0 99 42 ...B,00 00 9a 42 ...B'])
+
+ self.expect("frame variable other.flarr",
+ substrs = ['flarr = arr =',
+ '00 00 cc 41 ...A,00 00 ca 41 ...A,00 00 c9 41 ...A,00 00 d6 41 ...A,00 00 db 41 ...A,00 00 dc 41 ...A,00 00 d1 41 ...A'])
+
+ self.expect("frame variable intarr",
+ substrs = ['intarr = arr =',
+ '....,01 00 00 00',
+ '....,05 00 00 00'])
+
+ self.expect("frame variable other.intarr",
+ substrs = ['intarr = arr = ',
+ '09 00 00 00',
+ '....,07 00 00 00'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-smart-array/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-smart-array/main.cpp
new file mode 100644
index 000000000000..9279e414be31
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-smart-array/main.cpp
@@ -0,0 +1,65 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+struct SomeData
+{
+ int x;
+};
+
+struct SomeOtherData
+{
+ char strarr[32];
+ char *strptr;
+ int intarr[5];
+ float flarr[7];
+
+ SomeOtherData()
+ {
+ strcpy(strarr,"Nested Hello world!");
+ strptr = new char[128];
+ strcpy(strptr,"Nested Hello world!");
+ intarr[0] = 9;
+ intarr[1] = 8;
+ intarr[2] = 7;
+ intarr[3] = 6;
+ intarr[4] = 5;
+
+ flarr[0] = 25.5;
+ flarr[1] = 25.25;
+ flarr[2] = 25.125;
+ flarr[3] = 26.75;
+ flarr[4] = 27.375;
+ flarr[5] = 27.5;
+ flarr[6] = 26.125;
+ }
+};
+
+int main (int argc, const char * argv[])
+{
+ char strarr[32] = "Hello world!";
+ char *strptr = NULL;
+ strptr = "Hello world!";
+ int intarr[5] = {1,1,2,3,5};
+ float flarr[7] = {78.5,77.25,78.0,76.125,76.75,76.875,77.0};
+
+ SomeData data;
+
+ SomeOtherData other;
+
+ float* flptr = flarr;
+ int* intptr = intarr;
+
+ return 0; // Set break point at this line.
+
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/Makefile
new file mode 100644
index 000000000000..d37bef7dc5cc
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/Makefile
@@ -0,0 +1,4 @@
+LEVEL = ../../../../../make
+CXX_SOURCES := main.cpp
+CXXFLAGS += -std=c++11
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/TestInitializerList.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/TestInitializerList.py
new file mode 100644
index 000000000000..e01f1b6679fc
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/TestInitializerList.py
@@ -0,0 +1,40 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class InitializerListTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipIfWindows # libc++ not ported to Windows yet
+ @skipIfGcc
+ @expectedFailureLinux # fails on clang 3.5 and tot
+ def test(self):
+ """Test that that file and class static variables display correctly."""
+ self.build()
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ bkpt = self.target().FindBreakpointByID(lldbutil.run_break_set_by_source_regexp (self, "Set break point at this line."))
+
+ 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'])
+
+ self.expect("frame variable ili", substrs = ['[1] = 2','[4] = 5'])
+ self.expect("frame variable ils", substrs = ['[4] = "surprise it is a long string!! yay!!"'])
+
+ self.expect('image list', substrs = self.getLibcPlusPlusLibs())
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/main.cpp
new file mode 100644
index 000000000000..9109a20cb510
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/main.cpp
@@ -0,0 +1,21 @@
+//===-- main.cpp --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <string>
+#include <vector>
+#include <initializer_list>
+
+int main ()
+{
+ std::initializer_list<int> ili{1,2,3,4,5};
+ std::initializer_list<std::string> ils{"1","2","3","4","surprise it is a long string!! yay!!"};
+
+ return 0; // Set break point at this line.
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/Makefile
new file mode 100644
index 000000000000..1f609a41d908
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/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/iterator/TestDataFormatterLibccIterator.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/TestDataFormatterLibccIterator.py
new file mode 100644
index 000000000000..a87a2ed2d434
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/TestDataFormatterLibccIterator.py
@@ -0,0 +1,66 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class LibcxxIteratorDataFormatterTestCase(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.')
+
+ @skipIfGcc
+ @skipIfWindows # libc++ not ported to Windows yet
+ def test_with_run_command(self):
+ """Test that libc++ iterators format properly."""
+ 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)
+
+ 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.expect('image list', substrs = self.getLibcPlusPlusLibs())
+
+ self.expect('frame variable ivI', substrs = ['item = 3'])
+ self.expect('expr ivI', substrs = ['item = 3'])
+
+ self.expect('frame variable iimI', substrs = ['first = 0','second = 12'])
+ self.expect('expr iimI', substrs = ['first = 0','second = 12'])
+
+ self.expect('frame variable simI', substrs = ['first = "world"','second = 42'])
+ self.expect('expr simI', substrs = ['first = "world"','second = 42'])
+
+ self.expect('frame variable svI', substrs = ['item = "hello"'])
+ self.expect('expr svI', substrs = ['item = "hello"'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/main.cpp
new file mode 100644
index 000000000000..97b37851f53d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/main.cpp
@@ -0,0 +1,42 @@
+#include <string>
+#ifdef _LIBCPP_INLINE_VISIBILITY
+#undef _LIBCPP_INLINE_VISIBILITY
+#endif
+#define _LIBCPP_INLINE_VISIBILITY
+#include <map>
+#include <vector>
+
+typedef std::map<int, int> intint_map;
+typedef std::map<std::string, int> strint_map;
+
+typedef std::vector<int> int_vector;
+typedef std::vector<std::string> string_vector;
+
+typedef intint_map::iterator iimter;
+typedef strint_map::iterator simter;
+
+typedef int_vector::iterator ivter;
+typedef string_vector::iterator svter;
+
+int main()
+{
+ intint_map iim;
+ iim[0] = 12;
+
+ strint_map sim;
+ sim["world"] = 42;
+
+ int_vector iv;
+ iv.push_back(3);
+
+ string_vector sv;
+ sv.push_back("hello");
+
+ iimter iimI = iim.begin();
+ simter simI = sim.begin();
+
+ ivter ivI = iv.begin();
+ svter svI = sv.begin();
+
+ return 0; // Set break point at this line.
+} \ No newline at end of file
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;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/Makefile
new file mode 100644
index 000000000000..1f609a41d908
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/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/map/TestDataFormatterLibccMap.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py
new file mode 100644
index 000000000000..70a98f9c2cae
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py
@@ -0,0 +1,298 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class LibcxxMapDataFormatterTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @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)
+
+ bkpt = self.target().FindBreakpointByID(lldbutil.run_break_set_by_source_regexp (self, "Set break point at this line."))
+
+ 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.expect('image list', substrs = self.getLibcPlusPlusLibs())
+
+ self.expect('frame variable ii',
+ substrs = ['size=0',
+ '{}'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect('frame variable ii',
+ substrs = ['size=2',
+ '[0] = ',
+ 'first = 0',
+ 'second = 0',
+ '[1] = ',
+ 'first = 1',
+ 'second = 1'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect('frame variable ii',
+ substrs = ['size=4',
+ '[2] = ',
+ 'first = 2',
+ 'second = 0',
+ '[3] = ',
+ 'first = 3',
+ 'second = 1'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect("frame variable ii",
+ substrs = ['size=8',
+ '[5] = ',
+ 'first = 5',
+ 'second = 0',
+ '[7] = ',
+ 'first = 7',
+ 'second = 1'])
+
+ self.expect("p ii",
+ substrs = ['size=8',
+ '[5] = ',
+ 'first = 5',
+ 'second = 0',
+ '[7] = ',
+ 'first = 7',
+ 'second = 1'])
+
+ # check access-by-index
+ self.expect("frame variable ii[0]",
+ substrs = ['first = 0',
+ 'second = 0']);
+ self.expect("frame variable ii[3]",
+ substrs = ['first =',
+ 'second =']);
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(self.frame().FindVariable("ii").MightHaveChildren(), "ii.MightHaveChildren() says False for non empty!")
+
+ # check that the expression parser does not make use of
+ # synthetic children instead of running code
+ # TOT clang has a fix for this, which makes the expression command here succeed
+ # since this would make the test fail or succeed depending on clang version in use
+ # this is safer commented for the time being
+ #self.expect("expression ii[8]", matching=False, error=True,
+ # substrs = ['1234567'])
+
+ self.runCmd("continue");
+
+ self.expect('frame variable ii',
+ substrs = ['size=0',
+ '{}'])
+
+ self.expect('frame variable si',
+ substrs = ['size=0',
+ '{}'])
+
+ self.runCmd("continue");
+
+ self.expect('frame variable si',
+ substrs = ['size=1',
+ '[0] = ',
+ 'first = \"zero\"',
+ 'second = 0'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect("frame variable si",
+ substrs = ['size=4',
+ '[0] = ',
+ 'first = \"zero\"',
+ 'second = 0',
+ '[1] = ',
+ 'first = \"one\"',
+ 'second = 1',
+ '[2] = ',
+ 'first = \"two\"',
+ 'second = 2',
+ '[3] = ',
+ 'first = \"three\"',
+ 'second = 3'])
+
+ self.expect("p si",
+ substrs = ['size=4',
+ '[0] = ',
+ 'first = \"zero\"',
+ 'second = 0',
+ '[1] = ',
+ 'first = \"one\"',
+ 'second = 1',
+ '[2] = ',
+ 'first = \"two\"',
+ 'second = 2',
+ '[3] = ',
+ 'first = \"three\"',
+ 'second = 3'])
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(self.frame().FindVariable("si").MightHaveChildren(), "si.MightHaveChildren() says False for non empty!")
+
+ # check access-by-index
+ self.expect("frame variable si[0]",
+ substrs = ['first = ', 'one',
+ 'second = 1']);
+
+ # check that the expression parser does not make use of
+ # synthetic children instead of running code
+ # TOT clang has a fix for this, which makes the expression command here succeed
+ # since this would make the test fail or succeed depending on clang version in use
+ # this is safer commented for the time being
+ #self.expect("expression si[0]", matching=False, error=True,
+ # substrs = ['first = ', 'zero'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect('frame variable si',
+ substrs = ['size=0',
+ '{}'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect('frame variable is',
+ substrs = ['size=0',
+ '{}'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect("frame variable is",
+ substrs = ['size=4',
+ '[0] = ',
+ 'second = \"goofy\"',
+ 'first = 85',
+ '[1] = ',
+ 'second = \"is\"',
+ 'first = 1',
+ '[2] = ',
+ 'second = \"smart\"',
+ 'first = 2',
+ '[3] = ',
+ 'second = \"!!!\"',
+ 'first = 3'])
+
+ self.expect("p is",
+ substrs = ['size=4',
+ '[0] = ',
+ 'second = \"goofy\"',
+ 'first = 85',
+ '[1] = ',
+ 'second = \"is\"',
+ 'first = 1',
+ '[2] = ',
+ 'second = \"smart\"',
+ 'first = 2',
+ '[3] = ',
+ 'second = \"!!!\"',
+ 'first = 3'])
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(self.frame().FindVariable("is").MightHaveChildren(), "is.MightHaveChildren() says False for non empty!")
+
+ # check access-by-index
+ self.expect("frame variable is[0]",
+ substrs = ['first = ',
+ 'second =']);
+
+ # check that the expression parser does not make use of
+ # synthetic children instead of running code
+ # TOT clang has a fix for this, which makes the expression command here succeed
+ # since this would make the test fail or succeed depending on clang version in use
+ # this is safer commented for the time being
+ #self.expect("expression is[0]", matching=False, error=True,
+ # substrs = ['first = ', 'goofy'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect('frame variable is',
+ substrs = ['size=0',
+ '{}'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect('frame variable ss',
+ substrs = ['size=0',
+ '{}'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect("frame variable ss",
+ substrs = ['size=3',
+ '[0] = ',
+ 'second = \"hello\"',
+ 'first = \"ciao\"',
+ '[1] = ',
+ 'second = \"house\"',
+ 'first = \"casa\"',
+ '[2] = ',
+ 'second = \"cat\"',
+ 'first = \"gatto\"'])
+
+ self.expect("p ss",
+ substrs = ['size=3',
+ '[0] = ',
+ 'second = \"hello\"',
+ 'first = \"ciao\"',
+ '[1] = ',
+ 'second = \"house\"',
+ 'first = \"casa\"',
+ '[2] = ',
+ 'second = \"cat\"',
+ 'first = \"gatto\"'])
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(self.frame().FindVariable("ss").MightHaveChildren(), "ss.MightHaveChildren() says False for non empty!")
+
+ # check access-by-index
+ self.expect("frame variable ss[2]",
+ substrs = ['gatto', 'cat']);
+
+ # check that the expression parser does not make use of
+ # synthetic children instead of running code
+ # TOT clang has a fix for this, which makes the expression command here succeed
+ # since this would make the test fail or succeed depending on clang version in use
+ # this is safer commented for the time being
+ #self.expect("expression ss[3]", matching=False, error=True,
+ # substrs = ['gatto'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect('frame variable ss',
+ substrs = ['size=0',
+ '{}'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/main.cpp
new file mode 100644
index 000000000000..6247ca8b2412
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/main.cpp
@@ -0,0 +1,77 @@
+#include <string>
+#include <map>
+
+#define intint_map std::map<int, int>
+#define strint_map std::map<std::string, int>
+#define intstr_map std::map<int, std::string>
+#define strstr_map std::map<std::string, std::string>
+
+int g_the_foo = 0;
+
+int thefoo_rw(int arg = 1)
+{
+ if (arg < 0)
+ arg = 0;
+ if (!arg)
+ arg = 1;
+ g_the_foo += arg;
+ return g_the_foo;
+}
+
+int main()
+{
+ intint_map ii;
+
+ ii[0] = 0; // Set break point at this line.
+ ii[1] = 1;
+ thefoo_rw(1); // Set break point at this line.
+ ii[2] = 0;
+ ii[3] = 1;
+ thefoo_rw(1); // Set break point at this line.
+ ii[4] = 0;
+ ii[5] = 1;
+ ii[6] = 0;
+ ii[7] = 1;
+ thefoo_rw(1); // Set break point at this line.
+ ii[85] = 1234567;
+
+ ii.clear();
+
+ strint_map si;
+ thefoo_rw(1); // Set break point at this line.
+
+ si["zero"] = 0;
+ thefoo_rw(1); // Set break point at this line.
+ si["one"] = 1;
+ si["two"] = 2;
+ si["three"] = 3;
+ thefoo_rw(1); // Set break point at this line.
+ si["four"] = 4;
+
+ si.clear();
+ thefoo_rw(1); // Set break point at this line.
+
+ intstr_map is;
+ thefoo_rw(1); // Set break point at this line.
+ is[85] = "goofy";
+ is[1] = "is";
+ is[2] = "smart";
+ is[3] = "!!!";
+ thefoo_rw(1); // Set break point at this line.
+
+ is.clear();
+ thefoo_rw(1); // Set break point at this line.
+
+ strstr_map ss;
+ thefoo_rw(1); // Set break point at this line.
+
+ ss["ciao"] = "hello";
+ ss["casa"] = "house";
+ ss["gatto"] = "cat";
+ thefoo_rw(1); // Set break point at this line.
+ ss["a Mac.."] = "..is always a Mac!";
+
+ ss.clear();
+ thefoo_rw(1); // Set break point at this line.
+ return 0;
+} \ No newline at end of file
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/Makefile
new file mode 100644
index 000000000000..1f609a41d908
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/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/multimap/TestDataFormatterLibccMultiMap.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/TestDataFormatterLibccMultiMap.py
new file mode 100644
index 000000000000..d0ca73d3251d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/TestDataFormatterLibccMultiMap.py
@@ -0,0 +1,298 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class LibcxxMultiMapDataFormatterTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipIfWindows # libc++ not ported to Windows yet
+ @skipIfGcc
+ 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)
+
+ bkpt = self.target().FindBreakpointByID(lldbutil.run_break_set_by_source_regexp (self, "Set break point at this line."))
+
+ 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.expect('image list', substrs = self.getLibcPlusPlusLibs())
+
+ self.expect('frame variable ii',
+ substrs = ['size=0',
+ '{}'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect('frame variable ii',
+ substrs = ['size=2',
+ '[0] = ',
+ 'first = 0',
+ 'second = 0',
+ '[1] = ',
+ 'first = 1',
+ 'second = 1'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect('frame variable ii',
+ substrs = ['size=4',
+ '[2] = ',
+ 'first = 2',
+ 'second = 0',
+ '[3] = ',
+ 'first = 3',
+ 'second = 1'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect("frame variable ii",
+ substrs = ['size=8',
+ '[5] = ',
+ 'first = 5',
+ 'second = 0',
+ '[7] = ',
+ 'first = 7',
+ 'second = 1'])
+
+ self.expect("p ii",
+ substrs = ['size=8',
+ '[5] = ',
+ 'first = 5',
+ 'second = 0',
+ '[7] = ',
+ 'first = 7',
+ 'second = 1'])
+
+ # check access-by-index
+ self.expect("frame variable ii[0]",
+ substrs = ['first = 0',
+ 'second = 0']);
+ self.expect("frame variable ii[3]",
+ substrs = ['first =',
+ 'second =']);
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(self.frame().FindVariable("ii").MightHaveChildren(), "ii.MightHaveChildren() says False for non empty!")
+
+ # check that the expression parser does not make use of
+ # synthetic children instead of running code
+ # TOT clang has a fix for this, which makes the expression command here succeed
+ # since this would make the test fail or succeed depending on clang version in use
+ # this is safer commented for the time being
+ #self.expect("expression ii[8]", matching=False, error=True,
+ # substrs = ['1234567'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect('frame variable ii',
+ substrs = ['size=0',
+ '{}'])
+
+ self.expect('frame variable si',
+ substrs = ['size=0',
+ '{}'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect('frame variable si',
+ substrs = ['size=1',
+ '[0] = ',
+ 'first = \"zero\"',
+ 'second = 0'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect("frame variable si",
+ substrs = ['size=4',
+ '[0] = ',
+ 'first = \"zero\"',
+ 'second = 0',
+ '[1] = ',
+ 'first = \"one\"',
+ 'second = 1',
+ '[2] = ',
+ 'first = \"two\"',
+ 'second = 2',
+ '[3] = ',
+ 'first = \"three\"',
+ 'second = 3'])
+
+ self.expect("p si",
+ substrs = ['size=4',
+ '[0] = ',
+ 'first = \"zero\"',
+ 'second = 0',
+ '[1] = ',
+ 'first = \"one\"',
+ 'second = 1',
+ '[2] = ',
+ 'first = \"two\"',
+ 'second = 2',
+ '[3] = ',
+ 'first = \"three\"',
+ 'second = 3'])
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(self.frame().FindVariable("si").MightHaveChildren(), "si.MightHaveChildren() says False for non empty!")
+
+ # check access-by-index
+ self.expect("frame variable si[0]",
+ substrs = ['first = ', 'one',
+ 'second = 1']);
+
+ # check that the expression parser does not make use of
+ # synthetic children instead of running code
+ # TOT clang has a fix for this, which makes the expression command here succeed
+ # since this would make the test fail or succeed depending on clang version in use
+ # this is safer commented for the time being
+ #self.expect("expression si[0]", matching=False, error=True,
+ # substrs = ['first = ', 'zero'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect('frame variable si',
+ substrs = ['size=0',
+ '{}'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect('frame variable is',
+ substrs = ['size=0',
+ '{}'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect("frame variable is",
+ substrs = ['size=4',
+ '[0] = ',
+ 'second = \"goofy\"',
+ 'first = 85',
+ '[1] = ',
+ 'second = \"is\"',
+ 'first = 1',
+ '[2] = ',
+ 'second = \"smart\"',
+ 'first = 2',
+ '[3] = ',
+ 'second = \"!!!\"',
+ 'first = 3'])
+
+ self.expect("p is",
+ substrs = ['size=4',
+ '[0] = ',
+ 'second = \"goofy\"',
+ 'first = 85',
+ '[1] = ',
+ 'second = \"is\"',
+ 'first = 1',
+ '[2] = ',
+ 'second = \"smart\"',
+ 'first = 2',
+ '[3] = ',
+ 'second = \"!!!\"',
+ 'first = 3'])
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(self.frame().FindVariable("is").MightHaveChildren(), "is.MightHaveChildren() says False for non empty!")
+
+ # check access-by-index
+ self.expect("frame variable is[0]",
+ substrs = ['first = ',
+ 'second =']);
+
+ # check that the expression parser does not make use of
+ # synthetic children instead of running code
+ # TOT clang has a fix for this, which makes the expression command here succeed
+ # since this would make the test fail or succeed depending on clang version in use
+ # this is safer commented for the time being
+ #self.expect("expression is[0]", matching=False, error=True,
+ # substrs = ['first = ', 'goofy'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect('frame variable is',
+ substrs = ['size=0',
+ '{}'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect('frame variable ss',
+ substrs = ['size=0',
+ '{}'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect("frame variable ss",
+ substrs = ['size=3',
+ '[0] = ',
+ 'second = \"hello\"',
+ 'first = \"ciao\"',
+ '[1] = ',
+ 'second = \"house\"',
+ 'first = \"casa\"',
+ '[2] = ',
+ 'second = \"cat\"',
+ 'first = \"gatto\"'])
+
+ self.expect("p ss",
+ substrs = ['size=3',
+ '[0] = ',
+ 'second = \"hello\"',
+ 'first = \"ciao\"',
+ '[1] = ',
+ 'second = \"house\"',
+ 'first = \"casa\"',
+ '[2] = ',
+ 'second = \"cat\"',
+ 'first = \"gatto\"'])
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(self.frame().FindVariable("ss").MightHaveChildren(), "ss.MightHaveChildren() says False for non empty!")
+
+ # check access-by-index
+ self.expect("frame variable ss[2]",
+ substrs = ['gatto', 'cat']);
+
+ # check that the expression parser does not make use of
+ # synthetic children instead of running code
+ # TOT clang has a fix for this, which makes the expression command here succeed
+ # since this would make the test fail or succeed depending on clang version in use
+ # this is safer commented for the time being
+ #self.expect("expression ss[3]", matching=False, error=True,
+ # substrs = ['gatto'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect('frame variable ss',
+ substrs = ['size=0',
+ '{}'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/main.cpp
new file mode 100644
index 000000000000..e8385994125d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/main.cpp
@@ -0,0 +1,77 @@
+#include <string>
+#include <map>
+
+#define intint_map std::multimap<int, int>
+#define strint_map std::multimap<std::string, int>
+#define intstr_map std::multimap<int, std::string>
+#define strstr_map std::multimap<std::string, std::string>
+
+int g_the_foo = 0;
+
+int thefoo_rw(int arg = 1)
+{
+ if (arg < 0)
+ arg = 0;
+ if (!arg)
+ arg = 1;
+ g_the_foo += arg;
+ return g_the_foo;
+}
+
+int main()
+{
+ intint_map ii;
+
+ ii.emplace(0,0); // Set break point at this line.
+ ii.emplace(1,1);
+ thefoo_rw(1); // Set break point at this line.
+ ii.emplace(2,0);
+ ii.emplace(3,1);
+ thefoo_rw(1); // Set break point at this line.
+ ii.emplace(4,0);
+ ii.emplace(5,1);
+ ii.emplace(6,0);
+ ii.emplace(7,1);
+ thefoo_rw(1); // Set break point at this line.
+ ii.emplace(85,1234567);
+
+ ii.clear();
+
+ strint_map si;
+ thefoo_rw(1); // Set break point at this line.
+
+ si.emplace("zero",0);
+ thefoo_rw(1); // Set break point at this line.
+ si.emplace("one",1);
+ si.emplace("two",2);
+ si.emplace("three",3);
+ thefoo_rw(1); // Set break point at this line.
+ si.emplace("four",4);
+
+ si.clear();
+ thefoo_rw(1); // Set break point at this line.
+
+ intstr_map is;
+ thefoo_rw(1); // Set break point at this line.
+ is.emplace(85,"goofy");
+ is.emplace(1,"is");
+ is.emplace(2,"smart");
+ is.emplace(3,"!!!");
+ thefoo_rw(1); // Set break point at this line.
+
+ is.clear();
+ thefoo_rw(1); // Set break point at this line.
+
+ strstr_map ss;
+ thefoo_rw(1); // Set break point at this line.
+
+ ss.emplace("ciao","hello");
+ ss.emplace("casa","house");
+ ss.emplace("gatto","cat");
+ thefoo_rw(1); // Set break point at this line.
+ ss.emplace("a Mac..","..is always a Mac!");
+
+ ss.clear();
+ thefoo_rw(1); // Set break point at this line.
+ return 0;
+} \ No newline at end of file
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/Makefile
new file mode 100644
index 000000000000..1f609a41d908
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/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/multiset/TestDataFormatterLibcxxMultiSet.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/TestDataFormatterLibcxxMultiSet.py
new file mode 100644
index 000000000000..384f6130d0c0
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/TestDataFormatterLibcxxMultiSet.py
@@ -0,0 +1,69 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class LibcxxMultiSetDataFormatterTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @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)
+
+ bkpt = self.target().FindBreakpointByID(lldbutil.run_break_set_by_source_regexp (self, "Set break point at this line."))
+
+ 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.expect('image list', substrs = self.getLibcPlusPlusLibs())
+
+ self.expect("frame variable ii",substrs = ["size=0","{}"])
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+ self.expect("frame variable ii",substrs = ["size=6","[0] = 0","[1] = 1", "[2] = 2", "[3] = 3", "[4] = 4", "[5] = 5"])
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+ self.expect("frame variable ii",substrs = ["size=7","[2] = 2", "[3] = 3", "[6] = 6"])
+ self.expect("p ii",substrs = ["size=7","[2] = 2", "[3] = 3", "[6] = 6"])
+ self.expect("frame variable ii[2]",substrs = [" = 2"])
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+ self.expect("frame variable ii",substrs = ["size=0","{}"])
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+ self.expect("frame variable ii",substrs = ["size=0","{}"])
+ self.expect("frame variable ss",substrs = ["size=0","{}"])
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+ self.expect("frame variable ss",substrs = ["size=2",'[0] = "a"','[1] = "a very long string is right here"'])
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+ self.expect("frame variable ss",substrs = ["size=4",'[2] = "b"','[3] = "c"','[0] = "a"','[1] = "a very long string is right here"'])
+ self.expect("p ss",substrs = ["size=4",'[2] = "b"','[3] = "c"','[0] = "a"','[1] = "a very long string is right here"'])
+ self.expect("frame variable ss[2]",substrs = [' = "b"'])
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+ self.expect("frame variable ss",substrs = ["size=3",'[0] = "a"','[1] = "a very long string is right here"','[2] = "c"'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/main.cpp
new file mode 100644
index 000000000000..1e1dd3b16039
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/main.cpp
@@ -0,0 +1,57 @@
+#include <string>
+#ifdef _LIBCPP_INLINE_VISIBILITY
+#undef _LIBCPP_INLINE_VISIBILITY
+#endif
+#define _LIBCPP_INLINE_VISIBILITY
+#include <set>
+
+typedef std::multiset<int> intset;
+typedef std::multiset<std::string> stringset;
+
+int g_the_foo = 0;
+
+int thefoo_rw(int arg = 1)
+{
+ if (arg < 0)
+ arg = 0;
+ if (!arg)
+ arg = 1;
+ g_the_foo += arg;
+ return g_the_foo;
+}
+
+int main()
+{
+ intset ii;
+ thefoo_rw(1); // Set break point at this line.
+
+ ii.insert(0);
+ ii.insert(1);
+ ii.insert(2);
+ ii.insert(3);
+ ii.insert(4);
+ ii.insert(5);
+ thefoo_rw(1); // Set break point at this line.
+
+ ii.insert(6);
+ thefoo_rw(1); // Set break point at this line.
+
+ ii.clear();
+ thefoo_rw(1); // Set break point at this line.
+
+ stringset ss;
+ thefoo_rw(1); // Set break point at this line.
+
+ ss.insert("a");
+ ss.insert("a very long string is right here");
+ thefoo_rw(1); // Set break point at this line.
+
+ ss.insert("b");
+ ss.insert("c");
+ thefoo_rw(1); // Set break point at this line.
+
+ ss.erase("b");
+ thefoo_rw(1); // Set break point at this line.
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/Makefile
new file mode 100644
index 000000000000..1f609a41d908
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/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/set/TestDataFormatterLibcxxSet.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/TestDataFormatterLibcxxSet.py
new file mode 100644
index 000000000000..fcbfb0a8f0ed
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/TestDataFormatterLibcxxSet.py
@@ -0,0 +1,69 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class LibcxxSetDataFormatterTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @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)
+
+ bkpt = self.target().FindBreakpointByID(lldbutil.run_break_set_by_source_regexp (self, "Set break point at this line."))
+
+ 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.expect('image list', substrs = self.getLibcPlusPlusLibs())
+
+ self.expect("frame variable ii",substrs = ["size=0","{}"])
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+ self.expect("frame variable ii",substrs = ["size=6","[0] = 0","[1] = 1", "[2] = 2", "[3] = 3", "[4] = 4", "[5] = 5"])
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+ self.expect("frame variable ii",substrs = ["size=7","[2] = 2", "[3] = 3", "[6] = 6"])
+ self.expect("frame variable ii[2]",substrs = [" = 2"])
+ self.expect("p ii",substrs = ["size=7","[2] = 2", "[3] = 3", "[6] = 6"])
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+ self.expect("frame variable ii",substrs = ["size=0","{}"])
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+ self.expect("frame variable ii",substrs = ["size=0","{}"])
+ self.expect("frame variable ss",substrs = ["size=0","{}"])
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+ self.expect("frame variable ss",substrs = ["size=2",'[0] = "a"','[1] = "a very long string is right here"'])
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+ self.expect("frame variable ss",substrs = ["size=4",'[2] = "b"','[3] = "c"','[0] = "a"','[1] = "a very long string is right here"'])
+ self.expect("p ss",substrs = ["size=4",'[2] = "b"','[3] = "c"','[0] = "a"','[1] = "a very long string is right here"'])
+ self.expect("frame variable ss[2]",substrs = [' = "b"'])
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+ self.expect("frame variable ss",substrs = ["size=3",'[0] = "a"','[1] = "a very long string is right here"','[2] = "c"'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/main.cpp
new file mode 100644
index 000000000000..cc3033ef26e4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/main.cpp
@@ -0,0 +1,57 @@
+#include <string>
+#ifdef _LIBCPP_INLINE_VISIBILITY
+#undef _LIBCPP_INLINE_VISIBILITY
+#endif
+#define _LIBCPP_INLINE_VISIBILITY
+#include <set>
+
+typedef std::set<int> intset;
+typedef std::set<std::string> stringset;
+
+int g_the_foo = 0;
+
+int thefoo_rw(int arg = 1)
+{
+ if (arg < 0)
+ arg = 0;
+ if (!arg)
+ arg = 1;
+ g_the_foo += arg;
+ return g_the_foo;
+}
+
+int main()
+{
+ intset ii;
+ thefoo_rw(1); // Set break point at this line.
+
+ ii.insert(0);
+ ii.insert(1);
+ ii.insert(2);
+ ii.insert(3);
+ ii.insert(4);
+ ii.insert(5);
+ thefoo_rw(1); // Set break point at this line.
+
+ ii.insert(6);
+ thefoo_rw(1); // Set break point at this line.
+
+ ii.clear();
+ thefoo_rw(1); // Set break point at this line.
+
+ stringset ss;
+ thefoo_rw(1); // Set break point at this line.
+
+ ss.insert("a");
+ ss.insert("a very long string is right here");
+ thefoo_rw(1); // Set break point at this line.
+
+ ss.insert("b");
+ ss.insert("c");
+ thefoo_rw(1); // Set break point at this line.
+
+ ss.erase("b");
+ thefoo_rw(1); // Set break point at this line.
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/Makefile
new file mode 100644
index 000000000000..1f609a41d908
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/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/string/TestDataFormatterLibcxxString.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py
new file mode 100644
index 000000000000..942124255f55
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py
@@ -0,0 +1,86 @@
+#coding=utf8
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class LibcxxStringDataFormatterTestCase(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.')
+
+ @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)
+
+ 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.expect("frame variable",
+ substrs = ['(std::__1::wstring) s = L"hello world! מזל טוב!"',
+ '(std::__1::wstring) S = L"!!!!"',
+ '(const wchar_t *) mazeltov = 0x','L"מזל טוב"',
+ '(std::__1::string) q = "hello world"',
+ '(std::__1::string) Q = "quite a long std::strin with lots of info inside it"',
+ '(std::__1::string) IHaveEmbeddedZeros = "a\\0b\\0c\\0d"',
+ '(std::__1::wstring) IHaveEmbeddedZerosToo = L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"'])
+
+ self.runCmd("n")
+
+ TheVeryLongOne = self.frame().FindVariable("TheVeryLongOne");
+ summaryOptions = lldb.SBTypeSummaryOptions()
+ summaryOptions.SetCapping(lldb.eTypeSummaryUncapped)
+ uncappedSummaryStream = lldb.SBStream()
+ TheVeryLongOne.GetSummary(uncappedSummaryStream,summaryOptions)
+ uncappedSummary = uncappedSummaryStream.GetData()
+ self.assertTrue(uncappedSummary.find("someText") > 0, "uncappedSummary does not include the full string")
+ summaryOptions.SetCapping(lldb.eTypeSummaryCapped)
+ cappedSummaryStream = lldb.SBStream()
+ TheVeryLongOne.GetSummary(cappedSummaryStream,summaryOptions)
+ cappedSummary = cappedSummaryStream.GetData()
+ self.assertTrue(cappedSummary.find("someText") <= 0, "cappedSummary includes the full string")
+
+ self.expect("frame variable",
+ substrs = ['(std::__1::wstring) s = L"hello world! מזל טוב!"',
+ '(std::__1::wstring) S = L"!!!!!"',
+ '(const wchar_t *) mazeltov = 0x','L"מזל טוב"',
+ '(std::__1::string) q = "hello world"',
+ '(std::__1::string) Q = "quite a long std::strin with lots of info inside it"',
+ '(std::__1::string) IHaveEmbeddedZeros = "a\\0b\\0c\\0d"',
+ '(std::__1::wstring) IHaveEmbeddedZerosToo = L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/main.cpp
new file mode 100644
index 000000000000..9ca0da39cfc8
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/main.cpp
@@ -0,0 +1,15 @@
+#include <string>
+
+int main()
+{
+ std::wstring s(L"hello world! מזל טוב!");
+ std::wstring S(L"!!!!");
+ const wchar_t *mazeltov = L"מזל טוב";
+ std::string q("hello world");
+ std::string Q("quite a long std::strin with lots of info inside it");
+ std::string TheVeryLongOne("1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890someText1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890");
+ std::string IHaveEmbeddedZeros("a\0b\0c\0d",7);
+ std::wstring IHaveEmbeddedZerosToo(L"hello world!\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監", 38);
+ S.assign(L"!!!!!"); // Set break point at this line.
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/Makefile
new file mode 100644
index 000000000000..1f609a41d908
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/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/unordered/TestDataFormatterUnordered.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/TestDataFormatterUnordered.py
new file mode 100644
index 000000000000..5e6ec2519323
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/TestDataFormatterUnordered.py
@@ -0,0 +1,75 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class LibcxxUnorderedDataFormatterTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipIfWindows # libc++ not ported to Windows yet
+ @skipIfGcc
+ 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_source_regexp (self, "Set break point at this line.")
+
+ 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.expect('image list', substrs = self.getLibcPlusPlusLibs())
+
+ self.look_for_content_and_continue(
+ "map", ['size=5 {', 'hello', 'world', 'this', 'is', 'me'])
+
+ self.look_for_content_and_continue(
+ "mmap", ['size=6 {', 'first = 3', 'second = "this"',
+ 'first = 2', 'second = "hello"'])
+
+ self.look_for_content_and_continue(
+ "iset", ['size=5 {', '\[\d\] = 5', '\[\d\] = 3', '\[\d\] = 2'])
+
+ self.look_for_content_and_continue(
+ "sset", ['size=5 {', '\[\d\] = "is"', '\[\d\] = "world"',
+ '\[\d\] = "hello"'])
+
+ self.look_for_content_and_continue(
+ "imset", ['size=6 {', '(\[\d\] = 3(\\n|.)+){3}',
+ '\[\d\] = 2', '\[\d\] = 1'])
+
+ self.look_for_content_and_continue(
+ "smset",
+ ['size=5 {', '(\[\d\] = "is"(\\n|.)+){2}',
+ '(\[\d\] = "world"(\\n|.)+){2}'])
+
+ def look_for_content_and_continue(self, var_name, patterns):
+ self.expect( ("frame variable %s" % var_name), patterns=patterns)
+ self.runCmd("continue")
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/main.cpp
new file mode 100644
index 000000000000..4e8a1a779c0c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/main.cpp
@@ -0,0 +1,84 @@
+#include <string>
+#ifdef _LIBCPP_INLINE_VISIBILITY
+#undef _LIBCPP_INLINE_VISIBILITY
+#endif
+#define _LIBCPP_INLINE_VISIBILITY
+#include <unordered_map>
+#include <unordered_set>
+
+using std::string;
+
+#define intstr_map std::unordered_map<int, string>
+#define intstr_mmap std::unordered_multimap<int, string>
+
+#define int_set std::unordered_set<int>
+#define str_set std::unordered_set<string>
+#define int_mset std::unordered_multiset<int>
+#define str_mset std::unordered_multiset<string>
+
+int g_the_foo = 0;
+
+int thefoo_rw(int arg = 1)
+{
+ if (arg < 0)
+ arg = 0;
+ if (!arg)
+ arg = 1;
+ g_the_foo += arg;
+ return g_the_foo;
+}
+
+int main()
+{
+ intstr_map map;
+ map.emplace(1,"hello");
+ map.emplace(2,"world");
+ map.emplace(3,"this");
+ map.emplace(4,"is");
+ map.emplace(5,"me");
+ thefoo_rw(); // Set break point at this line.
+
+ intstr_mmap mmap;
+ mmap.emplace(1,"hello");
+ mmap.emplace(2,"hello");
+ mmap.emplace(2,"world");
+ mmap.emplace(3,"this");
+ mmap.emplace(3,"this");
+ mmap.emplace(3,"this");
+ thefoo_rw(); // Set break point at this line.
+
+ int_set iset;
+ iset.emplace(1);
+ iset.emplace(2);
+ iset.emplace(3);
+ iset.emplace(4);
+ iset.emplace(5);
+ thefoo_rw(); // Set break point at this line.
+
+ str_set sset;
+ sset.emplace("hello");
+ sset.emplace("world");
+ sset.emplace("this");
+ sset.emplace("is");
+ sset.emplace("me");
+ thefoo_rw(); // Set break point at this line.
+
+ int_mset imset;
+ imset.emplace(1);
+ imset.emplace(2);
+ imset.emplace(2);
+ imset.emplace(3);
+ imset.emplace(3);
+ imset.emplace(3);
+ thefoo_rw(); // Set break point at this line.
+
+ str_mset smset;
+ smset.emplace("hello");
+ smset.emplace("world");
+ smset.emplace("world");
+ smset.emplace("is");
+ smset.emplace("is");
+ thefoo_rw(); // Set break point at this line.
+
+ return 0;
+} \ No newline at end of file
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/Makefile
new file mode 100644
index 000000000000..637fa7e80bfd
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/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/vbool/TestDataFormatterLibcxxVBool.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/TestDataFormatterLibcxxVBool.py
new file mode 100644
index 000000000000..9771a819aa6b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/TestDataFormatterLibcxxVBool.py
@@ -0,0 +1,58 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class LibcxxVBoolDataFormatterTestCase(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.')
+
+ @skipIfGcc
+ @skipIfWindows # libc++ not ported to Windows.
+ 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.skip_if_library_missing(self, self.target(), lldbutil.PrintableRegex("libc\+\+"))
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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.expect("frame variable vBool",
+ substrs = ['size=49','[0] = false','[1] = true','[18] = false','[27] = true','[36] = false','[47] = true','[48] = true'])
+
+ self.expect("expr vBool",
+ substrs = ['size=49','[0] = false','[1] = true','[18] = false','[27] = true','[36] = false','[47] = true','[48] = true'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/main.cpp
new file mode 100644
index 000000000000..7b9956ed36ea
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/main.cpp
@@ -0,0 +1,69 @@
+#include <string>
+#ifdef _LIBCPP_INLINE_VISIBILITY
+#undef _LIBCPP_INLINE_VISIBILITY
+#endif
+#define _LIBCPP_INLINE_VISIBILITY
+
+#include <vector>
+
+int main()
+{
+ std::vector<bool> vBool;
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(true);
+
+ return 0; // Set break point at this line.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/Makefile
new file mode 100644
index 000000000000..1f609a41d908
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/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/vector/TestDataFormatterLibcxxVector.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py
new file mode 100644
index 000000000000..f8cd65be0931
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py
@@ -0,0 +1,180 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class LibcxxVectorDataFormatterTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @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.skip_if_library_missing(self, self.target(), lldbutil.PrintableRegex("libc\+\+"))
+
+ bkpt = self.target().FindBreakpointByID(lldbutil.run_break_set_by_source_regexp (self, "break here"))
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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)
+
+ # empty vectors (and storage pointers SHOULD BOTH BE NULL..)
+ self.expect("frame variable numbers",
+ substrs = ['numbers = size=0'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ # first value added
+ self.expect("frame variable numbers",
+ substrs = ['numbers = size=1',
+ '[0] = 1',
+ '}'])
+
+ # add some more data
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect("frame variable numbers",
+ substrs = ['numbers = size=4',
+ '[0] = 1',
+ '[1] = 12',
+ '[2] = 123',
+ '[3] = 1234',
+ '}'])
+
+ self.expect("p numbers",
+ substrs = ['$', 'size=4',
+ '[0] = 1',
+ '[1] = 12',
+ '[2] = 123',
+ '[3] = 1234',
+ '}'])
+
+
+ # check access to synthetic children
+ self.runCmd("type summary add --summary-string \"item 0 is ${var[0]}\" std::int_vect int_vect")
+ self.expect('frame variable numbers',
+ substrs = ['item 0 is 1']);
+
+ self.runCmd("type summary add --summary-string \"item 0 is ${svar[0]}\" std::int_vect int_vect")
+ self.expect('frame variable numbers',
+ substrs = ['item 0 is 1']);
+ # move on with synths
+ self.runCmd("type summary delete std::int_vect")
+ self.runCmd("type summary delete int_vect")
+
+ # add some more data
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect("frame variable numbers",
+ substrs = ['numbers = size=7',
+ '[0] = 1',
+ '[1] = 12',
+ '[2] = 123',
+ '[3] = 1234',
+ '[4] = 12345',
+ '[5] = 123456',
+ '[6] = 1234567',
+ '}'])
+
+ self.expect("p numbers",
+ substrs = ['$', 'size=7',
+ '[0] = 1',
+ '[1] = 12',
+ '[2] = 123',
+ '[3] = 1234',
+ '[4] = 12345',
+ '[5] = 123456',
+ '[6] = 1234567',
+ '}'])
+
+ # check access-by-index
+ self.expect("frame variable numbers[0]",
+ substrs = ['1']);
+ self.expect("frame variable numbers[1]",
+ substrs = ['12']);
+ self.expect("frame variable numbers[2]",
+ substrs = ['123']);
+ self.expect("frame variable numbers[3]",
+ substrs = ['1234']);
+
+ # clear out the vector and see that we do the right thing once again
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect("frame variable numbers",
+ substrs = ['numbers = size=0'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ # first value added
+ self.expect("frame variable numbers",
+ substrs = ['numbers = size=1',
+ '[0] = 7',
+ '}'])
+
+ # check if we can display strings
+ self.expect("frame variable strings",
+ substrs = ['goofy',
+ 'is',
+ 'smart'])
+
+ self.expect("p strings",
+ substrs = ['goofy',
+ 'is',
+ 'smart'])
+
+ # test summaries based on synthetic children
+ self.runCmd("type summary add std::string_vect string_vect --summary-string \"vector has ${svar%#} items\" -e")
+ self.expect("frame variable strings",
+ substrs = ['vector has 3 items',
+ 'goofy',
+ 'is',
+ 'smart'])
+
+ self.expect("p strings",
+ substrs = ['vector has 3 items',
+ 'goofy',
+ 'is',
+ 'smart'])
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect("frame variable strings",
+ substrs = ['vector has 4 items'])
+
+ # check access-by-index
+ self.expect("frame variable strings[0]",
+ substrs = ['goofy']);
+ self.expect("frame variable strings[1]",
+ substrs = ['is']);
+
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+
+ self.expect("frame variable strings",
+ substrs = ['vector has 0 items'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/main.cpp
new file mode 100644
index 000000000000..a9aeacf90e43
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/main.cpp
@@ -0,0 +1,35 @@
+#include <string>
+#ifdef _LIBCPP_INLINE_VISIBILITY
+#undef _LIBCPP_INLINE_VISIBILITY
+#endif
+#define _LIBCPP_INLINE_VISIBILITY
+#include <vector>
+typedef std::vector<int> int_vect;
+typedef std::vector<std::string> string_vect;
+
+int main()
+{
+ int_vect numbers;
+ (numbers.push_back(1)); // break here
+ (numbers.push_back(12)); // break here
+ (numbers.push_back(123));
+ (numbers.push_back(1234));
+ (numbers.push_back(12345)); // break here
+ (numbers.push_back(123456));
+ (numbers.push_back(1234567));
+
+ numbers.clear(); // break here
+
+ (numbers.push_back(7)); // break here
+
+ string_vect strings;
+ (strings.push_back(std::string("goofy")));
+ (strings.push_back(std::string("is")));
+ (strings.push_back(std::string("smart")));
+
+ (strings.push_back(std::string("!!!"))); // break here
+
+ strings.clear(); // break here
+
+ return 0; // break here
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/Makefile
new file mode 100644
index 000000000000..7fe01d004f03
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/Makefile
@@ -0,0 +1,15 @@
+LEVEL = ../../../../../make
+
+CXX_SOURCES := main.cpp
+
+CFLAGS_EXTRAS += -O0
+USE_LIBSTDCPP := 1
+
+# clang-3.5+ outputs FullDebugInfo by default for Darwin/FreeBSD
+# targets. Other targets do not, which causes this test to fail.
+# This flag enables FullDebugInfo for all targets.
+ifneq (,$(findstring clang,$(CC)))
+ CFLAGS_EXTRAS += -fno-limit-debug-info
+endif
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/TestDataFormatterStdIterator.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/TestDataFormatterStdIterator.py
new file mode 100644
index 000000000000..6742c9e71701
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/TestDataFormatterStdIterator.py
@@ -0,0 +1,62 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class StdIteratorDataFormatterTestCase(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.')
+
+ @skipIfWindows # libstdcpp not ported to Windows
+ @expectedFailureIcc # llvm.org/pr15301 LLDB prints incorrect sizes of STL containers
+ def test_with_run_command(self):
+ """Test that libstdcpp iterators format properly."""
+ 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)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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.expect('frame variable ivI', substrs = ['item = 3'])
+ self.expect('expr ivI', substrs = ['item = 3'])
+
+ self.expect('frame variable iimI', substrs = ['first = 0','second = 12'])
+ self.expect('expr iimI', substrs = ['first = 0','second = 12'])
+
+ self.expect('frame variable simI', substrs = ['first = "world"','second = 42'])
+ self.expect('expr simI', substrs = ['first = "world"','second = 42'])
+
+ self.expect('frame variable svI', substrs = ['item = "hello"'])
+ self.expect('expr svI', substrs = ['item = "hello"'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/main.cpp
new file mode 100644
index 000000000000..d7b046c5bff8
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/main.cpp
@@ -0,0 +1,38 @@
+#include <string>
+#include <map>
+#include <vector>
+
+typedef std::map<int, int> intint_map;
+typedef std::map<std::string, int> strint_map;
+
+typedef std::vector<int> int_vector;
+typedef std::vector<std::string> string_vector;
+
+typedef intint_map::iterator iimter;
+typedef strint_map::iterator simter;
+
+typedef int_vector::iterator ivter;
+typedef string_vector::iterator svter;
+
+int main()
+{
+ intint_map iim;
+ iim[0] = 12;
+
+ strint_map sim;
+ sim["world"] = 42;
+
+ int_vector iv;
+ iv.push_back(3);
+
+ string_vector sv;
+ sv.push_back("hello");
+
+ iimter iimI = iim.begin();
+ simter simI = sim.begin();
+
+ ivter ivI = iv.begin();
+ svter svI = sv.begin();
+
+ return 0; // Set break point at this line.
+} \ No newline at end of file
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/Makefile
new file mode 100644
index 000000000000..7fe01d004f03
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/Makefile
@@ -0,0 +1,15 @@
+LEVEL = ../../../../../make
+
+CXX_SOURCES := main.cpp
+
+CFLAGS_EXTRAS += -O0
+USE_LIBSTDCPP := 1
+
+# clang-3.5+ outputs FullDebugInfo by default for Darwin/FreeBSD
+# targets. Other targets do not, which causes this test to fail.
+# This flag enables FullDebugInfo for all targets.
+ifneq (,$(findstring clang,$(CC)))
+ CFLAGS_EXTRAS += -fno-limit-debug-info
+endif
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py
new file mode 100644
index 000000000000..5147d18da0fe
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py
@@ -0,0 +1,188 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class StdListDataFormatterTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line numbers to break at for the different tests.
+ self.line = line_number('main.cpp', '// Set break point at this line.')
+ self.optional_line = line_number('main.cpp', '// Optional break point at this line.')
+ self.final_line = line_number('main.cpp', '// Set final break point at this line.')
+
+ @skipIfWindows # libstdcpp not ported to Windows
+ 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)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 format add -f hex int")
+
+ self.expect("frame variable numbers_list --raw", matching=False,
+ substrs = ['size=0',
+ '{}'])
+ self.expect("frame variable &numbers_list._M_impl._M_node --raw", matching=False,
+ substrs = ['size=0',
+ '{}'])
+
+ self.expect("frame variable numbers_list",
+ substrs = ['size=0',
+ '{}'])
+
+ self.expect("p numbers_list",
+ substrs = ['size=0',
+ '{}'])
+
+ self.runCmd("n")
+
+ self.expect("frame variable numbers_list",
+ substrs = ['size=1',
+ '[0] = ',
+ '0x12345678'])
+
+ self.runCmd("n");self.runCmd("n");self.runCmd("n");
+
+ self.expect("frame variable numbers_list",
+ substrs = ['size=4',
+ '[0] = ',
+ '0x12345678',
+ '[1] =',
+ '0x11223344',
+ '[2] =',
+ '0xbeeffeed',
+ '[3] =',
+ '0x00abba00'])
+
+ self.runCmd("n");self.runCmd("n");
+
+ self.expect("frame variable numbers_list",
+ substrs = ['size=6',
+ '[0] = ',
+ '0x12345678',
+ '0x11223344',
+ '0xbeeffeed',
+ '0x00abba00',
+ '[4] =',
+ '0x0abcdef0',
+ '[5] =',
+ '0x0cab0cab'])
+
+ self.expect("p numbers_list",
+ substrs = ['size=6',
+ '[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']);
+
+ # but check that expression does not rely on us
+ self.expect("expression numbers_list[0]", matching=False, error=True,
+ substrs = ['0x12345678'])
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(self.frame().FindVariable("numbers_list").MightHaveChildren(), "numbers_list.MightHaveChildren() says False for non empty!")
+
+ self.runCmd("n")
+
+ self.expect("frame variable numbers_list",
+ substrs = ['size=0',
+ '{}'])
+
+ self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");
+
+ self.expect("frame variable numbers_list",
+ substrs = ['size=4',
+ '[0] = ', '1',
+ '[1] = ', '2',
+ '[2] = ', '3',
+ '[3] = ', '4'])
+
+ self.runCmd("type format delete int")
+
+ self.runCmd("n")
+
+ self.expect("frame variable text_list",
+ substrs = ['size=0',
+ '{}'])
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.final_line, num_expected_locations=-1)
+
+ self.runCmd("c", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ self.expect("frame variable text_list",
+ substrs = ['size=4',
+ '[0]', 'goofy',
+ '[1]', 'is',
+ '[2]', 'smart',
+ '[3]', '!!!'])
+
+ self.expect("p text_list",
+ substrs = ['size=4',
+ '\"goofy\"',
+ '\"is\"',
+ '\"smart\"',
+ '\"!!!\"'])
+
+ # check access-by-index
+ self.expect("frame variable text_list[0]",
+ substrs = ['goofy']);
+ self.expect("frame variable text_list[3]",
+ substrs = ['!!!']);
+
+ # but check that expression does not rely on us
+ self.expect("expression text_list[0]", matching=False, error=True,
+ substrs = ['goofy'])
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(self.frame().FindVariable("text_list").MightHaveChildren(), "text_list.MightHaveChildren() says False for non empty!")
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/main.cpp
new file mode 100644
index 000000000000..191acdcc97be
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/main.cpp
@@ -0,0 +1,34 @@
+#include <list>
+#include <string>
+
+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")); // Optional break point at this line.
+ text_list.push_back(std::string("is"));
+ text_list.push_back(std::string("smart"));
+
+ text_list.push_back(std::string("!!!"));
+
+ return 0; // Set final break point at this line.
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/Makefile
new file mode 100644
index 000000000000..2c6c3cf72842
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/Makefile
@@ -0,0 +1,14 @@
+LEVEL = ../../../../../make
+
+CXX_SOURCES := main.cpp
+
+USE_LIBSTDCPP := 1
+
+# clang-3.5+ outputs FullDebugInfo by default for Darwin/FreeBSD
+# targets. Other targets do not, which causes this test to fail.
+# This flag enables FullDebugInfo for all targets.
+ifneq (,$(findstring clang,$(CC)))
+ CFLAGS_EXTRAS += -fno-limit-debug-info
+endif
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py
new file mode 100644
index 000000000000..e21c4e94c2c4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py
@@ -0,0 +1,322 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class StdMapDataFormatterTestCase(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.')
+
+ @expectedFailureIcc # llvm.org/pr15301: LLDB prints incorrect size of libstdc++ containers
+ @skipIfWindows # libstdcpp not ported to Windows
+ @skipIfFreeBSD
+ 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_source_regexp (self, "Set break point at this line.")
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 ii --show-types")
+
+ self.runCmd("type summary add -x \"std::map<\" --summary-string \"map has ${svar%#} items\" -e")
+
+ self.expect('frame variable ii',
+ substrs = ['map has 0 items',
+ '{}'])
+
+ self.runCmd("c");
+
+ self.expect('frame variable ii',
+ substrs = ['map has 2 items',
+ '[0] = ',
+ 'first = 0',
+ 'second = 0',
+ '[1] = ',
+ 'first = 1',
+ 'second = 1'])
+
+ self.runCmd("c");
+
+ self.expect('frame variable ii',
+ substrs = ['map has 4 items',
+ '[2] = ',
+ 'first = 2',
+ 'second = 0',
+ '[3] = ',
+ 'first = 3',
+ 'second = 1'])
+
+ self.runCmd("c");
+
+ self.expect("frame variable ii",
+ substrs = ['map has 9 items',
+ '[5] = ',
+ 'first = 5',
+ 'second = 0',
+ '[7] = ',
+ 'first = 7',
+ 'second = 1'])
+
+ self.expect("p ii",
+ substrs = ['map has 9 items',
+ '[5] = ',
+ 'first = 5',
+ 'second = 0',
+ '[7] = ',
+ 'first = 7',
+ 'second = 1'])
+
+ # check access-by-index
+ self.expect("frame variable ii[0]",
+ substrs = ['first = 0',
+ 'second = 0']);
+ self.expect("frame variable ii[3]",
+ substrs = ['first =',
+ 'second =']);
+
+ self.expect("frame variable ii[8]", matching=True,
+ substrs = ['1234567'])
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(self.frame().FindVariable("ii").MightHaveChildren(), "ii.MightHaveChildren() says False for non empty!")
+
+ # check that the expression parser does not make use of
+ # synthetic children instead of running code
+ # TOT clang has a fix for this, which makes the expression command here succeed
+ # since this would make the test fail or succeed depending on clang version in use
+ # this is safer commented for the time being
+ #self.expect("expression ii[8]", matching=False, error=True,
+ # substrs = ['1234567'])
+
+ self.runCmd("c")
+
+ self.expect('frame variable ii',
+ substrs = ['map has 0 items',
+ '{}'])
+
+ self.runCmd("frame variable si --show-types")
+
+ self.expect('frame variable si',
+ substrs = ['map has 0 items',
+ '{}'])
+
+ self.runCmd("c")
+
+ self.expect('frame variable si',
+ substrs = ['map has 1 items',
+ '[0] = ',
+ 'first = \"zero\"',
+ 'second = 0'])
+
+ self.runCmd("c");
+
+ self.expect("frame variable si",
+ substrs = ['map has 5 items',
+ '[0] = ',
+ 'first = \"zero\"',
+ 'second = 0',
+ '[1] = ',
+ 'first = \"one\"',
+ 'second = 1',
+ '[2] = ',
+ 'first = \"two\"',
+ 'second = 2',
+ '[3] = ',
+ 'first = \"three\"',
+ 'second = 3',
+ '[4] = ',
+ 'first = \"four\"',
+ 'second = 4'])
+
+ self.expect("p si",
+ substrs = ['map has 5 items',
+ '[0] = ',
+ 'first = \"zero\"',
+ 'second = 0',
+ '[1] = ',
+ 'first = \"one\"',
+ 'second = 1',
+ '[2] = ',
+ 'first = \"two\"',
+ 'second = 2',
+ '[3] = ',
+ 'first = \"three\"',
+ 'second = 3',
+ '[4] = ',
+ 'first = \"four\"',
+ 'second = 4'])
+
+ # check access-by-index
+ self.expect("frame variable si[0]",
+ substrs = ['first = ', 'four',
+ 'second = 4']);
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(self.frame().FindVariable("si").MightHaveChildren(), "si.MightHaveChildren() says False for non empty!")
+
+ # check that the expression parser does not make use of
+ # synthetic children instead of running code
+ # TOT clang has a fix for this, which makes the expression command here succeed
+ # since this would make the test fail or succeed depending on clang version in use
+ # this is safer commented for the time being
+ #self.expect("expression si[0]", matching=False, error=True,
+ # substrs = ['first = ', 'zero'])
+
+ self.runCmd("c")
+
+ self.expect('frame variable si',
+ substrs = ['map has 0 items',
+ '{}'])
+
+ self.runCmd("frame variable is --show-types")
+
+ self.expect('frame variable is',
+ substrs = ['map has 0 items',
+ '{}'])
+
+ self.runCmd("c");
+
+ self.expect("frame variable is",
+ substrs = ['map has 4 items',
+ '[0] = ',
+ 'second = \"goofy\"',
+ 'first = 85',
+ '[1] = ',
+ 'second = \"is\"',
+ 'first = 1',
+ '[2] = ',
+ 'second = \"smart\"',
+ 'first = 2',
+ '[3] = ',
+ 'second = \"!!!\"',
+ 'first = 3'])
+
+ self.expect("p is",
+ substrs = ['map has 4 items',
+ '[0] = ',
+ 'second = \"goofy\"',
+ 'first = 85',
+ '[1] = ',
+ 'second = \"is\"',
+ 'first = 1',
+ '[2] = ',
+ 'second = \"smart\"',
+ 'first = 2',
+ '[3] = ',
+ 'second = \"!!!\"',
+ 'first = 3'])
+
+ # check access-by-index
+ self.expect("frame variable is[0]",
+ substrs = ['first = ',
+ 'second =']);
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(self.frame().FindVariable("is").MightHaveChildren(), "is.MightHaveChildren() says False for non empty!")
+
+ # check that the expression parser does not make use of
+ # synthetic children instead of running code
+ # TOT clang has a fix for this, which makes the expression command here succeed
+ # since this would make the test fail or succeed depending on clang version in use
+ # this is safer commented for the time being
+ #self.expect("expression is[0]", matching=False, error=True,
+ # substrs = ['first = ', 'goofy'])
+
+ self.runCmd("c")
+
+ self.expect('frame variable is',
+ substrs = ['map has 0 items',
+ '{}'])
+
+ self.runCmd("frame variable ss --show-types")
+
+ self.expect('frame variable ss',
+ substrs = ['map has 0 items',
+ '{}'])
+
+ self.runCmd("c");
+
+ self.expect("frame variable ss",
+ substrs = ['map has 4 items',
+ '[0] = ',
+ 'second = \"hello\"',
+ 'first = \"ciao\"',
+ '[1] = ',
+ 'second = \"house\"',
+ 'first = \"casa\"',
+ '[2] = ',
+ 'second = \"cat\"',
+ 'first = \"gatto\"',
+ '[3] = ',
+ 'second = \"..is always a Mac!\"',
+ 'first = \"a Mac..\"'])
+
+ self.expect("p ss",
+ substrs = ['map has 4 items',
+ '[0] = ',
+ 'second = \"hello\"',
+ 'first = \"ciao\"',
+ '[1] = ',
+ 'second = \"house\"',
+ 'first = \"casa\"',
+ '[2] = ',
+ 'second = \"cat\"',
+ 'first = \"gatto\"',
+ '[3] = ',
+ 'second = \"..is always a Mac!\"',
+ 'first = \"a Mac..\"'])
+
+ # check access-by-index
+ self.expect("frame variable ss[3]",
+ substrs = ['gatto', 'cat']);
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(self.frame().FindVariable("ss").MightHaveChildren(), "ss.MightHaveChildren() says False for non empty!")
+
+ # check that the expression parser does not make use of
+ # synthetic children instead of running code
+ # TOT clang has a fix for this, which makes the expression command here succeed
+ # since this would make the test fail or succeed depending on clang version in use
+ # this is safer commented for the time being
+ #self.expect("expression ss[3]", matching=False, error=True,
+ # substrs = ['gatto'])
+
+ self.runCmd("c")
+
+ self.expect('frame variable ss',
+ substrs = ['map has 0 items',
+ '{}'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/main.cpp
new file mode 100644
index 000000000000..568c35efe072
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/main.cpp
@@ -0,0 +1,55 @@
+#include <map>
+#include <string>
+
+#define intint_map std::map<int, int>
+#define strint_map std::map<std::string, int>
+#define intstr_map std::map<int, std::string>
+#define strstr_map std::map<std::string, std::string>
+
+
+int main()
+{
+ intint_map ii;
+
+ ii[0] = 0; // Set break point at this line.
+ ii[1] = 1;
+ ii[2] = 0;// Set break point at this line.
+ ii[3] = 1;
+ ii[4] = 0;// Set break point at this line.
+ ii[5] = 1;
+ ii[6] = 0;
+ ii[7] = 1;
+ ii[85] = 1234567;
+
+ ii.clear();// Set break point at this line.
+
+ strint_map si;
+
+ si["zero"] = 0;// Set break point at this line.
+ si["one"] = 1;// Set break point at this line.
+ si["two"] = 2;
+ si["three"] = 3;
+ si["four"] = 4;
+
+ si.clear();// Set break point at this line.
+
+ intstr_map is;
+
+ is[85] = "goofy";// Set break point at this line.
+ is[1] = "is";
+ is[2] = "smart";
+ is[3] = "!!!";
+
+ is.clear();// Set break point at this line.
+
+ strstr_map ss;
+
+ ss["ciao"] = "hello";// Set break point at this line.
+ ss["casa"] = "house";
+ ss["gatto"] = "cat";
+ ss["a Mac.."] = "..is always a Mac!";
+
+ ss.clear();// Set break point at this line.
+
+ return 0;// Set break point at this line.
+} \ No newline at end of file
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/Makefile
new file mode 100644
index 000000000000..7fe01d004f03
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/Makefile
@@ -0,0 +1,15 @@
+LEVEL = ../../../../../make
+
+CXX_SOURCES := main.cpp
+
+CFLAGS_EXTRAS += -O0
+USE_LIBSTDCPP := 1
+
+# clang-3.5+ outputs FullDebugInfo by default for Darwin/FreeBSD
+# targets. Other targets do not, which causes this test to fail.
+# This flag enables FullDebugInfo for all targets.
+ifneq (,$(findstring clang,$(CC)))
+ CFLAGS_EXTRAS += -fno-limit-debug-info
+endif
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/TestDataFormatterStdString.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/TestDataFormatterStdString.py
new file mode 100644
index 000000000000..2d6af24c6afc
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/TestDataFormatterStdString.py
@@ -0,0 +1,66 @@
+#coding=utf8
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class StdStringDataFormatterTestCase(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.')
+
+ @skipIfWindows # libstdcpp not ported to Windows
+ 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)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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)
+
+ var_s = self.frame().FindVariable('s')
+ var_S = self.frame().FindVariable('S')
+ var_mazeltov = self.frame().FindVariable('mazeltov')
+ var_q = self.frame().FindVariable('q')
+ var_Q = self.frame().FindVariable('Q')
+
+ self.assertTrue(var_s.GetSummary() == 'L"hello world! מזל טוב!"', "s summary wrong")
+ self.assertTrue(var_S.GetSummary() == 'L"!!!!"', "S summary wrong")
+ self.assertTrue(var_mazeltov.GetSummary() == 'L"מזל טוב"', "mazeltov summary wrong")
+ self.assertTrue(var_q.GetSummary() == '"hello world"', "q summary wrong")
+ self.assertTrue(var_Q.GetSummary() == '"quite a long std::strin with lots of info inside it"', "Q summary wrong")
+
+ self.runCmd("next")
+
+ self.assertTrue(var_S.GetSummary() == 'L"!!!!!"', "new S summary wrong")
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/main.cpp
new file mode 100644
index 000000000000..4a9b4fc7d0db
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/main.cpp
@@ -0,0 +1,12 @@
+#include <string>
+
+int main()
+{
+ std::wstring s(L"hello world! מזל טוב!");
+ std::wstring S(L"!!!!");
+ const wchar_t *mazeltov = L"מזל טוב";
+ std::string q("hello world");
+ std::string Q("quite a long std::strin with lots of info inside it");
+ S.assign(L"!!!!!"); // Set break point at this line.
+ return 0;
+} \ No newline at end of file
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile
new file mode 100644
index 000000000000..2e8bcb9079bd
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile
@@ -0,0 +1,8 @@
+LEVEL = ../../../../../make
+
+CXX_SOURCES := main.cpp
+
+CFLAGS_EXTRAS += -O0
+USE_LIBSTDCPP := 1
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py
new file mode 100644
index 000000000000..9e73009aba83
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py
@@ -0,0 +1,58 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class StdVBoolDataFormatterTestCase(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.')
+
+ @expectedFailureFreeBSD("llvm.org/pr20548") # fails to build on lab.llvm.org buildbot
+ @expectedFailureIcc # llvm.org/pr15301: lldb does not print the correct sizes of STL containers when building with ICC
+ @skipIfWindows # libstdcpp not ported to Windows.
+ @skipIfDarwin
+ 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)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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.expect("frame variable vBool",
+ substrs = ['size=49','[0] = false','[1] = true','[18] = false','[27] = true','[36] = false','[47] = true','[48] = true'])
+
+ self.expect("expr vBool",
+ substrs = ['size=49','[0] = false','[1] = true','[18] = false','[27] = true','[36] = false','[47] = true','[48] = true'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/main.cpp
new file mode 100644
index 000000000000..73956dd3fda3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/main.cpp
@@ -0,0 +1,63 @@
+#include <vector>
+
+int main()
+{
+ std::vector<bool> vBool;
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(true);
+
+ return 0; // Set break point at this line.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/Makefile
new file mode 100644
index 000000000000..88cb026aba1c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/Makefile
@@ -0,0 +1,15 @@
+LEVEL = ../../../../../make
+
+CXX_SOURCES := main.cpp
+
+CXXFLAGS := -O0
+USE_LIBSTDCPP := 1
+
+# clang-3.5+ outputs FullDebugInfo by default for Darwin/FreeBSD
+# targets. Other targets do not, which causes this test to fail.
+# This flag enables FullDebugInfo for all targets.
+ifneq (,$(findstring clang,$(CC)))
+ CFLAGS_EXTRAS += -fno-limit-debug-info
+endif
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py
new file mode 100644
index 000000000000..ed4313657e93
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py
@@ -0,0 +1,207 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class StdVectorDataFormatterTestCase(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.')
+
+ @skipIfFreeBSD
+ @expectedFailureIcc # llvm.org/pr15301 LLDB prints incorrect sizes of STL containers
+ @skipIfWindows # libstdcpp not ported to Windows
+ 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_source_regexp (self, "Set break point at this line.")
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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)
+
+ # empty vectors (and storage pointers SHOULD BOTH BE NULL..)
+ self.expect("frame variable numbers",
+ substrs = ['numbers = size=0'])
+
+ self.runCmd("c")
+
+ # first value added
+ self.expect("frame variable numbers",
+ substrs = ['numbers = size=1',
+ '[0] = 1',
+ '}'])
+
+ # add some more data
+ self.runCmd("c");
+
+ self.expect("frame variable numbers",
+ substrs = ['numbers = size=4',
+ '[0] = 1',
+ '[1] = 12',
+ '[2] = 123',
+ '[3] = 1234',
+ '}'])
+
+ self.expect("p numbers",
+ substrs = ['$', 'size=4',
+ '[0] = 1',
+ '[1] = 12',
+ '[2] = 123',
+ '[3] = 1234',
+ '}'])
+
+
+ # check access to synthetic children
+ self.runCmd("type summary add --summary-string \"item 0 is ${var[0]}\" std::int_vect int_vect")
+ self.expect('frame variable numbers',
+ substrs = ['item 0 is 1']);
+
+ self.runCmd("type summary add --summary-string \"item 0 is ${svar[0]}\" std::int_vect int_vect")
+ #import time
+ #time.sleep(19)
+ self.expect('frame variable numbers',
+ substrs = ['item 0 is 1']);
+ # move on with synths
+ self.runCmd("type summary delete std::int_vect")
+ self.runCmd("type summary delete int_vect")
+
+ # add some more data
+ self.runCmd("c");
+
+ self.expect("frame variable numbers",
+ substrs = ['numbers = size=7',
+ '[0] = 1',
+ '[1] = 12',
+ '[2] = 123',
+ '[3] = 1234',
+ '[4] = 12345',
+ '[5] = 123456',
+ '[6] = 1234567',
+ '}'])
+
+ self.expect("p numbers",
+ substrs = ['$', 'size=7',
+ '[0] = 1',
+ '[1] = 12',
+ '[2] = 123',
+ '[3] = 1234',
+ '[4] = 12345',
+ '[5] = 123456',
+ '[6] = 1234567',
+ '}'])
+
+ # check access-by-index
+ self.expect("frame variable numbers[0]",
+ substrs = ['1']);
+ self.expect("frame variable numbers[1]",
+ substrs = ['12']);
+ self.expect("frame variable numbers[2]",
+ substrs = ['123']);
+ self.expect("frame variable numbers[3]",
+ substrs = ['1234']);
+
+ # but check that expression does not rely on us
+ # (when expression gets to call into STL code correctly, we will have to find
+ # another way to check this)
+ self.expect("expression numbers[6]", matching=False, error=True,
+ substrs = ['1234567'])
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(self.frame().FindVariable("numbers").MightHaveChildren(), "numbers.MightHaveChildren() says False for non empty!")
+
+ # clear out the vector and see that we do the right thing once again
+ self.runCmd("c")
+
+ self.expect("frame variable numbers",
+ substrs = ['numbers = size=0'])
+
+ self.runCmd("c")
+
+ # first value added
+ self.expect("frame variable numbers",
+ substrs = ['numbers = size=1',
+ '[0] = 7',
+ '}'])
+
+ # check if we can display strings
+ self.runCmd("c")
+
+ self.expect("frame variable strings",
+ substrs = ['goofy',
+ 'is',
+ 'smart'])
+
+ self.expect("p strings",
+ substrs = ['goofy',
+ 'is',
+ 'smart'])
+
+ # test summaries based on synthetic children
+ self.runCmd("type summary add std::string_vect string_vect --summary-string \"vector has ${svar%#} items\" -e")
+ self.expect("frame variable strings",
+ substrs = ['vector has 3 items',
+ 'goofy',
+ 'is',
+ 'smart'])
+
+ self.expect("p strings",
+ substrs = ['vector has 3 items',
+ 'goofy',
+ 'is',
+ 'smart'])
+
+ self.runCmd("c");
+
+ self.expect("frame variable strings",
+ substrs = ['vector has 4 items'])
+
+ # check access-by-index
+ self.expect("frame variable strings[0]",
+ substrs = ['goofy']);
+ self.expect("frame variable strings[1]",
+ substrs = ['is']);
+
+ # but check that expression does not rely on us
+ # (when expression gets to call into STL code correctly, we will have to find
+ # another way to check this)
+ self.expect("expression strings[0]", matching=False, error=True,
+ substrs = ['goofy'])
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(self.frame().FindVariable("strings").MightHaveChildren(), "strings.MightHaveChildren() says False for non empty!")
+
+ self.runCmd("c")
+
+ self.expect("frame variable strings",
+ substrs = ['vector has 0 items'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/main.cpp
new file mode 100644
index 000000000000..010917995e40
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/main.cpp
@@ -0,0 +1,31 @@
+#include <string>
+#include <vector>
+typedef std::vector<int> int_vect;
+typedef std::vector<std::string> string_vect;
+
+int main()
+{
+ int_vect numbers;
+ numbers.push_back(1); // Set break point at this line.
+ numbers.push_back(12); // Set break point at this line.
+ numbers.push_back(123);
+ numbers.push_back(1234);
+ numbers.push_back(12345); // Set break point at this line.
+ numbers.push_back(123456);
+ numbers.push_back(1234567);
+
+ numbers.clear(); // Set break point at this line.
+
+ numbers.push_back(7); // Set break point at this line.
+
+ string_vect strings; // Set break point at this line.
+ strings.push_back(std::string("goofy"));
+ strings.push_back(std::string("is"));
+ strings.push_back(std::string("smart"));
+
+ strings.push_back(std::string("!!!")); // Set break point at this line.
+
+ strings.clear(); // Set break point at this line.
+
+ return 0;// Set break point at this line.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synth/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synth/Makefile
new file mode 100644
index 000000000000..04f39271f0cd
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synth/Makefile
@@ -0,0 +1,12 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+# clang-3.5+ outputs FullDebugInfo by default for Darwin/FreeBSD
+# targets. Other targets do not, which causes this test to fail.
+# This flag enables FullDebugInfo for all targets.
+ifneq (,$(findstring clang,$(CC)))
+ CFLAGS_EXTRAS += -fno-limit-debug-info
+endif
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py
new file mode 100644
index 000000000000..8cebf20ddd2a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py
@@ -0,0 +1,205 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class SynthDataFormatterTestCase(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.')
+
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # Pick some values and check that the basics work
+ self.runCmd("type filter add BagOfInts --child x --child z")
+ self.expect("frame variable int_bag",
+ substrs = ['x = 6',
+ 'z = 8'])
+
+ # Check we can still access the missing child by summary
+ self.runCmd("type summary add BagOfInts --summary-string \"y=${var.y}\"")
+ self.expect('frame variable int_bag',
+ substrs = ['y=7'])
+
+ # Even if we have synth children, the summary prevails
+ self.expect("frame variable int_bag", matching=False,
+ substrs = ['x = 6',
+ 'z = 8'])
+
+ # if we skip synth and summary show y
+ self.expect("frame variable int_bag --synthetic-type false --no-summary-depth=1",
+ substrs = ['x = 6',
+ 'y = 7',
+ 'z = 8'])
+
+ # if we ask for raw output same happens
+ self.expect("frame variable int_bag --raw-output",
+ substrs = ['x = 6',
+ 'y = 7',
+ 'z = 8'])
+
+ # Summary+Synth must work together
+ self.runCmd("type summary add BagOfInts --summary-string \"x=${var.x}\" -e")
+ self.expect('frame variable int_bag',
+ substrs = ['x=6',
+ 'x = 6',
+ 'z = 8'])
+
+ # Same output, but using Python
+ self.runCmd("type summary add BagOfInts --python-script \"return 'x=%s' % valobj.GetChildMemberWithName('x').GetValue()\" -e")
+ self.expect('frame variable int_bag',
+ substrs = ['x=6',
+ 'x = 6',
+ 'z = 8'])
+
+ # If I skip summaries, still give me the artificial children
+ self.expect("frame variable int_bag --no-summary-depth=1",
+ substrs = ['x = 6',
+ 'z = 8'])
+
+ # Delete synth and check that the view reflects it immediately
+ self.runCmd("type filter delete BagOfInts")
+ self.expect("frame variable int_bag",
+ substrs = ['x = 6',
+ 'y = 7',
+ 'z = 8'])
+
+ # Add the synth again and check that it's honored deeper in the hierarchy
+ self.runCmd("type filter add BagOfInts --child x --child z")
+ self.expect('frame variable bag_bag',
+ substrs = ['x = x=69 {',
+ 'x = 69',
+ 'z = 71',
+ 'y = x=66 {',
+ 'x = 66',
+ 'z = 68'])
+ self.expect('frame variable bag_bag', matching=False,
+ substrs = ['y = 70',
+ 'y = 67'])
+
+ # Check that a synth can expand nested stuff
+ self.runCmd("type filter add BagOfBags --child x.y --child y.z")
+ self.expect('frame variable bag_bag',
+ substrs = ['x.y = 70',
+ 'y.z = 68'])
+
+ # ...even if we get -> and . wrong
+ self.runCmd("type filter add BagOfBags --child x.y --child \"y->z\"")
+ self.expect('frame variable bag_bag',
+ substrs = ['x.y = 70',
+ 'y->z = 68'])
+
+ # ...even bitfields
+ self.runCmd("type filter add BagOfBags --child x.y --child \"y->z[1-2]\"")
+ self.expect('frame variable bag_bag --show-types',
+ substrs = ['x.y = 70',
+ '(int:2) y->z[1-2] = 2'])
+
+ # ...even if we format the bitfields
+ self.runCmd("type filter add BagOfBags --child x.y --child \"y->y[0-0]\"")
+ self.runCmd("type format add \"int:1\" -f bool")
+ self.expect('frame variable bag_bag --show-types',
+ substrs = ['x.y = 70',
+ '(int:1) y->y[0-0] = true'])
+
+ # ...even if we use one-liner summaries
+ self.runCmd("type summary add -c BagOfBags")
+ self.expect('frame variable bag_bag',
+ substrs = ['(BagOfBags) bag_bag = (x.y = 70, y->y[0-0] = true)'])
+
+ self.runCmd("type summary delete BagOfBags")
+
+ # now check we are dynamic (and arrays work)
+ self.runCmd("type filter add Plenty --child bitfield --child array[0] --child array[2]")
+ self.expect('frame variable plenty_of_stuff',
+ substrs = ['bitfield = 1',
+ 'array[0] = 5',
+ 'array[2] = 3'])
+
+ self.runCmd("n")
+ self.expect('frame variable plenty_of_stuff',
+ substrs = ['bitfield = 17',
+ 'array[0] = 5',
+ 'array[2] = 3'])
+
+ # skip synthetic children
+ self.expect('frame variable plenty_of_stuff --synthetic-type no',
+ substrs = ['some_values = 0x',
+ 'array = 0x',
+ 'array_size = 5'])
+
+
+ # check flat printing with synthetic children
+ self.expect('frame variable plenty_of_stuff --flat',
+ substrs = ['plenty_of_stuff.bitfield = 17',
+ '*(plenty_of_stuff.array) = 5',
+ '*(plenty_of_stuff.array) = 3'])
+
+ # check that we do not lose location information for our children
+ self.expect('frame variable plenty_of_stuff --location',
+ substrs = ['0x',
+ ': bitfield = 17'])
+
+ # check we work across pointer boundaries
+ self.expect('frame variable plenty_of_stuff.some_values --ptr-depth=1',
+ substrs = ['(BagOfInts *) plenty_of_stuff.some_values',
+ 'x = 5',
+ 'z = 7'])
+
+ # but not if we don't want to
+ self.runCmd("type filter add BagOfInts --child x --child z -p")
+ self.expect('frame variable plenty_of_stuff.some_values --ptr-depth=1',
+ substrs = ['(BagOfInts *) plenty_of_stuff.some_values',
+ 'x = 5',
+ 'y = 6',
+ 'z = 7'])
+
+ # check we're dynamic even if nested
+ self.runCmd("type filter add BagOfBags --child x.z")
+ self.expect('frame variable bag_bag',
+ substrs = ['x.z = 71'])
+
+ self.runCmd("n")
+ self.expect('frame variable bag_bag',
+ substrs = ['x.z = 12'])
+
+ self.runCmd('type summary add -e -s "I am always empty but have" EmptyStruct')
+ self.expect('frame variable es', substrs = ["I am always empty but have {}"])
+ self.runCmd('type summary add -e -h -s "I am really empty" EmptyStruct')
+ self.expect('frame variable es', substrs = ["I am really empty"])
+ self.expect('frame variable es', substrs = ["I am really empty {}"], matching=False)
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synth/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synth/main.cpp
new file mode 100644
index 000000000000..bac38d84fae3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synth/main.cpp
@@ -0,0 +1,86 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+struct BagOfInts
+{
+ int x;
+ int y;
+ int z;
+ BagOfInts(int X) :
+ x(X),
+ y(X+1),
+ z(X+2) {}
+};
+
+struct BagOfFloats
+{
+ float x;
+ float y;
+ float z;
+ BagOfFloats(float X) :
+ x(X+0.334),
+ y(X+0.500),
+ z(X+0.667) {}
+};
+
+struct BagOfBags
+{
+ BagOfInts x;
+ BagOfInts y;
+ BagOfFloats z;
+ BagOfFloats q;
+ BagOfBags() :
+ x('E'),
+ y('B'),
+ z(1.1),
+ q(20.11) {}
+};
+
+struct EmptyStruct {};
+
+struct Plenty
+{
+ BagOfInts *some_values;
+ int* array;
+ int array_size;
+ int bitfield;
+
+ Plenty(int N, bool flagA, bool flagB) :
+ some_values(new BagOfInts(N)),
+ array(new int[N]),
+ array_size(N),
+ bitfield( (flagA ? 0x01 : 0x00) | (flagB ? 0x10 : 0x00) )
+ {
+ for (int j = 0; j < N; j++)
+ array[j] = N-j;
+ }
+};
+
+int main (int argc, const char * argv[])
+{
+ BagOfInts int_bag(6);
+ BagOfFloats float_bag(2.71);
+
+ BagOfBags bag_bag;
+ EmptyStruct es;
+
+ Plenty plenty_of_stuff(5,true,false);
+
+ plenty_of_stuff.bitfield = 0x11; // Set break point at this line.
+
+ bag_bag.x.z = 12;
+
+ return 0;
+
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py
new file mode 100644
index 000000000000..8d6e5df37a5c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py
@@ -0,0 +1,96 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class DataFormatterSynthValueTestCase(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', 'break here')
+
+ @skipIfFreeBSD # llvm.org/pr20545 bogus output confuses buildbot parser
+ @expectedFailureWindows("llvm.org/pr24462") # Data formatters have problems on Windows
+ def test_with_run_command(self):
+ """Test using Python synthetic children provider to provide a value."""
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ x = self.frame().FindVariable("x")
+ x.SetPreferSyntheticValue(True)
+ y = self.frame().FindVariable("y")
+ y.SetPreferSyntheticValue(True)
+ z = self.frame().FindVariable("z")
+ z.SetPreferSyntheticValue(True)
+
+ x_val = x.GetValueAsUnsigned
+ y_val = y.GetValueAsUnsigned
+ z_val = z.GetValueAsUnsigned
+
+ if self.TraceOn():
+ print("x_val = %s; y_val = %s; z_val = %s" % (x_val(),y_val(),z_val()))
+
+ self.assertFalse(x_val() == 3, "x == 3 before synthetics")
+ self.assertFalse(y_val() == 4, "y == 4 before synthetics")
+ self.assertFalse(z_val() == 7, "z == 7 before synthetics")
+
+ # now set up the synth
+ self.runCmd("script from myIntSynthProvider import *")
+ self.runCmd("type synth add -l myIntSynthProvider myInt")
+ self.runCmd("type synth add -l myArraySynthProvider myArray")
+
+ if self.TraceOn():
+ print("x_val = %s; y_val = %s; z_val = %s" % (x_val(),y_val(),z_val()))
+
+ self.assertTrue(x_val() == 3, "x != 3 after synthetics")
+ self.assertTrue(y_val() == 4, "y != 4 after synthetics")
+ self.assertTrue(z_val() == 7, "z != 7 after synthetics")
+
+ self.expect("frame variable x", substrs=['3'])
+ self.expect("frame variable x", substrs=['theValue = 3'], matching=False)
+
+ # check that an aptly defined synthetic provider does not affect one-lining
+ self.expect("expression struct S { myInt theInt{12}; }; S()", substrs = ['(theInt = 12)'])
+
+ # check that we can use a synthetic value in a summary
+ self.runCmd("type summary add hasAnInt -s ${var.theInt}")
+ hi = self.frame().FindVariable("hi")
+ self.assertEqual(hi.GetSummary(), "42")
+
+ ma = self.frame().FindVariable("ma")
+ self.assertTrue(ma.IsValid())
+ self.assertEqual(ma.GetNumChildren(15), 15)
+ self.assertEqual(ma.GetNumChildren(16), 16)
+ self.assertEqual(ma.GetNumChildren(17), 16)
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/main.cpp
new file mode 100644
index 000000000000..accbf0a5a578
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/main.cpp
@@ -0,0 +1,29 @@
+class myInt {
+ private: int theValue;
+ public: myInt() : theValue(0) {}
+ public: myInt(int _x) : theValue(_x) {}
+ int val() { return theValue; }
+};
+
+class myArray {
+public:
+ int array[16];
+};
+
+class hasAnInt {
+ public:
+ myInt theInt;
+ hasAnInt() : theInt(42) {}
+};
+
+myInt operator + (myInt x, myInt y) { return myInt(x.val() + y.val()); }
+
+int main() {
+ myInt x{3};
+ myInt y{4};
+ myInt z {x+y};
+ hasAnInt hi;
+ myArray ma;
+
+ return z.val(); // break here
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/myIntSynthProvider.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/myIntSynthProvider.py
new file mode 100644
index 000000000000..c8517a442932
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/myIntSynthProvider.py
@@ -0,0 +1,36 @@
+class myIntSynthProvider(object):
+ def __init__(self, valobj, dict):
+ self.valobj = valobj;
+ self.val = self.valobj.GetChildMemberWithName("theValue")
+ def num_children(self):
+ return 0;
+ def get_child_at_index(self, index):
+ return None
+ def get_child_index(self, name):
+ return None
+ def update(self):
+ return False
+ def has_children(self):
+ return False
+ def get_value(self):
+ return self.val
+
+
+class myArraySynthProvider(object):
+ def __init__(self, valobj, dict):
+ self.valobj = valobj
+ self.array = self.valobj.GetChildMemberWithName("array")
+
+ def num_children(self, max_count):
+ if 16 < max_count:
+ return 16
+ return max_count
+
+ def get_child_at_index(self, index):
+ return None # Keep it simple when this is not tested here.
+
+ def get_child_index(self, name):
+ return None # Keep it simple when this is not tested here.
+
+ def has_children(self):
+ return True
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/dump_dynamic/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/dump_dynamic/Makefile
new file mode 100644
index 000000000000..69dde1b76184
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/dump_dynamic/Makefile
@@ -0,0 +1,12 @@
+LEVEL = ../../../make
+CXX_SOURCES := main.cpp
+CXXFLAGS += -std=c++11
+
+# clang-3.5+ outputs FullDebugInfo by default for Darwin/FreeBSD
+# targets. Other targets do not, which causes this test to fail.
+# This flag enables FullDebugInfo for all targets.
+ifneq (,$(findstring clang,$(CC)))
+ CFLAGS_EXTRAS += -fno-limit-debug-info
+endif
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/dump_dynamic/TestDumpDynamic.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/dump_dynamic/TestDumpDynamic.py
new file mode 100644
index 000000000000..8ae09d691940
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/dump_dynamic/TestDumpDynamic.py
@@ -0,0 +1,5 @@
+from __future__ import absolute_import
+
+from lldbsuite.test import lldbinline
+
+lldbinline.MakeInlineTest(__file__, globals(), [lldbinline.expectedFailureWindows("llvm.org/pr24663")])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/dump_dynamic/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/dump_dynamic/main.cpp
new file mode 100644
index 000000000000..bc8e05829316
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/dump_dynamic/main.cpp
@@ -0,0 +1,35 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+class Base {
+public:
+ Base () = default;
+ virtual int func() { return 1; }
+ virtual ~Base() = default;
+};
+
+class Derived : public Base {
+private:
+ int m_derived_data;
+public:
+ Derived () : Base(), m_derived_data(0x0fedbeef) {}
+ virtual ~Derived() = default;
+ virtual int func() { return m_derived_data; }
+};
+
+int main (int argc, char const *argv[])
+{
+ Base *base = new Derived();
+ return 0; //% stream = lldb.SBStream()
+ //% base = self.frame().FindVariable("base")
+ //% base.SetPreferDynamicValue(lldb.eDynamicDontRunTarget)
+ //% base.GetDescription(stream)
+ //% if self.TraceOn(): print(stream.GetData())
+ //% self.assertTrue(stream.GetData().startswith("(Derived *"))
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/format-propagation/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/format-propagation/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/format-propagation/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/format-propagation/TestFormatPropagation.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/format-propagation/TestFormatPropagation.py
new file mode 100644
index 000000000000..5cb7c82c9e09
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/format-propagation/TestFormatPropagation.py
@@ -0,0 +1,75 @@
+"""
+Check if changing Format on an SBValue correctly propagates that new format to children as it should
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class FormatPropagationTestCase(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.')
+
+ # rdar://problem/14035604
+ def test_with_run_command(self):
+ """Check for an issue where capping does not work because the Target pointer appears to be changing behind our backs."""
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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():
+ pass
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # extract the parent and the children
+ frame = self.frame()
+ parent = self.frame().FindVariable("f")
+ self.assertTrue(parent != None and parent.IsValid(),"could not find f")
+ X = parent.GetChildMemberWithName("X")
+ self.assertTrue(X != None and X.IsValid(),"could not find X")
+ Y = parent.GetChildMemberWithName("Y")
+ self.assertTrue(Y != None and Y.IsValid(),"could not find Y")
+ # check their values now
+ self.assertTrue(X.GetValue() == "1", "X has an invalid value")
+ self.assertTrue(Y.GetValue() == "2", "Y has an invalid value")
+ # set the format on the parent
+ parent.SetFormat(lldb.eFormatHex)
+ self.assertTrue(X.GetValue() == "0x00000001", "X has not changed format")
+ self.assertTrue(Y.GetValue() == "0x00000002", "Y has not changed format")
+ # Step and check if the values make sense still
+ self.runCmd("next")
+ self.assertTrue(X.GetValue() == "0x00000004", "X has not become 4")
+ self.assertTrue(Y.GetValue() == "0x00000002", "Y has not stuck as hex")
+ # Check that children can still make their own choices
+ Y.SetFormat(lldb.eFormatDecimal)
+ self.assertTrue(X.GetValue() == "0x00000004", "X is still hex")
+ self.assertTrue(Y.GetValue() == "2", "Y has not been reset")
+ # Make a few more changes
+ parent.SetFormat(lldb.eFormatDefault)
+ X.SetFormat(lldb.eFormatHex)
+ Y.SetFormat(lldb.eFormatDefault)
+ self.assertTrue(X.GetValue() == "0x00000004", "X is not hex as it asked")
+ self.assertTrue(Y.GetValue() == "2", "Y is not defaulted")
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/format-propagation/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/format-propagation/main.cpp
new file mode 100644
index 000000000000..5822fbc2a710
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/format-propagation/main.cpp
@@ -0,0 +1,13 @@
+struct foo
+{
+ int X;
+ int Y;
+ foo(int a, int b) : X(a), Y(b) {}
+};
+
+int main()
+{
+ foo f(1,2);
+ f.X = 4; // Set break point at this line.
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/frameformat_smallstruct/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/frameformat_smallstruct/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/frameformat_smallstruct/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/frameformat_smallstruct/TestFrameFormatSmallStruct.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/frameformat_smallstruct/TestFrameFormatSmallStruct.py
new file mode 100644
index 000000000000..555351998c2d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/frameformat_smallstruct/TestFrameFormatSmallStruct.py
@@ -0,0 +1,38 @@
+"""
+Test that the user can input a format but it will not prevail over summary format's choices.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class FrameFormatSmallStructTestCase(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.')
+
+ def test_with_run_command(self):
+ """Test that the user can input a format but it will not prevail over summary format's choices."""
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ self.expect("thread list", substrs = ['addPair(p=(x = 3, y = -3))'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/frameformat_smallstruct/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/frameformat_smallstruct/main.cpp
new file mode 100644
index 000000000000..120ef0ea0910
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/frameformat_smallstruct/main.cpp
@@ -0,0 +1,25 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+struct Pair {
+ int x;
+ int y;
+
+ Pair(int _x, int _y) : x(_x), y(_y) {}
+};
+
+int addPair(Pair p)
+{
+ return p.x + p.y; // Set break point at this line.
+}
+
+int main() {
+ Pair p1(3,-3);
+ return addPair(p1);
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/hexcaps/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/hexcaps/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/hexcaps/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/hexcaps/TestDataFormatterHexCaps.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/hexcaps/TestDataFormatterHexCaps.py
new file mode 100644
index 000000000000..3c28b68056f5
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/hexcaps/TestDataFormatterHexCaps.py
@@ -0,0 +1,82 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class DataFormatterHexCapsTestCase(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.')
+
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 delete hex', check=False)
+ self.runCmd('type summary clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.runCmd("type format add -f uppercase int")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ 'first = 0x001122AA', 'second = 0x1122BB44'])
+
+ self.runCmd("type format add -f hex int")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ 'first = 0x001122aa', 'second = 0x1122bb44'])
+
+ self.runCmd("type format delete int")
+
+ self.runCmd("type summary add -s \"${var.first%X} and ${var.second%x}\" foo")
+
+ self.expect('frame variable mine',
+ substrs = ['(foo) mine = 0x001122AA and 0x1122bb44'])
+
+ self.runCmd("type summary add -s \"${var.first%X} and ${var.second%X}\" foo")
+ self.runCmd("next")
+ self.runCmd("next")
+ self.expect('frame variable mine',
+ substrs = ['(foo) mine = 0xAABBCCDD and 0x1122BB44'])
+
+ self.runCmd("type summary add -s \"${var.first%x} and ${var.second%X}\" foo")
+ self.expect('frame variable mine',
+ substrs = ['(foo) mine = 0xaabbccdd and 0x1122BB44'])
+ self.runCmd("next")
+ self.runCmd("next")
+ self.runCmd("type summary add -s \"${var.first%x} and ${var.second%x}\" foo")
+ self.expect('frame variable mine',
+ substrs = ['(foo) mine = 0xaabbccdd and 0xff00ff00'])
+ self.runCmd("type summary add -s \"${var.first%X} and ${var.second%X}\" foo")
+ self.expect('frame variable mine',
+ substrs = ['(foo) mine = 0xAABBCCDD and 0xFF00FF00'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/hexcaps/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/hexcaps/main.cpp
new file mode 100644
index 000000000000..5ee113c17b28
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/hexcaps/main.cpp
@@ -0,0 +1,28 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+
+struct foo
+{
+ int first;
+ int second;
+};
+
+int main ()
+{
+ struct foo mine = {0x001122AA, 0x1122BB44};
+ printf("main.first = 0x%8.8x, main.second = 0x%8.8x\n", mine.first, mine.second);
+ mine.first = 0xAABBCCDD; // Set break point at this line.
+ printf("main.first = 0x%8.8x, main.second = 0x%8.8x\n", mine.first, mine.second);
+ mine.second = 0xFF00FF00;
+ printf("main.first = 0x%8.8x, main.second = 0x%8.8x\n", mine.first, mine.second);
+ return 0;
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/language_category_updates/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/language_category_updates/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/language_category_updates/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/language_category_updates/TestDataFormatterLanguageCategoryUpdates.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/language_category_updates/TestDataFormatterLanguageCategoryUpdates.py
new file mode 100644
index 000000000000..b7562c4336a6
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/language_category_updates/TestDataFormatterLanguageCategoryUpdates.py
@@ -0,0 +1,60 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class LanguageCategoryUpdatesTestCase(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', '// break here')
+
+ @expectedFailureWindows("llvm.org/pr24462") # Data formatters have problems on Windows
+ def test_with_run_command(self):
+ """Test that LLDB correctly cleans caches when language categories change."""
+ # This is the function to remove the custom formats in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ if hasattr(self, 'type_category') and hasattr(self, 'type_specifier'):
+ self.type_category.DeleteTypeSummary(self.type_specifier)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ self.expect("frame variable", substrs = ['(S)', 'object', '123', '456'], matching=True)
+
+ self.type_category = self.dbg.GetCategory(lldb.eLanguageTypeC_plus_plus)
+ type_summary = lldb.SBTypeSummary.CreateWithSummaryString("this is an object of type S")
+ self.type_specifier = lldb.SBTypeNameSpecifier('S')
+ self.type_category.AddTypeSummary(self.type_specifier, type_summary)
+
+ self.expect("frame variable", substrs = ['this is an object of type S'], matching=True)
+
+ self.type_category.DeleteTypeSummary(self.type_specifier)
+ self.expect("frame variable", substrs = ['this is an object of type S'], matching=False)
+ self.expect("frame variable", substrs = ['(S)', 'object', '123', '456'], matching=True)
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/language_category_updates/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/language_category_updates/main.cpp
new file mode 100644
index 000000000000..ac77e537b80a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/language_category_updates/main.cpp
@@ -0,0 +1,20 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+struct S {
+ int x;
+ int y;
+
+ S() : x(123), y(456) {}
+};
+
+int main() {
+ S object;
+ return 0; // break here
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/nsarraysynth/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/nsarraysynth/Makefile
new file mode 100644
index 000000000000..9f7fb1ca6231
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/nsarraysynth/Makefile
@@ -0,0 +1,9 @@
+LEVEL = ../../../make
+
+OBJC_SOURCES := main.m
+
+CFLAGS_EXTRAS += -w
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/nsarraysynth/TestNSArraySynthetic.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/nsarraysynth/TestNSArraySynthetic.py
new file mode 100644
index 000000000000..a12f9c841a7f
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/nsarraysynth/TestNSArraySynthetic.py
@@ -0,0 +1,67 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import datetime
+import lldbsuite.test.lldbutil as lldbutil
+
+class NSArraySyntheticTestCase(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.m', '// Set break point at this line.')
+
+ @skipUnlessDarwin
+ def test_rdar11086338_with_run_command(self):
+ """Test that NSArray reports its synthetic children properly."""
+ self.build()
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 synth clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # Now check that we are displaying Cocoa classes correctly
+ self.expect('frame variable arr',
+ substrs = ['@"6 elements"'])
+ self.expect('frame variable other_arr',
+ substrs = ['@"4 elements"'])
+ self.expect('frame variable arr --ptr-depth 1',
+ substrs = ['@"6 elements"','[0] = 0x','[1] = 0x','[2] = 0x','[3] = 0x','[4] = 0x','[5] = 0x'])
+ self.expect('frame variable other_arr --ptr-depth 1',
+ substrs = ['@"4 elements"','[0] = 0x','[1] = 0x','[2] = 0x','[3] = 0x'])
+ self.expect('frame variable arr --ptr-depth 1 -d no-run-target',
+ substrs = ['@"6 elements"','@"hello"','@"world"','@"this"','@"is"','@"me"','@"http://www.apple.com'])
+ self.expect('frame variable other_arr --ptr-depth 1 -d no-run-target',
+ substrs = ['@"4 elements"','(int)5','@"a string"','@"6 elements"'])
+ self.expect('frame variable other_arr --ptr-depth 2 -d no-run-target',
+ substrs = ['@"4 elements"','@"6 elements" {','@"hello"','@"world"','@"this"','@"is"','@"me"','@"http://www.apple.com'])
+
+ self.assertTrue(self.frame().FindVariable("arr").MightHaveChildren(), "arr says it does not have children!")
+ self.assertTrue(self.frame().FindVariable("other_arr").MightHaveChildren(), "arr says it does not have children!")
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/nsarraysynth/main.m b/packages/Python/lldbsuite/test/functionalities/data-formatter/nsarraysynth/main.m
new file mode 100644
index 000000000000..1b4a6e03857a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/nsarraysynth/main.m
@@ -0,0 +1,35 @@
+//===-- main.m ------------------------------------------------*- ObjC -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#import <Foundation/Foundation.h>
+
+int main (int argc, const char * argv[])
+{
+
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+
+ NSMutableArray* arr = [[NSMutableArray alloc] init];
+ [arr addObject:@"hello"];
+ [arr addObject:@"world"];
+ [arr addObject:@"this"];
+ [arr addObject:@"is"];
+ [arr addObject:@"me"];
+ [arr addObject:[NSURL URLWithString:@"http://www.apple.com/"]];
+
+ NSDate *aDate = [NSDate distantFuture];
+ NSValue *aValue = [NSNumber numberWithInt:5];
+ NSString *aString = @"a string";
+
+ NSArray *other_arr = [NSArray arrayWithObjects:aDate, aValue, aString, arr, nil];
+
+ [pool drain];// Set break point at this line.
+ return 0;
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/nsdictionarysynth/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/nsdictionarysynth/Makefile
new file mode 100644
index 000000000000..9f7fb1ca6231
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/nsdictionarysynth/Makefile
@@ -0,0 +1,9 @@
+LEVEL = ../../../make
+
+OBJC_SOURCES := main.m
+
+CFLAGS_EXTRAS += -w
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/nsdictionarysynth/TestNSDictionarySynthetic.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/nsdictionarysynth/TestNSDictionarySynthetic.py
new file mode 100644
index 000000000000..13d493ecbdcc
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/nsdictionarysynth/TestNSDictionarySynthetic.py
@@ -0,0 +1,69 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import datetime
+import lldbsuite.test.lldbutil as lldbutil
+
+class NSDictionarySyntheticTestCase(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.m', '// Set break point at this line.')
+
+ @skipUnlessDarwin
+ def test_rdar11988289_with_run_command(self):
+ """Test that NSDictionary reports its synthetic children properly."""
+ self.build()
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 synth clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # Now check that we are displaying Cocoa classes correctly
+ self.expect('frame variable dictionary',
+ substrs = ['3 key/value pairs'])
+ self.expect('frame variable mutabledict',
+ substrs = ['4 key/value pairs'])
+ self.expect('frame variable dictionary --ptr-depth 1',
+ substrs = ['3 key/value pairs','[0] = ','key = 0x','value = 0x','[1] = ','[2] = '])
+ self.expect('frame variable mutabledict --ptr-depth 1',
+ substrs = ['4 key/value pairs','[0] = ','key = 0x','value = 0x','[1] = ','[2] = ','[3] = '])
+ self.expect('frame variable dictionary --ptr-depth 1 --dynamic-type no-run-target',
+ substrs = ['3 key/value pairs','@"bar"','@"2 elements"','@"baz"','2 key/value pairs'])
+ self.expect('frame variable mutabledict --ptr-depth 1 --dynamic-type no-run-target',
+ substrs = ['4 key/value pairs','(int)23','@"123"','@"http://www.apple.com"','@"sourceofstuff"','3 key/value pairs'])
+ self.expect('frame variable mutabledict --ptr-depth 2 --dynamic-type no-run-target',
+ substrs = ['4 key/value pairs','(int)23','@"123"','@"http://www.apple.com"','@"sourceofstuff"','3 key/value pairs','@"bar"','@"2 elements"'])
+ self.expect('frame variable mutabledict --ptr-depth 3 --dynamic-type no-run-target',
+ substrs = ['4 key/value pairs','(int)23','@"123"','@"http://www.apple.com"','@"sourceofstuff"','3 key/value pairs','@"bar"','@"2 elements"','(int)1','@"two"'])
+
+ self.assertTrue(self.frame().FindVariable("dictionary").MightHaveChildren(), "dictionary says it does not have children!")
+ self.assertTrue(self.frame().FindVariable("mutabledict").MightHaveChildren(), "mutable says it does not have children!")
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/nsdictionarysynth/main.m b/packages/Python/lldbsuite/test/functionalities/data-formatter/nsdictionarysynth/main.m
new file mode 100644
index 000000000000..fdc533aeaf24
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/nsdictionarysynth/main.m
@@ -0,0 +1,30 @@
+//===-- main.m ------------------------------------------------*- ObjC -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#import <Foundation/Foundation.h>
+
+int main (int argc, const char * argv[])
+{
+
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+
+ NSArray* keys = @[@"foo",@"bar",@"baz"];
+ NSArray* values = @[@"hello",@[@"X",@"Y"],@{@1 : @"one",@2 : @"two"}];
+ NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys];
+ NSMutableDictionary* mutabledict = [NSMutableDictionary dictionaryWithCapacity:5];
+ [mutabledict setObject:@"123" forKey:@23];
+ [mutabledict setObject:[NSURL URLWithString:@"http://www.apple.com"] forKey:@"foobar"];
+ [mutabledict setObject:@[@"a",@12] forKey:@57];
+ [mutabledict setObject:dictionary forKey:@"sourceofstuff"];
+
+ [pool drain];// Set break point at this line.
+ return 0;
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/nssetsynth/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/nssetsynth/Makefile
new file mode 100644
index 000000000000..9f7fb1ca6231
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/nssetsynth/Makefile
@@ -0,0 +1,9 @@
+LEVEL = ../../../make
+
+OBJC_SOURCES := main.m
+
+CFLAGS_EXTRAS += -w
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/nssetsynth/TestNSSetSynthetic.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/nssetsynth/TestNSSetSynthetic.py
new file mode 100644
index 000000000000..6c558001bb04
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/nssetsynth/TestNSSetSynthetic.py
@@ -0,0 +1,74 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import datetime
+import lldbsuite.test.lldbutil as lldbutil
+
+class NSSetSyntheticTestCase(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.m', '// Set break point at this line.')
+
+ @skipUnlessDarwin
+ def test_rdar12529957_with_run_command(self):
+ """Test that NSSet reports its synthetic children properly."""
+ self.build()
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 synth clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # Now check that we are displaying Cocoa classes correctly
+ self.expect('frame variable set',
+ substrs = ['4 elements'])
+ self.expect('frame variable mutable',
+ substrs = ['9 elements'])
+ self.expect('frame variable set --ptr-depth 1 -d run -T',
+ substrs = ['4 elements','[0]','[1]','[2]','[3]','hello','world','(int)1','(int)2'])
+ self.expect('frame variable mutable --ptr-depth 1 -d run -T',
+ substrs = ['9 elements','(int)5','@"3 elements"','@"www.apple.com"','(int)3','@"world"','(int)4'])
+
+ self.runCmd("next")
+ self.expect('frame variable mutable',
+ substrs = ['0 elements'])
+
+ self.runCmd("next")
+ self.expect('frame variable mutable',
+ substrs = ['4 elements'])
+ self.expect('frame variable mutable --ptr-depth 1 -d run -T',
+ substrs = ['4 elements','[0]','[1]','[2]','[3]','hello','world','(int)1','(int)2'])
+
+ self.runCmd("next")
+ self.expect('frame variable mutable',
+ substrs = ['4 elements'])
+ self.expect('frame variable mutable --ptr-depth 1 -d run -T',
+ substrs = ['4 elements','[0]','[1]','[2]','[3]','hello','world','(int)1','(int)2'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/nssetsynth/main.m b/packages/Python/lldbsuite/test/functionalities/data-formatter/nssetsynth/main.m
new file mode 100644
index 000000000000..7bc49583606f
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/nssetsynth/main.m
@@ -0,0 +1,34 @@
+//===-- main.m ------------------------------------------------*- ObjC -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#import <Foundation/Foundation.h>
+
+int main (int argc, const char * argv[])
+{
+
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+ NSSet* set = [NSSet setWithArray:@[@1,@"hello",@2,@"world"]];
+ NSMutableSet* mutable = [NSMutableSet setWithCapacity:5];
+ [mutable addObject:@1];
+ [mutable addObject:@2];
+ [mutable addObject:@3];
+ [mutable addObject:@4];
+ [mutable addObject:@5];
+ [mutable addObject:[NSURL URLWithString:@"www.apple.com"]];
+ [mutable addObject:@[@1,@2,@3]];
+ [mutable unionSet:set];
+ [mutable removeAllObjects]; // Set break point at this line.
+ [mutable unionSet:set];
+ [mutable addObject:@1];
+
+ [pool drain];
+ return 0;
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/ostypeformatting/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/ostypeformatting/Makefile
new file mode 100644
index 000000000000..261658b10ae8
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/ostypeformatting/Makefile
@@ -0,0 +1,9 @@
+LEVEL = ../../../make
+
+OBJCXX_SOURCES := main.mm
+
+CFLAGS_EXTRAS += -w
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/ostypeformatting/TestFormattersOsType.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/ostypeformatting/TestFormattersOsType.py
new file mode 100644
index 000000000000..4fb6176e9e4f
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/ostypeformatting/TestFormattersOsType.py
@@ -0,0 +1,52 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import datetime
+import lldbsuite.test.lldbutil as lldbutil
+
+class DataFormatterOSTypeTestCase(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.mm', '// Set break point at this line.')
+
+ @skipUnlessDarwin
+ def test_ostype_with_run_command(self):
+ """Test the formatters we use for OSType."""
+ self.build()
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.mm", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 synth clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # Now check that we use the right summary for OSType
+ self.expect('frame variable',
+ substrs = ["'test'","'best'"])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/ostypeformatting/main.mm b/packages/Python/lldbsuite/test/functionalities/data-formatter/ostypeformatting/main.mm
new file mode 100644
index 000000000000..8d22659374a7
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/ostypeformatting/main.mm
@@ -0,0 +1,23 @@
+//===-- main.m ------------------------------------------------*- ObjC -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#import <Foundation/Foundation.h>
+
+int main (int argc, const char * argv[])
+{
+
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+ OSType a = 'test';
+ OSType b = 'best';
+
+ [pool drain];// Set break point at this line.
+ return 0;
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/ptr_ref_typedef/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/ptr_ref_typedef/Makefile
new file mode 100644
index 000000000000..d85e665333ea
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/ptr_ref_typedef/Makefile
@@ -0,0 +1,7 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+CFLAGS_EXTRAS += -std=c++11
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/ptr_ref_typedef/TestPtrRef2Typedef.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/ptr_ref_typedef/TestPtrRef2Typedef.py
new file mode 100644
index 000000000000..bf98559cd0c1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/ptr_ref_typedef/TestPtrRef2Typedef.py
@@ -0,0 +1,57 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class PtrRef2TypedefTestCase(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 breakpoint here')
+
+ def test_with_run_command(self):
+ """Test that a pointer/reference to a typedef is formatted as we want."""
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.runCmd('type summary add --cascade true -s "IntPointer" "int *"')
+ self.runCmd('type summary add --cascade true -s "IntLRef" "int &"')
+ self.runCmd('type summary add --cascade true -s "IntRRef" "int &&"')
+
+ self.expect("frame variable x", substrs = ['(Foo *) x = 0x','IntPointer'])
+ # note: Ubuntu 12.04 x86_64 build with gcc 4.8.2 is getting a
+ # const after the ref that isn't showing up on FreeBSD. This
+ # tweak changes the behavior so that the const is not part of
+ # the match.
+ self.expect("frame variable y", substrs = ['(Foo &', ') y = 0x','IntLRef'])
+ self.expect("frame variable z", substrs = ['(Foo &&', ') z = 0x','IntRRef'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/ptr_ref_typedef/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/ptr_ref_typedef/main.cpp
new file mode 100644
index 000000000000..219f398da3f5
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/ptr_ref_typedef/main.cpp
@@ -0,0 +1,19 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+typedef int Foo;
+
+int main() {
+ int lval = 1;
+ Foo* x = &lval;
+ Foo& y = lval;
+ Foo&& z = 1;
+ return 0; // Set breakpoint here
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/refpointer-recursion/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/refpointer-recursion/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/refpointer-recursion/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/refpointer-recursion/TestDataFormatterRefPtrRecursion.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/refpointer-recursion/TestDataFormatterRefPtrRecursion.py
new file mode 100644
index 000000000000..13b84e9f74c7
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/refpointer-recursion/TestDataFormatterRefPtrRecursion.py
@@ -0,0 +1,41 @@
+"""
+Test that ValueObjectPrinter does not cause an infinite loop when a reference to a struct that contains a pointer to itself is printed.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class DataFormatterRefPtrRecursionTestCase(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.')
+
+ def test_with_run_command(self):
+ """Test that ValueObjectPrinter does not cause an infinite loop when a reference to a struct that contains a pointer to itself is printed."""
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ self.expect("frame variable foo", substrs = []);
+ self.expect("frame variable foo --ptr-depth=1", substrs = ['ID = 1']);
+ self.expect("frame variable foo --ptr-depth=2", substrs = ['ID = 1']);
+ self.expect("frame variable foo --ptr-depth=3", substrs = ['ID = 1']);
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/refpointer-recursion/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/refpointer-recursion/main.cpp
new file mode 100644
index 000000000000..4b576bd266dd
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/refpointer-recursion/main.cpp
@@ -0,0 +1,21 @@
+int _ID = 0;
+
+class Foo {
+ public:
+ Foo *next;
+ int ID;
+
+ Foo () : next(0), ID(++_ID) {}
+};
+
+int evalFoo(Foo& foo)
+{
+ return foo.ID; // Set break point at this line.
+}
+
+int main() {
+ Foo f;
+ f.next = &f;
+ return evalFoo(f);
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/setvaluefromcstring/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/setvaluefromcstring/Makefile
new file mode 100644
index 000000000000..62a57f6cd9be
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/setvaluefromcstring/Makefile
@@ -0,0 +1,4 @@
+LEVEL = ../../../make
+OBJC_SOURCES := main.m
+include $(LEVEL)/Makefile.rules
+LDFLAGS += -framework Foundation
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/setvaluefromcstring/TestSetValueFromCString.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/setvaluefromcstring/TestSetValueFromCString.py
new file mode 100644
index 000000000000..80305e303d03
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/setvaluefromcstring/TestSetValueFromCString.py
@@ -0,0 +1,4 @@
+import lldbsuite.test.lldbinline as lldbinline
+import lldbsuite.test.lldbtest as lldbtest
+
+lldbinline.MakeInlineTest(__file__, globals(), [lldbtest.skipIfFreeBSD,lldbtest.skipIfLinux,lldbtest.skipIfWindows])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/setvaluefromcstring/main.m b/packages/Python/lldbsuite/test/functionalities/data-formatter/setvaluefromcstring/main.m
new file mode 100644
index 000000000000..3dd455081007
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/setvaluefromcstring/main.m
@@ -0,0 +1,19 @@
+//===-- main.m ---------------------------------------------------*- ObjC -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#import <Foundation/Foundation.h>
+
+int main() {
+ NSDictionary* dic = @{@1 : @2};
+ NSLog(@"hello world"); //% dic = self.frame().FindVariable("dic")
+ //% dic.SetPreferSyntheticValue(True)
+ //% dic.SetPreferDynamicValue(lldb.eDynamicCanRunTarget)
+ //% dic.SetValueFromCString("12")
+ return 0; //% dic = self.frame().FindVariable("dic")
+ //% self.assertTrue(dic.GetValueAsUnsigned() == 0xC, "failed to read what I wrote")
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/stringprinter/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/stringprinter/Makefile
new file mode 100644
index 000000000000..69dde1b76184
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/stringprinter/Makefile
@@ -0,0 +1,12 @@
+LEVEL = ../../../make
+CXX_SOURCES := main.cpp
+CXXFLAGS += -std=c++11
+
+# clang-3.5+ outputs FullDebugInfo by default for Darwin/FreeBSD
+# targets. Other targets do not, which causes this test to fail.
+# This flag enables FullDebugInfo for all targets.
+ifneq (,$(findstring clang,$(CC)))
+ CFLAGS_EXTRAS += -fno-limit-debug-info
+endif
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/stringprinter/TestStringPrinter.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/stringprinter/TestStringPrinter.py
new file mode 100644
index 000000000000..69f7d48c8b6c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/stringprinter/TestStringPrinter.py
@@ -0,0 +1,4 @@
+import lldbsuite.test.lldbinline as lldbinline
+import lldbsuite.test.lldbtest as lldbtest
+
+lldbinline.MakeInlineTest(__file__, globals(), [lldbtest.expectedFailureWindows("llvm.org/pr24772")])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/stringprinter/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/stringprinter/main.cpp
new file mode 100644
index 000000000000..4a449e9716c3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/stringprinter/main.cpp
@@ -0,0 +1,40 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <string>
+
+int main (int argc, char const *argv[])
+{
+ std::string stdstring("Hello\t\tWorld\nI am here\t\tto say hello\n"); //%self.addTearDownHook(lambda x: x.runCmd("setting set escape-non-printables true"))
+ const char* constcharstar = stdstring.c_str();
+ std::string longstring(
+"I am a very long string; in fact I am longer than any reasonable length that a string should be; quite long indeed; oh my, so many words; so many letters; this is kind of like writing a poem; except in real life all that is happening"
+" is just me producing a very very long set of words; there is text here, text there, text everywhere; it fills me with glee to see so much text; all around me it's just letters, and symbols, and other pleasant drawings that cause me"
+" a large amount of joy upon visually seeing them with my eyes; well, this is now a lot of letters, but it is still not enough for the purpose of the test I want to test, so maybe I should copy and paste this a few times, you know.."
+" for science, or something"
+ "I am a very long string; in fact I am longer than any reasonable length that a string should be; quite long indeed; oh my, so many words; so many letters; this is kind of like writing a poem; except in real life all that is happening"
+ " is just me producing a very very long set of words; there is text here, text there, text everywhere; it fills me with glee to see so much text; all around me it's just letters, and symbols, and other pleasant drawings that cause me"
+ " a large amount of joy upon visually seeing them with my eyes; well, this is now a lot of letters, but it is still not enough for the purpose of the test I want to test, so maybe I should copy and paste this a few times, you know.."
+ " for science, or something"
+ "I am a very long string; in fact I am longer than any reasonable length that a string should be; quite long indeed; oh my, so many words; so many letters; this is kind of like writing a poem; except in real life all that is happening"
+ " is just me producing a very very long set of words; there is text here, text there, text everywhere; it fills me with glee to see so much text; all around me it's just letters, and symbols, and other pleasant drawings that cause me"
+ " a large amount of joy upon visually seeing them with my eyes; well, this is now a lot of letters, but it is still not enough for the purpose of the test I want to test, so maybe I should copy and paste this a few times, you know.."
+ " for science, or something"
+ );
+ const char* longconstcharstar = longstring.c_str();
+ return 0; //% if self.TraceOn(): self.runCmd('frame variable')
+ //% self.assertTrue(self.frame().FindVariable('stdstring').GetSummary() == '"Hello\\t\\tWorld\\nI am here\\t\\tto say hello\\n"')
+ //% self.assertTrue(self.frame().FindVariable('constcharstar').GetSummary() == '"Hello\\t\\tWorld\\nI am here\\t\\tto say hello\\n"')
+ //% self.runCmd("setting set escape-non-printables false")
+ //% self.assertTrue(self.frame().FindVariable('stdstring').GetSummary() == '"Hello\t\tWorld\nI am here\t\tto say hello\n"')
+ //% self.assertTrue(self.frame().FindVariable('constcharstar').GetSummary() == '"Hello\t\tWorld\nI am here\t\tto say hello\n"')
+ //% self.assertTrue(self.frame().FindVariable('longstring').GetSummary().endswith('"...'))
+ //% self.assertTrue(self.frame().FindVariable('longconstcharstar').GetSummary().endswith('"...'))
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/summary-string-onfail/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/summary-string-onfail/Makefile
new file mode 100644
index 000000000000..04f39271f0cd
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/summary-string-onfail/Makefile
@@ -0,0 +1,12 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+# clang-3.5+ outputs FullDebugInfo by default for Darwin/FreeBSD
+# targets. Other targets do not, which causes this test to fail.
+# This flag enables FullDebugInfo for all targets.
+ifneq (,$(findstring clang,$(CC)))
+ CFLAGS_EXTRAS += -fno-limit-debug-info
+endif
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/summary-string-onfail/Test-rdar-9974002.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/summary-string-onfail/Test-rdar-9974002.py
new file mode 100644
index 000000000000..2873e35368fb
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/summary-string-onfail/Test-rdar-9974002.py
@@ -0,0 +1,133 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class Radar9974002DataFormatterTestCase(TestBase):
+
+ # test for rdar://problem/9974002 ()
+ 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.')
+
+ def test_with_run_command(self):
+ """Test that that file and class static variables display correctly."""
+ self.build()
+ if "clang" in self.getCompiler() and "3.4" in self.getCompilerVersion():
+ self.skipTest("llvm.org/pr16214 -- clang emits partial DWARF for structures referenced via typedef")
+
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 summary clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer.first}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', '<parent is NULL>'])
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', '0x000000'])
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer%S}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', '0x000000'])
+
+ self.runCmd("type summary add -s foo contained")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', 'foo'])
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', 'foo'])
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer%V}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', '0x000000'])
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer.first}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', '<parent is NULL>'])
+
+ self.runCmd("type summary delete contained")
+ self.runCmd("n")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', '<parent is NULL>'])
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', '0x000000'])
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer%S}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', '0x000000'])
+
+ self.runCmd("type summary add -s foo contained")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', 'foo'])
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', 'foo'])
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer%V}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', '0x000000'])
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer.first}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', '<parent is NULL>'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/summary-string-onfail/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/summary-string-onfail/main.cpp
new file mode 100644
index 000000000000..03a9f278b7ec
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/summary-string-onfail/main.cpp
@@ -0,0 +1,30 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+
+struct contained
+{
+ int first;
+ int second;
+};
+
+struct container
+{
+ int scalar;
+ struct contained *pointer;
+};
+
+int main ()
+{
+ struct container mine = {1, 0};
+ printf ("Mine's scalar is the only thing that is good: %d.\n", mine.scalar); // Set break point at this line.
+ return 0;
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/TestSyntheticCapping.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/TestSyntheticCapping.py
new file mode 100644
index 000000000000..0550f57ae62a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/TestSyntheticCapping.py
@@ -0,0 +1,75 @@
+"""
+Check for an issue where capping does not work because the Target pointer appears to be changing behind our backs
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class SyntheticCappingTestCase(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.')
+
+ def test_with_run_command(self):
+ """Check for an issue where capping does not work because the Target pointer appears to be changing behind our backs."""
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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)
+
+ # set up the synthetic children provider
+ self.runCmd("script from fooSynthProvider import *")
+ self.runCmd("type synth add -l fooSynthProvider foo")
+
+ # check that the synthetic children work, so we know we are doing the right thing
+ self.expect("frame variable f00_1",
+ substrs = ['r = 33',
+ 'fake_a = 16777216',
+ 'a = 0']);
+
+ # check that capping works
+ self.runCmd("settings set target.max-children-count 2", check=False)
+
+ self.expect("frame variable f00_1",
+ substrs = ['...',
+ 'fake_a = 16777216',
+ 'a = 0']);
+
+ self.expect("frame variable f00_1", matching=False,
+ substrs = ['r = 33']);
+
+
+ self.runCmd("settings set target.max-children-count 256", check=False)
+
+ self.expect("frame variable f00_1", matching=True,
+ substrs = ['r = 33']);
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/fooSynthProvider.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/fooSynthProvider.py
new file mode 100644
index 000000000000..fb95ac2b54d0
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/fooSynthProvider.py
@@ -0,0 +1,21 @@
+import lldb
+class fooSynthProvider:
+ def __init__(self, valobj, dict):
+ self.valobj = valobj;
+ self.int_type = valobj.GetType().GetBasicType(lldb.eBasicTypeInt)
+ def num_children(self):
+ return 3;
+ def get_child_at_index(self, index):
+ if index == 0:
+ child = self.valobj.GetChildMemberWithName('a');
+ if index == 1:
+ child = self.valobj.CreateChildAtOffset ('fake_a', 1, self.int_type);
+ if index == 2:
+ child = self.valobj.GetChildMemberWithName('r');
+ return child;
+ def get_child_index(self, name):
+ if name == 'a':
+ return 0;
+ if name == 'fake_a':
+ return 1;
+ return 2;
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/main.cpp
new file mode 100644
index 000000000000..b921915b91c5
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/main.cpp
@@ -0,0 +1,62 @@
+struct foo
+{
+ int a;
+ int b;
+ int c;
+ int d;
+ int e;
+ int f;
+ int g;
+ int h;
+ int i;
+ int j;
+ int k;
+ int l;
+ int m;
+ int n;
+ int o;
+ int p;
+ int q;
+ int r;
+
+ foo(int X) :
+ a(X),
+ b(X+1),
+ c(X+3),
+ d(X+5),
+ e(X+7),
+ f(X+9),
+ g(X+11),
+ h(X+13),
+ i(X+15),
+ j(X+17),
+ k(X+19),
+ l(X+21),
+ m(X+23),
+ n(X+25),
+ o(X+27),
+ p(X+29),
+ q(X+31),
+ r(X+33) {}
+};
+
+struct wrapint
+{
+ int x;
+ wrapint(int X) : x(X) {}
+};
+
+int main()
+{
+ foo f00_1(0);
+ foo *f00_ptr = new foo(12);
+
+ f00_1.a++; // Set break point at this line.
+
+ wrapint test_cast('A' +
+ 256*'B' +
+ 256*256*'C'+
+ 256*256*256*'D');
+
+ return 0;
+} \ No newline at end of file
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/synthupdate/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthupdate/Makefile
new file mode 100644
index 000000000000..a8e1853a1290
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthupdate/Makefile
@@ -0,0 +1,12 @@
+LEVEL = ../../../make
+
+OBJC_SOURCES := main.m
+
+CFLAGS_EXTRAS += -w
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation
+
+clean::
+ rm -rf $(wildcard *.o *.d *.dSYM *.log)
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/synthupdate/TestSyntheticFilterRecompute.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthupdate/TestSyntheticFilterRecompute.py
new file mode 100644
index 000000000000..6b70a88b9f2c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthupdate/TestSyntheticFilterRecompute.py
@@ -0,0 +1,74 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import datetime
+import lldbsuite.test.lldbutil as lldbutil
+
+class SyntheticFilterRecomputingTestCase(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.m', '// Set break point at this line.')
+
+ @skipUnlessDarwin
+ def test_rdar12437442_with_run_command(self):
+ """Test that we update SBValues correctly as dynamic types change."""
+ self.build()
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 synth clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # Now run the bulk of the test
+ id_x = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable("x")
+ id_x.SetPreferDynamicValue(lldb.eDynamicCanRunTarget)
+ id_x.SetPreferSyntheticValue(True)
+
+ if self.TraceOn():
+ self.runCmd("expr --dynamic-type run-target --ptr-depth 1 -- x")
+
+ self.assertTrue(id_x.GetSummary() == '@"5 elements"', "array does not get correct summary")
+
+ self.runCmd("next")
+ self.runCmd("frame select 0")
+
+ id_x = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable("x")
+ id_x.SetPreferDynamicValue(lldb.eDynamicCanRunTarget)
+ id_x.SetPreferSyntheticValue(True)
+
+ if self.TraceOn():
+ self.runCmd("expr --dynamic-type run-target --ptr-depth 1 -- x")
+
+ self.assertTrue(id_x.GetNumChildren() == 7, "dictionary does not have 7 children")
+ id_x.SetPreferSyntheticValue(False)
+ self.assertFalse(id_x.GetNumChildren() == 7, "dictionary still looks synthetic")
+ id_x.SetPreferSyntheticValue(True)
+ self.assertTrue(id_x.GetSummary() == "7 key/value pairs", "dictionary does not get correct summary")
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/synthupdate/main.m b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthupdate/main.m
new file mode 100644
index 000000000000..a7e94d29d469
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthupdate/main.m
@@ -0,0 +1,25 @@
+//===-- main.m ------------------------------------------------*- ObjC -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#import <Foundation/Foundation.h>
+
+int main (int argc, const char * argv[])
+{
+
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+ NSArray* foo = [NSArray arrayWithObjects:@1,@2,@3,@4,@5, nil];
+ NSDictionary *bar = @{@1 : @"one",@2 : @"two", @3 : @"three", @4 : @"four", @5 : @"five", @6 : @"six", @7 : @"seven"};
+ id x = foo;
+ x = bar; // Set break point at this line.
+
+ [pool drain];
+ return 0;
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/typedef_array/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/typedef_array/Makefile
new file mode 100644
index 000000000000..3e2b0187b954
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/typedef_array/Makefile
@@ -0,0 +1,4 @@
+LEVEL = ../../../make
+CXX_SOURCES := main.cpp
+CXXFLAGS += -std=c++11
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/typedef_array/TestTypedefArray.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/typedef_array/TestTypedefArray.py
new file mode 100644
index 000000000000..30b66e062827
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/typedef_array/TestTypedefArray.py
@@ -0,0 +1,4 @@
+import lldbsuite.test.lldbinline as lldbinline
+import lldbsuite.test.lldbtest as lldbtest
+
+lldbinline.MakeInlineTest(__file__, globals(), [lldbtest.expectedFailureGcc])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/typedef_array/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/typedef_array/main.cpp
new file mode 100644
index 000000000000..649c1e09a6a5
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/typedef_array/main.cpp
@@ -0,0 +1,14 @@
+//===-- main.cpp --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+typedef int Foo;
+
+int main() {
+ Foo array[3] = {1,2,3};
+ return 0; //% self.expect("frame variable array --show-types --", substrs = ['(Foo [3]) array = {','(Foo) [0] = 1','(Foo) [1] = 2','(Foo) [2] = 3'])
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/user-format-vs-summary/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/user-format-vs-summary/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/user-format-vs-summary/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/user-format-vs-summary/TestUserFormatVsSummary.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/user-format-vs-summary/TestUserFormatVsSummary.py
new file mode 100644
index 000000000000..dba2816d2647
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/user-format-vs-summary/TestUserFormatVsSummary.py
@@ -0,0 +1,59 @@
+"""
+Test that the user can input a format but it will not prevail over summary format's choices.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class UserFormatVSSummaryTestCase(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.')
+
+ def test_with_run_command(self):
+ """Test that the user can input a format but it will not prevail over summary format's choices."""
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ self.expect("frame variable p1", substrs = ['(Pair) p1 = (x = 3, y = -3)']);
+
+ # 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)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.runCmd('type summary add Pair -s "x=${var.x%d},y=${var.y%u}"')
+
+ self.expect("frame variable p1", substrs = ['(Pair) p1 = x=3,y=4294967293']);
+ self.expect("frame variable -f x p1", substrs = ['(Pair) p1 = x=0x00000003,y=0xfffffffd'], matching=False);
+ self.expect("frame variable -f d p1", substrs = ['(Pair) p1 = x=3,y=-3'], matching=False);
+ self.expect("frame variable p1", substrs = ['(Pair) p1 = x=3,y=4294967293']);
+
+ self.runCmd('type summary add Pair -s "x=${var.x%x},y=${var.y%u}"')
+
+ self.expect("frame variable p1", substrs = ['(Pair) p1 = x=0x00000003,y=4294967293']);
+ self.expect("frame variable -f d p1", substrs = ['(Pair) p1 = x=3,y=-3'],matching=False);
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/user-format-vs-summary/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/user-format-vs-summary/main.cpp
new file mode 100644
index 000000000000..41c934aec0c3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/user-format-vs-summary/main.cpp
@@ -0,0 +1,20 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+struct Pair {
+ int x;
+ int y;
+
+ Pair(int _x, int _y) : x(_x), y(_y) {}
+};
+
+int main() {
+ Pair p1(3,-3);
+ return p1.x + p1.y; // Set break point at this line.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/var-in-aggregate-misuse/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/var-in-aggregate-misuse/Makefile
new file mode 100644
index 000000000000..18c35a7d84a5
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/var-in-aggregate-misuse/Makefile
@@ -0,0 +1,11 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+# Workaround for llvm.org/pr16214: clang doesn't emit structure definition DWARF
+# information without the flag below.
+ifneq (,$(findstring clang,$(CC)))
+ CFLAGS_EXTRAS += -fno-limit-debug-info
+endif
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/var-in-aggregate-misuse/TestVarInAggregateMisuse.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/var-in-aggregate-misuse/TestVarInAggregateMisuse.py
new file mode 100644
index 000000000000..5899469651d3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/var-in-aggregate-misuse/TestVarInAggregateMisuse.py
@@ -0,0 +1,74 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class VarInAggregateMisuseTestCase(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.')
+
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 summary clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.runCmd("type summary add --summary-string \"SUMMARY SUCCESS ${var}\" Summarize")
+
+ self.expect('frame variable mine_ptr',
+ substrs = ['SUMMARY SUCCESS summarize_ptr_t @ '])
+
+ self.expect('frame variable *mine_ptr',
+ substrs = ['SUMMARY SUCCESS summarize_t @'])
+
+ self.runCmd("type summary add --summary-string \"SUMMARY SUCCESS ${var.first}\" Summarize")
+
+ self.expect('frame variable mine_ptr',
+ substrs = ['SUMMARY SUCCESS 10'])
+
+ self.expect('frame variable *mine_ptr',
+ substrs = ['SUMMARY SUCCESS 10'])
+
+ self.runCmd("type summary add --summary-string \"${var}\" Summarize")
+ self.runCmd("type summary add --summary-string \"${var}\" -e TwoSummarizes")
+
+ self.expect('frame variable',
+ substrs = ['(TwoSummarizes) twos = TwoSummarizes @ ',
+ 'first = summarize_t @ ',
+ 'second = summarize_t @ '])
+
+ self.runCmd("type summary add --summary-string \"SUMMARY SUCCESS ${var.first}\" Summarize")
+ self.expect('frame variable',
+ substrs = ['(TwoSummarizes) twos = TwoSummarizes @ ',
+ 'first = SUMMARY SUCCESS 1',
+ 'second = SUMMARY SUCCESS 3'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/var-in-aggregate-misuse/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/var-in-aggregate-misuse/main.cpp
new file mode 100644
index 000000000000..72c7e138205d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/var-in-aggregate-misuse/main.cpp
@@ -0,0 +1,41 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+struct Summarize
+{
+ int first;
+ int second;
+};
+
+typedef struct Summarize summarize_t;
+typedef summarize_t *summarize_ptr_t;
+
+summarize_t global_mine = {30, 40};
+
+struct TwoSummarizes
+{
+ summarize_t first;
+ summarize_t second;
+};
+
+int
+main()
+{
+ summarize_t mine = {10, 20};
+ summarize_ptr_t mine_ptr = &mine;
+
+ TwoSummarizes twos = { {1,2}, {3,4} };
+
+ printf ("Summarize: first: %d second: %d and address: 0x%p\n", mine.first, mine.second, mine_ptr); // Set break point at this line.
+ printf ("Global summarize: first: %d second: %d.\n", global_mine.first, global_mine.second);
+ return 0;
+}
+
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/TestDataFormatterVarScriptFormatting.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/TestDataFormatterVarScriptFormatting.py
new file mode 100644
index 000000000000..4d060c332f93
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/TestDataFormatterVarScriptFormatting.py
@@ -0,0 +1,56 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+import os.path
+
+class PythonSynthDataFormatterTestCase(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 breakpoint here.')
+
+ @skipIfFreeBSD # llvm.org/pr20545 bogus output confuses buildbot parser
+ def test_with_run_command(self):
+ """Test using Python synthetic children provider."""
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.runCmd("command script import helperfunc.py")
+ self.runCmd('type summary add -x "^something<.*>$" -s "T is a ${script.var:helperfunc.f}"')
+
+ self.expect("frame variable x", substrs = ['T is a non-pointer type']);
+
+ self.expect("frame variable y", substrs = ['T is a pointer type']);
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/helperfunc.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/helperfunc.py
new file mode 100644
index 000000000000..01562c5baa8d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/helperfunc.py
@@ -0,0 +1,5 @@
+import lldb
+
+def f(value,d):
+ return "pointer type" if value.GetType().GetTemplateArgumentType(0).IsPointerType() else "non-pointer type"
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/main.cpp
new file mode 100644
index 000000000000..4dc94af3566c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/main.cpp
@@ -0,0 +1,8 @@
+template <typename T>
+struct something {};
+
+int main() {
+ something<int> x;
+ something<void*> y;
+ return 0; // Set breakpoint here.
+} \ No newline at end of file
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/vector-types/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/vector-types/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/vector-types/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/vector-types/TestVectorTypesFormatting.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/vector-types/TestVectorTypesFormatting.py
new file mode 100644
index 000000000000..05899a24ad22
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/vector-types/TestVectorTypesFormatting.py
@@ -0,0 +1,73 @@
+"""
+Check that vector types format properly
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class VectorTypesFormattingTestCase(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', '// break here')
+
+ # rdar://problem/14035604
+ @skipIf(compiler='gcc') # gcc don't have ext_vector_type extension
+ def test_with_run_command(self):
+ """Check that vector types format properly"""
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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():
+ pass
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ pass # my code never fails
+
+ v = self.frame().FindVariable("v")
+ v.SetPreferSyntheticValue(True)
+ v.SetFormat(lldb.eFormatVectorOfFloat32)
+
+ if self.TraceOn(): print(v)
+
+ self.assertTrue(v.GetNumChildren() == 4, "v as float32[] has 4 children")
+ self.assertTrue(v.GetChildAtIndex(0).GetData().float[0] == 1.25, "child 0 == 1.25")
+ self.assertTrue(v.GetChildAtIndex(1).GetData().float[0] == 1.25, "child 1 == 1.25")
+ self.assertTrue(v.GetChildAtIndex(2).GetData().float[0] == 2.50, "child 2 == 2.50")
+ self.assertTrue(v.GetChildAtIndex(3).GetData().float[0] == 2.50, "child 3 == 2.50")
+
+ self.expect("expr -f int16_t[] -- v", substrs=['(0, 16288, 0, 16288, 0, 16416, 0, 16416)'])
+ self.expect("expr -f uint128_t[] -- v", substrs=['(85236745249553456609335044694184296448)'])
+ self.expect("expr -f float32[] -- v", substrs=['(1.25, 1.25, 2.5, 2.5)'])
+
+ oldValue = v.GetChildAtIndex(0).GetValue()
+ v.SetFormat(lldb.eFormatHex)
+ newValue = v.GetChildAtIndex(0).GetValue()
+ self.assertFalse(oldValue == newValue, "values did not change along with format")
+
+ v.SetFormat(lldb.eFormatVectorOfFloat32)
+ oldValueAgain = v.GetChildAtIndex(0).GetValue()
+ self.assertTrue(oldValue == oldValueAgain, "same format but different values")
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/vector-types/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/vector-types/main.cpp
new file mode 100644
index 000000000000..b9d67ad20ab2
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/vector-types/main.cpp
@@ -0,0 +1,17 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef unsigned char vec __attribute__((ext_vector_type(16)));
+
+int main() {
+ float4 f4 = {1.25, 1.25, 2.50, 2.50};
+ vec v = (vec)f4;
+ return 0; // break here
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/dead-strip/Makefile b/packages/Python/lldbsuite/test/functionalities/dead-strip/Makefile
new file mode 100644
index 000000000000..c60ecd414635
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/dead-strip/Makefile
@@ -0,0 +1,18 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+ifeq "$(OS)" ""
+ OS = $(shell uname -s)
+endif
+
+ifeq "$(OS)" "Darwin"
+ LDFLAGS = $(CFLAGS) -Xlinker -dead_strip
+else
+ CFLAGS += -fdata-sections -ffunction-sections
+ LDFLAGS = $(CFLAGS) -Wl,--gc-sections
+endif
+
+MAKE_DSYM := NO
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/dead-strip/TestDeadStrip.py b/packages/Python/lldbsuite/test/functionalities/dead-strip/TestDeadStrip.py
new file mode 100644
index 000000000000..f10736bd75c0
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/dead-strip/TestDeadStrip.py
@@ -0,0 +1,58 @@
+"""
+Test that breakpoint works correctly in the presence of dead-code stripping.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class DeadStripTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureDwo("llvm.org/pr25087")
+ @skipIfFreeBSD # The -dead_strip linker option isn't supported on FreeBSD versions of ld.
+ def test(self):
+ """Test breakpoint works correctly with dead-code stripping."""
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Break by function name f1 (live code).
+ lldbutil.run_break_set_by_symbol (self, "f1", num_expected_locations=1, module_name="a.out")
+
+ # Break by function name f2 (dead code).
+ lldbutil.run_break_set_by_symbol (self, "f2", num_expected_locations=0, module_name="a.out")
+
+ # Break by function name f3 (live code).
+ lldbutil.run_break_set_by_symbol (self, "f3", num_expected_locations=1, module_name="a.out")
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint (breakpoint #1).
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'a.out`f1',
+ 'stop reason = breakpoint'])
+
+ # The breakpoint should have a hit count of 1.
+ self.expect("breakpoint list -f 1", BREAKPOINT_HIT_ONCE,
+ substrs = [' resolved, hit count = 1'])
+
+ self.runCmd("continue")
+
+ # The stop reason of the thread should be breakpoint (breakpoint #3).
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'a.out`f3',
+ 'stop reason = breakpoint'])
+
+ # The breakpoint should have a hit count of 1.
+ self.expect("breakpoint list -f 3", BREAKPOINT_HIT_ONCE,
+ substrs = [' resolved, hit count = 1'])
diff --git a/packages/Python/lldbsuite/test/functionalities/dead-strip/cmds.txt b/packages/Python/lldbsuite/test/functionalities/dead-strip/cmds.txt
new file mode 100644
index 000000000000..f6fd04502888
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/dead-strip/cmds.txt
@@ -0,0 +1,4 @@
+b main.c:21
+b main.c:41
+lines -shlib a.out main.c
+c
diff --git a/packages/Python/lldbsuite/test/functionalities/dead-strip/main.c b/packages/Python/lldbsuite/test/functionalities/dead-strip/main.c
new file mode 100644
index 000000000000..fe8e7c7de582
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/dead-strip/main.c
@@ -0,0 +1,53 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+
+int f1 (char *s);
+int f2 (char *s);
+int f3 (char *s);
+
+
+// We want f1 to start on line 20
+int f1 (char *s)
+{
+ return printf("f1: %s\n", s);
+}
+
+
+
+
+
+// We want f2 to start on line 30, this should get stripped
+int f2 (char *s)
+{
+ return printf("f2: %s\n", s);
+}
+
+
+
+
+
+// We want f3 to start on line 40
+int f3 (char *s)
+{
+ return printf("f3: %s\n", s);
+}
+
+
+
+
+
+// We want main to start on line 50
+int main (int argc, const char * argv[])
+{
+ f1("carp");
+ f3("dong");
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/disassembly/Makefile b/packages/Python/lldbsuite/test/functionalities/disassembly/Makefile
new file mode 100644
index 000000000000..8a7102e347af
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/disassembly/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/disassembly/TestDisassembleBreakpoint.py b/packages/Python/lldbsuite/test/functionalities/disassembly/TestDisassembleBreakpoint.py
new file mode 100644
index 000000000000..df2308de7605
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/disassembly/TestDisassembleBreakpoint.py
@@ -0,0 +1,54 @@
+"""
+Test some lldb command abbreviations.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class DisassemblyTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureWindows # Function name prints fully demangled instead of name-only
+ def test(self):
+ self.build()
+ exe = os.path.join (os.getcwd(), "a.out")
+ self.expect("file " + exe,
+ patterns = [ "Current executable set to .*a.out.*" ])
+
+ match_object = lldbutil.run_break_set_command (self, "br s -n sum")
+ lldbutil.check_breakpoint_result (self, match_object, symbol_name='sum', symbol_match_exact=False, num_locations=1)
+
+ self.expect("run",
+ patterns = [ "Process .* launched: "])
+
+ self.runCmd("dis -f")
+ disassembly = self.res.GetOutput()
+
+ # ARCH, if not specified, defaults to x86_64.
+ arch = self.getArchitecture()
+ if arch in ["", 'x86_64', 'i386', 'i686']:
+ breakpoint_opcodes = ["int3"]
+ instructions = [' mov', ' addl ', 'ret']
+ elif arch in ["arm", "aarch64"]:
+ breakpoint_opcodes = ["brk", "udf"]
+ instructions = [' add ', ' ldr ', ' str ']
+ elif re.match("mips" , arch):
+ breakpoint_opcodes = ["break"]
+ instructions = ['lw', 'sw', 'jr']
+ else:
+ # TODO please add your arch here
+ self.fail('unimplemented for arch = "{arch}"'.format(arch=self.getArchitecture()))
+
+ # make sure that the software breakpoint has been removed
+ for op in breakpoint_opcodes:
+ self.assertFalse(op in disassembly)
+
+ # make sure a few reasonable assembly instructions are here
+ self.expect(disassembly, exe=False, startstr = "a.out`sum", substrs = instructions)
diff --git a/packages/Python/lldbsuite/test/functionalities/disassembly/main.cpp b/packages/Python/lldbsuite/test/functionalities/disassembly/main.cpp
new file mode 100644
index 000000000000..8813647f6b72
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/disassembly/main.cpp
@@ -0,0 +1,28 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int
+sum (int a, int b)
+{
+ int result = a + b;
+ return result;
+}
+
+int
+main(int argc, char const *argv[])
+{
+
+ int array[3];
+
+ array[0] = sum (1238, 78392);
+ array[1] = sum (379265, 23674);
+ array[2] = sum (872934, 234);
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/dynamic_value_child_count/Makefile b/packages/Python/lldbsuite/test/functionalities/dynamic_value_child_count/Makefile
new file mode 100644
index 000000000000..ceb406ee2eab
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/dynamic_value_child_count/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := pass-to-base.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/dynamic_value_child_count/TestDynamicValueChildCount.py b/packages/Python/lldbsuite/test/functionalities/dynamic_value_child_count/TestDynamicValueChildCount.py
new file mode 100644
index 000000000000..ac039990b5bf
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/dynamic_value_child_count/TestDynamicValueChildCount.py
@@ -0,0 +1,78 @@
+"""
+Test that dynamic values update their child count correctly
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import re
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+class DynamicValueChildCountTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ # Find the line number to break for main.c.
+
+ self.main_third_call_line = line_number('pass-to-base.cpp',
+ '// Break here and check b has 0 children')
+ self.main_fourth_call_line = line_number('pass-to-base.cpp',
+ '// Break here and check b still has 0 children')
+ self.main_fifth_call_line = line_number('pass-to-base.cpp',
+ '// Break here and check b has one child now')
+ self.main_sixth_call_line = line_number('pass-to-base.cpp',
+ '// Break here and check b has 0 children again')
+
+ @expectedFailureLinux("llvm.org/pr23039")
+ @expectedFailureFreeBSD("llvm.org/pr19311") # continue at a breakpoint does not work
+ @expectedFailureWindows("llvm.org/pr24663")
+ @expectedFailurei386("to be figured out")
+ @add_test_categories(['pyapi'])
+ def test_get_dynamic_vals(self):
+ """Test fetching C++ dynamic values from pointers & references."""
+ """Get argument vals for the call stack when stopped on a breakpoint."""
+ self.build(dictionary=self.getBuildFlags())
+ 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:
+
+ third_call_bpt = target.BreakpointCreateByLocation('pass-to-base.cpp', self.main_third_call_line)
+ self.assertTrue(third_call_bpt,
+ VALID_BREAKPOINT)
+ fourth_call_bpt = target.BreakpointCreateByLocation('pass-to-base.cpp', self.main_fourth_call_line)
+ self.assertTrue(fourth_call_bpt,
+ VALID_BREAKPOINT)
+ fifth_call_bpt = target.BreakpointCreateByLocation('pass-to-base.cpp', self.main_fifth_call_line)
+ self.assertTrue(fifth_call_bpt,
+ VALID_BREAKPOINT)
+ sixth_call_bpt = target.BreakpointCreateByLocation('pass-to-base.cpp', self.main_sixth_call_line)
+ self.assertTrue(sixth_call_bpt,
+ VALID_BREAKPOINT)
+
+ # Now launch the process, and do not stop at the entry point.
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ self.assertTrue(process.GetState() == lldb.eStateStopped,
+ PROCESS_STOPPED)
+
+ b = self.frame().FindVariable("b").GetDynamicValue(lldb.eDynamicCanRunTarget)
+ self.assertTrue(b.GetNumChildren() == 0, "b has 0 children")
+ self.runCmd("continue")
+ self.assertTrue(b.GetNumChildren() == 0, "b still has 0 children")
+ self.runCmd("continue")
+ self.assertTrue(b.GetNumChildren() != 0, "b now has 1 child")
+ self.runCmd("continue")
+ self.assertTrue(b.GetNumChildren() == 0, "b didn't go back to 0 children")
diff --git a/packages/Python/lldbsuite/test/functionalities/dynamic_value_child_count/pass-to-base.cpp b/packages/Python/lldbsuite/test/functionalities/dynamic_value_child_count/pass-to-base.cpp
new file mode 100644
index 000000000000..d9dd3529821e
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/dynamic_value_child_count/pass-to-base.cpp
@@ -0,0 +1,36 @@
+#include <stdio.h>
+#include <memory>
+
+class BaseClass
+{
+public:
+ BaseClass();
+ virtual ~BaseClass() { }
+};
+
+class DerivedClass : public BaseClass
+{
+public:
+ DerivedClass();
+ virtual ~DerivedClass() { }
+protected:
+ int mem;
+};
+
+BaseClass::BaseClass()
+{
+}
+
+DerivedClass::DerivedClass() : BaseClass()
+{
+ mem = 101;
+}
+
+int
+main (int argc, char **argv)
+{
+ BaseClass *b = nullptr; // Break here and check b has 0 children
+ b = new DerivedClass(); // Break here and check b still has 0 children
+ b = nullptr; // Break here and check b has one child now
+ return 0; // Break here and check b has 0 children again
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/Makefile b/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/Makefile
new file mode 100644
index 000000000000..0d70f2595019
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/TestConvenienceVariables.py b/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/TestConvenienceVariables.py
new file mode 100644
index 000000000000..eddaa3cc9840
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/TestConvenienceVariables.py
@@ -0,0 +1,78 @@
+"""Test convenience variables when you drop in from lldb prompt into an embedded interpreter."""
+
+from __future__ import print_function
+
+
+
+import os
+import lldb
+from lldbsuite.test.lldbtest import *
+
+class ConvenienceVariablesCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break on inside main.cpp.
+ self.line = line_number('main.c', 'Hello world.')
+
+ @skipIfFreeBSD # llvm.org/pr17228
+ @skipIfRemote
+ @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ def test_with_run_commands(self):
+ """Test convenience variables lldb.debugger, lldb.target, lldb.process, lldb.thread, and lldb.frame."""
+ self.build()
+ import pexpect
+ exe = os.path.join(os.getcwd(), "a.out")
+ prompt = "(lldb) "
+ python_prompt = ">>> "
+
+ # So that the child gets torn down after the test.
+ self.child = pexpect.spawn('%s %s %s' % (lldbtest_config.lldbExec, self.lldbOption, exe))
+ child = self.child
+ # Turn on logging for what the child sends back.
+ if self.TraceOn():
+ child.logfile_read = sys.stdout
+
+ # Set the breakpoint, run the inferior, when it breaks, issue print on
+ # the various convenience variables.
+ child.expect_exact(prompt)
+ child.sendline('breakpoint set -f main.c -l %d' % self.line)
+ child.expect_exact(prompt)
+ child.sendline('run')
+ child.expect_exact("stop reason = breakpoint 1.1")
+ child.expect_exact(prompt)
+ child.sendline('script')
+ child.expect_exact(python_prompt)
+
+ # Set a flag so that we know during teardown time, we need to exit the
+ # Python interpreter, then the lldb interpreter.
+ self.child_in_script_interpreter = True
+
+ child.sendline('print(lldb.debugger)')
+ child.expect_exact(python_prompt)
+ self.expect(child.before, exe=False,
+ patterns = ['Debugger \(instance: .*, id: \d\)'])
+
+ child.sendline('print(lldb.target)')
+ child.expect_exact(python_prompt)
+ self.expect(child.before, exe=False,
+ substrs = ['a.out'])
+
+ child.sendline('print(lldb.process)')
+ child.expect_exact(python_prompt)
+ self.expect(child.before, exe=False,
+ patterns = ['SBProcess: pid = \d+, state = stopped, threads = \d, executable = a.out'])
+
+ child.sendline('print(lldb.thread)')
+ child.expect_exact(python_prompt)
+ # Linux outputs decimal tid and 'name' instead of 'queue'
+ self.expect(child.before, exe=False,
+ patterns = ['thread #1: tid = (0x[0-9a-f]+|[0-9]+), 0x[0-9a-f]+ a\.out`main\(argc=1, argv=0x[0-9a-f]+\) \+ \d+ at main\.c:%d, (name|queue) = \'.+\', stop reason = breakpoint 1\.1' % self.line])
+
+ child.sendline('print(lldb.frame)')
+ child.expect_exact(python_prompt)
+ self.expect(child.before, exe=False,
+ patterns = ['frame #0: 0x[0-9a-f]+ a\.out`main\(argc=1, argv=0x[0-9a-f]+\) \+ \d+ at main\.c:%d' % self.line])
diff --git a/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/main.c b/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/main.c
new file mode 100644
index 000000000000..277aa54a4eea
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/main.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main(int argc, char const *argv[]) {
+ printf("Hello world.\n");
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/exec/Makefile b/packages/Python/lldbsuite/test/functionalities/exec/Makefile
new file mode 100644
index 000000000000..8a7102e347af
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/exec/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py b/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py
new file mode 100644
index 000000000000..9321a308a83c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py
@@ -0,0 +1,85 @@
+"""
+Test some lldb command abbreviations.
+"""
+from __future__ import print_function
+
+
+
+import lldb
+import os
+import time
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+import lldbsuite.support.seven as seven
+
+def execute_command (command):
+ #print('%% %s' % (command))
+ (exit_status, output) = seven.get_command_status_output(command)
+ #if output:
+ # print(output)
+ #print('status = %u' % (exit_status))
+ return exit_status
+
+class ExecTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipUnlessDarwin
+ def test(self):
+ if self.getArchitecture() == 'x86_64':
+ source = os.path.join (os.getcwd(), "main.cpp")
+ o_file = os.path.join (os.getcwd(), "main.o")
+ execute_command ("'%s' -g -O0 -arch i386 -arch x86_64 '%s' -c -o '%s'" % (os.environ["CC"], source, o_file))
+ execute_command ("'%s' -g -O0 -arch i386 -arch x86_64 '%s'" % (os.environ["CC"], o_file))
+ if self.debug_info != "dsym":
+ dsym_path = os.path.join (os.getcwd(), "a.out.dSYM")
+ execute_command ("rm -rf '%s'" % (dsym_path))
+ else:
+ self.build()
+
+ exe = os.path.join (os.getcwd(), "a.out")
+
+ # Create the target
+ target = self.dbg.CreateTarget(exe)
+
+ # Create any breakpoints we need
+ breakpoint = target.BreakpointCreateBySourceRegex ('Set breakpoint 1 here', lldb.SBFileSpec ("main.cpp", False))
+ self.assertTrue(breakpoint, VALID_BREAKPOINT)
+
+ # Launch the process
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ for i in range(6):
+ # The stop reason of the thread should be breakpoint.
+ self.assertTrue(process.GetState() == lldb.eStateStopped,
+ STOPPED_DUE_TO_BREAKPOINT)
+
+ thread = process.GetThreadAtIndex (0)
+
+ self.assertTrue (thread.IsValid(),
+ "Process stopped at 'main' should have a valid thread");
+
+ stop_reason = thread.GetStopReason()
+
+ self.assertTrue (stop_reason == lldb.eStopReasonBreakpoint,
+ "Thread in process stopped in 'main' should have a stop reason of eStopReasonBreakpoint");
+
+ # Run and we should stop due to exec
+ process.Continue()
+
+ self.assertTrue(process.GetState() == lldb.eStateStopped,
+ "Process should be stopped at __dyld_start")
+
+ thread = process.GetThreadAtIndex (0)
+
+ self.assertTrue (thread.IsValid(),
+ "Process stopped at exec should have a valid thread");
+
+ stop_reason = thread.GetStopReason()
+
+ self.assertTrue (stop_reason == lldb.eStopReasonExec,
+ "Thread in process stopped on exec should have a stop reason of eStopReasonExec");
+
+ # Run and we should stop at breakpoint in main after exec
+ process.Continue()
diff --git a/packages/Python/lldbsuite/test/functionalities/exec/main.cpp b/packages/Python/lldbsuite/test/functionalities/exec/main.cpp
new file mode 100644
index 000000000000..700c5dd94b28
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/exec/main.cpp
@@ -0,0 +1,94 @@
+#include <errno.h>
+#include <mach/mach.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <spawn.h>
+#include <unistd.h>
+
+static void
+exit_with_errno (int err, const char *prefix)
+{
+ if (err)
+ {
+ fprintf (stderr,
+ "%s%s",
+ prefix ? prefix : "",
+ strerror(err));
+ exit (err);
+ }
+}
+
+static pid_t
+spawn_process (const char **argv,
+ const char **envp,
+ cpu_type_t cpu_type,
+ int &err)
+{
+ pid_t pid = 0;
+
+ const posix_spawn_file_actions_t *file_actions = NULL;
+ posix_spawnattr_t attr;
+ err = posix_spawnattr_init (&attr);
+ if (err)
+ return pid;
+
+ short flags = POSIX_SPAWN_SETEXEC | POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK;
+ err = posix_spawnattr_setflags (&attr, flags);
+ if (err == 0)
+ {
+ // Use the default signal masks
+ sigset_t no_signals;
+ sigset_t all_signals;
+ sigemptyset (&no_signals);
+ sigfillset (&all_signals);
+ posix_spawnattr_setsigmask(&attr, &no_signals);
+ posix_spawnattr_setsigdefault(&attr, &all_signals);
+
+ if (cpu_type != 0)
+ {
+ size_t ocount = 0;
+ err = posix_spawnattr_setbinpref_np (&attr, 1, &cpu_type, &ocount);
+ }
+
+ if (err == 0)
+ {
+ err = posix_spawn (&pid,
+ argv[0],
+ file_actions,
+ &attr,
+ (char * const *)argv,
+ (char * const *)envp);
+ }
+
+ posix_spawnattr_destroy(&attr);
+ }
+ return pid;
+}
+
+int
+main (int argc, char const **argv)
+{
+ printf ("pid %i: Pointer size is %zu.\n", getpid(), sizeof(void *));
+ int err = 0; // Set breakpoint 1 here
+#if defined (__x86_64__)
+ if (sizeof(void *) == 8)
+ {
+ spawn_process (argv, NULL, CPU_TYPE_I386, err);
+ if (err)
+ exit_with_errno (err, "posix_spawn i386 error");
+ }
+ else
+ {
+ spawn_process (argv, NULL, CPU_TYPE_X86_64, err);
+ if (err)
+ exit_with_errno (err, "posix_spawn x86_64 error");
+ }
+#else
+ spawn_process (argv, NULL, 0, err);
+ if (err)
+ exit_with_errno (err, "posix_spawn x86_64 error");
+#endif
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/expr-doesnt-deadlock/.categories b/packages/Python/lldbsuite/test/functionalities/expr-doesnt-deadlock/.categories
new file mode 100644
index 000000000000..897e40a99dda
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/expr-doesnt-deadlock/.categories
@@ -0,0 +1 @@
+expression
diff --git a/packages/Python/lldbsuite/test/functionalities/expr-doesnt-deadlock/Makefile b/packages/Python/lldbsuite/test/functionalities/expr-doesnt-deadlock/Makefile
new file mode 100644
index 000000000000..a10791d58907
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/expr-doesnt-deadlock/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../make
+
+C_SOURCES := locking.c
+ENABLE_THREADS := YES
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/expr-doesnt-deadlock/TestExprDoesntBlock.py b/packages/Python/lldbsuite/test/functionalities/expr-doesnt-deadlock/TestExprDoesntBlock.py
new file mode 100644
index 000000000000..a54b45822a6a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/expr-doesnt-deadlock/TestExprDoesntBlock.py
@@ -0,0 +1,57 @@
+"""
+Test that expr will time out and allow other threads to run if it blocks.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import re
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+class ExprDoesntDeadlockTestCase(TestBase):
+
+ def getCategories(self):
+ return ['basic_process']
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureFreeBSD('llvm.org/pr17946')
+ @expectedFlakeyLinux # failed 1/365 test runs, line 61, thread.IsValid()
+ @expectedFailureWindows # Windows doesn't have pthreads, need to port this test.
+ def test_with_run_command(self):
+ """Test that expr will time out and allow other threads to run if it blocks."""
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Now create a breakpoint at source line before call_me_to_get_lock gets called.
+
+ main_file_spec = lldb.SBFileSpec ("locking.c")
+ breakpoint = target.BreakpointCreateBySourceRegex('Break here', main_file_spec)
+ if self.TraceOn():
+ print("breakpoint:", breakpoint)
+ self.assertTrue(breakpoint and
+ breakpoint.GetNumLocations() == 1,
+ VALID_BREAKPOINT)
+
+ # Now launch the process, and do not stop at entry point.
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # Frame #0 should be on self.line1 and the break condition should hold.
+ from lldbsuite.test.lldbutil import get_stopped_thread
+ thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition")
+
+ frame0 = thread.GetFrameAtIndex(0)
+
+ var = frame0.EvaluateExpression ("call_me_to_get_lock()")
+ self.assertTrue (var.IsValid())
+ self.assertTrue (var.GetValueAsSigned (0) == 567)
diff --git a/packages/Python/lldbsuite/test/functionalities/expr-doesnt-deadlock/locking.c b/packages/Python/lldbsuite/test/functionalities/expr-doesnt-deadlock/locking.c
new file mode 100644
index 000000000000..fae9979611d5
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/expr-doesnt-deadlock/locking.c
@@ -0,0 +1,80 @@
+#include <pthread.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+
+pthread_mutex_t contended_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+pthread_mutex_t control_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t control_condition;
+
+pthread_mutex_t thread_started_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t thread_started_condition;
+
+// This function runs in a thread. The locking dance is to make sure that
+// by the time the main thread reaches the pthread_join below, this thread
+// has for sure acquired the contended_mutex. So then the call_me_to_get_lock
+// function will block trying to get the mutex, and only succeed once it
+// signals this thread, then lets it run to wake up from the cond_wait and
+// release the mutex.
+
+void *
+lock_acquirer_1 (void *input)
+{
+ pthread_mutex_lock (&contended_mutex);
+
+ // Grab this mutex, that will ensure that the main thread
+ // is in its cond_wait for it (since that's when it drops the mutex.
+
+ pthread_mutex_lock (&thread_started_mutex);
+ pthread_mutex_unlock(&thread_started_mutex);
+
+ // Now signal the main thread that it can continue, we have the contended lock
+ // so the call to call_me_to_get_lock won't make any progress till this
+ // thread gets a chance to run.
+
+ pthread_mutex_lock (&control_mutex);
+
+ pthread_cond_signal (&thread_started_condition);
+
+ pthread_cond_wait (&control_condition, &control_mutex);
+
+ pthread_mutex_unlock (&contended_mutex);
+ return NULL;
+}
+
+int
+call_me_to_get_lock ()
+{
+ pthread_cond_signal (&control_condition);
+ pthread_mutex_lock (&contended_mutex);
+ return 567;
+}
+
+int main ()
+{
+ pthread_t thread_1;
+
+ pthread_cond_init (&control_condition, NULL);
+ pthread_cond_init (&thread_started_condition, NULL);
+
+ pthread_mutex_lock (&thread_started_mutex);
+
+ pthread_create (&thread_1, NULL, lock_acquirer_1, NULL);
+
+ pthread_cond_wait (&thread_started_condition, &thread_started_mutex);
+
+ pthread_mutex_lock (&control_mutex);
+ pthread_mutex_unlock (&control_mutex);
+
+ // Break here. At this point the other thread will have the contended_mutex,
+ // and be sitting in its cond_wait for the control condition. So there is
+ // no way that our by-hand calling of call_me_to_get_lock will proceed
+ // without running the first thread at least somewhat.
+
+ call_me_to_get_lock();
+ pthread_join (thread_1, NULL);
+
+ return 0;
+
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/fat_archives/Makefile b/packages/Python/lldbsuite/test/functionalities/fat_archives/Makefile
new file mode 100644
index 000000000000..e1832fdefbee
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/fat_archives/Makefile
@@ -0,0 +1,14 @@
+all: clean
+ $(CC) -arch i386 -g -c a.c
+ ar -q liba-i386.a a.o
+ ranlib liba-i386.a
+ $(CC) -arch x86_64 -g -c a.c
+ ar -q liba-x86_64.a a.o
+ ranlib liba-x86_64.a
+ lipo -create -output liba.a liba-i386.a liba-x86_64.a
+ $(CC) -g -c main.c
+ $(CC) -o a.out main.o -L. -la
+
+clean:
+ rm -rf a.o a.out liba-i386.a liba-x86_64.a liba.a $(wildcard *un~ .*un~ main.o *.pyc)
+
diff --git a/packages/Python/lldbsuite/test/functionalities/fat_archives/TestFatArchives.py b/packages/Python/lldbsuite/test/functionalities/fat_archives/TestFatArchives.py
new file mode 100644
index 000000000000..19a2dba2109a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/fat_archives/TestFatArchives.py
@@ -0,0 +1,58 @@
+"""
+Test some lldb command abbreviations.
+"""
+from __future__ import print_function
+
+
+
+import lldb
+import os
+import time
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+import lldbsuite.support.seven as seven
+
+def execute_command (command):
+ # print('%% %s' % (command))
+ (exit_status, output) = seven.get_command_status_output(command)
+ # if output:
+ # print(output)
+ # print('status = %u' % (exit_status))
+ return exit_status
+
+class FatArchiveTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipUnlessDarwin
+ def test (self):
+ if self.getArchitecture() == 'x86_64':
+ execute_command ("make CC='%s'" % (os.environ["CC"]))
+ self.main ()
+ else:
+ self.skipTest("This test requires x86_64 as the architecture for the inferior")
+
+ def main (self):
+ '''This test compiles a quick example by making a fat file (universal) full of
+ skinny .o files and makes sure we can use them to resolve breakpoints when doing
+ DWARF in .o file debugging. The only thing this test needs to do is to compile and
+ set a breakpoint in the target and verify any breakpoint locations have valid debug
+ info for the function, and source file and line.'''
+ exe = os.path.join (os.getcwd(), "a.out")
+
+ # Create the target
+ target = self.dbg.CreateTarget(exe)
+
+ # Create a breakpoint by name
+ breakpoint = target.BreakpointCreateByName ('foo', exe)
+ self.assertTrue(breakpoint, VALID_BREAKPOINT)
+
+ # Make sure the breakpoint resolves to a function, file and line
+ for bp_loc in breakpoint:
+ # Get a section offset address (lldb.SBAddress) from the breakpoint location
+ bp_loc_addr = bp_loc.GetAddress()
+ line_entry = bp_loc_addr.GetLineEntry()
+ function = bp_loc_addr.GetFunction()
+ self.assertTrue(function.IsValid(), "Verify breakpoint in fat BSD archive has valid function debug info")
+ self.assertTrue(line_entry.GetFileSpec(), "Verify breakpoint in fat BSD archive has source file information")
+ self.assertTrue(line_entry.GetLine() != 0, "Verify breakpoint in fat BSD archive has source line information")
diff --git a/packages/Python/lldbsuite/test/functionalities/fat_archives/a.c b/packages/Python/lldbsuite/test/functionalities/fat_archives/a.c
new file mode 100644
index 000000000000..c100f9a2c075
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/fat_archives/a.c
@@ -0,0 +1,4 @@
+int foo ()
+{
+ return 5;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/fat_archives/a.h b/packages/Python/lldbsuite/test/functionalities/fat_archives/a.h
new file mode 100644
index 000000000000..a4536647cfc9
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/fat_archives/a.h
@@ -0,0 +1 @@
+int foo ();
diff --git a/packages/Python/lldbsuite/test/functionalities/fat_archives/main.c b/packages/Python/lldbsuite/test/functionalities/fat_archives/main.c
new file mode 100644
index 000000000000..328319d4fb8f
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/fat_archives/main.c
@@ -0,0 +1,6 @@
+#include "a.h"
+#include <stdio.h>
+int main()
+{
+ printf ("%d\n", foo());
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/format/Makefile b/packages/Python/lldbsuite/test/functionalities/format/Makefile
new file mode 100644
index 000000000000..0d70f2595019
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/format/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/format/TestFormats.py b/packages/Python/lldbsuite/test/functionalities/format/TestFormats.py
new file mode 100644
index 000000000000..cc962150bc8c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/format/TestFormats.py
@@ -0,0 +1,59 @@
+"""
+Test the command history mechanism
+"""
+
+from __future__ import print_function
+
+
+
+import os
+import lldb
+from lldbsuite.test.lldbtest import *
+
+class TestFormats(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureHostWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ def test_formats(self):
+ """Test format string functionality."""
+ self.build()
+ import pexpect
+ prompt = "(lldb) "
+ child = pexpect.spawn('%s %s -x -o "b main" -o r a.out' % (lldbtest_config.lldbExec, self.lldbOption))
+ # Turn on logging for what the child sends back.
+ if self.TraceOn():
+ child.logfile_read = sys.stdout
+ # So that the spawned lldb session gets shutdown durng teardown.
+ self.child = child
+
+ # Substitute 'Help!' for 'help' using the 'commands regex' mechanism.
+ child.expect_exact(prompt + 'target create "a.out"')
+ child.expect_exact(prompt + 'b main')
+ child.expect_exact(prompt + 'r')
+ child.expect_exact(prompt)
+ child.sendline()
+ # child.expect_exact(prompt + "target create")
+ #
+ # child.sendline("command regex 'Help__'")
+ # child.expect_exact(regex_prompt)
+ # child.sendline('s/^$/help/')
+ # child.expect_exact(regex_prompt1)
+ # child.sendline('')
+ # child.expect_exact(prompt)
+ # # Help!
+ # child.sendline('Help__')
+ # # If we see the familiar 'help' output, the test is done.
+ # child.expect('Debugger commands:')
+ # # Try and incorrectly remove "Help__" using "command unalias" and verify we fail
+ # child.sendline('command unalias Help__')
+ # child.expect_exact("error: 'Help__' is not an alias, it is a debugger command which can be removed using the 'command delete' command")
+ # child.expect_exact(prompt)
+ #
+ # # Delete the regex command using "command delete"
+ # child.sendline('command delete Help__')
+ # child.expect_exact(prompt)
+ # # Verify the command was removed
+ # child.sendline('Help__')
+ # child.expect_exact("error: 'Help__' is not a valid command")
+ # child.expect_exact(prompt)
diff --git a/packages/Python/lldbsuite/test/functionalities/format/main.c b/packages/Python/lldbsuite/test/functionalities/format/main.c
new file mode 100644
index 000000000000..1dfc8ef1f3aa
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/format/main.c
@@ -0,0 +1,15 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+int main (int argc, char const *argv[])
+{
+ printf("testing\n");
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/inferior-assert/Makefile b/packages/Python/lldbsuite/test/functionalities/inferior-assert/Makefile
new file mode 100644
index 000000000000..0d70f2595019
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/inferior-assert/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/inferior-assert/TestInferiorAssert.py b/packages/Python/lldbsuite/test/functionalities/inferior-assert/TestInferiorAssert.py
new file mode 100644
index 000000000000..69e977e6343f
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/inferior-assert/TestInferiorAssert.py
@@ -0,0 +1,253 @@
+"""Test that lldb functions correctly after the inferior has asserted."""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+import lldbsuite.test.lldbplatformutil as lldbplatformutil
+from lldbsuite.test.lldbtest import *
+
+class AssertingInferiorTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
+ @expectedFailurei386("llvm.org/pr25338")
+ def test_inferior_asserting(self):
+ """Test that lldb reliably catches the inferior asserting (command)."""
+ self.build()
+ self.inferior_asserting()
+
+ @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
+ @expectedFailureAndroid(api_levels=list(range(16 + 1))) # b.android.com/179836
+ def test_inferior_asserting_register(self):
+ """Test that lldb reliably reads registers from the inferior after asserting (command)."""
+ self.build()
+ self.inferior_asserting_registers()
+
+ @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
+ @expectedFailurei386("llvm.org/pr25338")
+ def test_inferior_asserting_disassemble(self):
+ """Test that lldb reliably disassembles frames after asserting (command)."""
+ self.build()
+ self.inferior_asserting_disassemble()
+
+ @add_test_categories(['pyapi'])
+ @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
+ def test_inferior_asserting_python(self):
+ """Test that lldb reliably catches the inferior asserting (Python API)."""
+ self.build()
+ self.inferior_asserting_python()
+
+ @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
+ @expectedFailurei386("llvm.org/pr25338")
+ def test_inferior_asserting_expr(self):
+ """Test that the lldb expression interpreter can read from the inferior after asserting (command)."""
+ self.build()
+ self.inferior_asserting_expr()
+
+ @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
+ @expectedFailurei386("llvm.org/pr25338")
+ def test_inferior_asserting_step(self):
+ """Test that lldb functions correctly after stepping through a call to assert()."""
+ self.build()
+ self.inferior_asserting_step()
+
+ def set_breakpoint(self, line):
+ lldbutil.run_break_set_by_file_and_line (self, "main.c", line, num_expected_locations=1, loc_exact=True)
+
+ def check_stop_reason(self):
+ if matchAndroid(api_levels=list(range(1, 16+1)))(self):
+ # On android until API-16 the abort() call ended in a sigsegv instead of in a sigabrt
+ stop_reason = 'stop reason = signal SIGSEGV'
+ else:
+ stop_reason = 'stop reason = signal SIGABRT'
+
+ # The stop reason of the thread should be an abort signal or exception.
+ self.expect("thread list", STOPPED_DUE_TO_ASSERT,
+ substrs = ['stopped',
+ stop_reason])
+
+ return stop_reason
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number of the call to assert.
+ self.line = line_number('main.c', '// Assert here.')
+
+ def inferior_asserting(self):
+ """Inferior asserts upon launching; lldb should catch the event and stop."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+ stop_reason = self.check_stop_reason()
+
+ # And it should report a backtrace that includes the assert site.
+ self.expect("thread backtrace all",
+ substrs = [stop_reason, 'main', 'argc', 'argv'])
+
+ # And it should report the correct line number.
+ self.expect("thread backtrace all",
+ substrs = [stop_reason,
+ 'main.c:%d' % self.line])
+
+ def inferior_asserting_python(self):
+ """Inferior asserts upon launching; lldb should catch the event and stop."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Now launch the process, and do not stop at entry point.
+ # Both argv and envp are null.
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ if process.GetState() != lldb.eStateStopped:
+ self.fail("Process should be in the 'stopped' state, "
+ "instead the actual state is: '%s'" %
+ lldbutil.state_type_to_str(process.GetState()))
+
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal)
+ if not thread:
+ self.fail("Fail to stop the thread upon assert")
+
+ if self.TraceOn():
+ lldbutil.print_stacktrace(thread)
+
+ def inferior_asserting_registers(self):
+ """Test that lldb can read registers after asserting."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+ self.check_stop_reason()
+
+ # lldb should be able to read from registers from the inferior after asserting.
+ lldbplatformutil.check_first_register_readable(self)
+
+ def inferior_asserting_disassemble(self):
+ """Test that lldb can disassemble frames after asserting."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Launch the process, and do not stop at the entry point.
+ target.LaunchSimple (None, None, self.get_process_working_directory())
+ self.check_stop_reason()
+
+ process = target.GetProcess()
+ self.assertTrue(process.IsValid(), "current process is valid")
+
+ thread = process.GetThreadAtIndex(0)
+ self.assertTrue(thread.IsValid(), "current thread is valid")
+
+ lastframeID = thread.GetFrameAtIndex(thread.GetNumFrames() - 1).GetFrameID()
+
+ isi386Arch = False
+ if "i386" in self.getArchitecture():
+ isi386Arch = True
+
+ # lldb should be able to disassemble frames from the inferior after asserting.
+ for frame in thread:
+ self.assertTrue(frame.IsValid(), "current frame is valid")
+
+ self.runCmd("frame select " + str(frame.GetFrameID()), RUN_SUCCEEDED)
+
+ # Don't expect the function name to be in the disassembly as the assert
+ # function might be a no-return function where the PC is past the end
+ # of the function and in the next function. We also can't back the PC up
+ # because we don't know how much to back it up by on targets with opcodes
+ # that have differing sizes
+ pc_backup_offset = 1
+ if frame.GetFrameID() == 0:
+ pc_backup_offset = 0
+ if isi386Arch == True:
+ if lastframeID == frame.GetFrameID():
+ pc_backup_offset = 0
+ self.expect("disassemble -a %s" % (frame.GetPC() - pc_backup_offset),
+ substrs = ['<+0>: '])
+
+ def check_expr_in_main(self, thread):
+ depth = thread.GetNumFrames()
+ for i in range(depth):
+ frame = thread.GetFrameAtIndex(i)
+ self.assertTrue(frame.IsValid(), "current frame is valid")
+ if self.TraceOn():
+ print("Checking if function %s is main" % frame.GetFunctionName())
+
+ if 'main' == frame.GetFunctionName():
+ frame_id = frame.GetFrameID()
+ self.runCmd("frame select " + str(frame_id), RUN_SUCCEEDED)
+ self.expect("p argc", substrs = ['(int)', ' = 1'])
+ self.expect("p hello_world", substrs = ['Hello'])
+ self.expect("p argv[0]", substrs = ['a.out'])
+ self.expect("p null_ptr", substrs = ['= 0x0'])
+ return True
+ return False
+
+ def inferior_asserting_expr(self):
+ """Test that the lldb expression interpreter can read symbols after asserting."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Launch the process, and do not stop at the entry point.
+ target.LaunchSimple (None, None, self.get_process_working_directory())
+ self.check_stop_reason()
+
+ process = target.GetProcess()
+ self.assertTrue(process.IsValid(), "current process is valid")
+
+ thread = process.GetThreadAtIndex(0)
+ self.assertTrue(thread.IsValid(), "current thread is valid")
+
+ # The lldb expression interpreter should be able to read from addresses of the inferior after a call to assert().
+ self.assertTrue(self.check_expr_in_main(thread), "cannot find 'main' in the backtrace")
+
+ def inferior_asserting_step(self):
+ """Test that lldb functions correctly after stepping through a call to assert()."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Launch the process, and do not stop at the entry point.
+ self.set_breakpoint(self.line)
+ target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['main.c:%d' % self.line,
+ 'stop reason = breakpoint'])
+
+ self.runCmd("next")
+ stop_reason = self.check_stop_reason()
+
+ # lldb should be able to read from registers from the inferior after asserting.
+ if "x86_64" in self.getArchitecture():
+ self.expect("register read rbp", substrs = ['rbp = 0x'])
+ if "i386" in self.getArchitecture():
+ self.expect("register read ebp", substrs = ['ebp = 0x'])
+
+ process = target.GetProcess()
+ self.assertTrue(process.IsValid(), "current process is valid")
+
+ thread = process.GetThreadAtIndex(0)
+ self.assertTrue(thread.IsValid(), "current thread is valid")
+
+ # The lldb expression interpreter should be able to read from addresses of the inferior after a call to assert().
+ self.assertTrue(self.check_expr_in_main(thread), "cannot find 'main' in the backtrace")
+
+ # And it should report the correct line number.
+ self.expect("thread backtrace all",
+ substrs = [stop_reason,
+ 'main.c:%d' % self.line])
diff --git a/packages/Python/lldbsuite/test/functionalities/inferior-assert/main.c b/packages/Python/lldbsuite/test/functionalities/inferior-assert/main.c
new file mode 100644
index 000000000000..6aec4c1023a9
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/inferior-assert/main.c
@@ -0,0 +1,19 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+#include <assert.h>
+
+const char *hello_world = "Hello, assertion!";
+
+int main(int argc, const char* argv[])
+{
+ int *null_ptr = 0;
+ printf("%s\n", hello_world);
+ assert(null_ptr); // Assert here.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/inferior-changed/Makefile b/packages/Python/lldbsuite/test/functionalities/inferior-changed/Makefile
new file mode 100644
index 000000000000..0d70f2595019
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/inferior-changed/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/inferior-changed/TestInferiorChanged.py b/packages/Python/lldbsuite/test/functionalities/inferior-changed/TestInferiorChanged.py
new file mode 100644
index 000000000000..830c7f69355f
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/inferior-changed/TestInferiorChanged.py
@@ -0,0 +1,80 @@
+"""Test lldb reloads the inferior after it was changed during the session."""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test import configuration
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class ChangedInferiorTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipIfHostWindows
+ def test_inferior_crashing(self):
+ """Test lldb reloads the inferior after it was changed during the session."""
+ self.build()
+ self.inferior_crashing()
+ self.cleanup()
+ # lldb needs to recognize the inferior has changed. If lldb needs to check the
+ # new module timestamp, make sure it is not the same as the old one, so add a
+ # 1 second delay.
+ time.sleep(1)
+ d = {'C_SOURCES': 'main2.c'}
+ self.build(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ self.inferior_not_crashing()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number of the crash.
+ self.line1 = line_number('main.c', '// Crash here.')
+ self.line2 = line_number('main2.c', '// Not crash here.')
+
+ def inferior_crashing(self):
+ """Inferior crashes upon launching; lldb should catch the event and stop."""
+ self.exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + self.exe, CURRENT_EXECUTABLE_SET)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # We should have one crashing thread
+ self.assertEqual(
+ len(lldbutil.get_crashed_threads(self, self.dbg.GetSelectedTarget().GetProcess())),
+ 1,
+ STOPPED_DUE_TO_EXC_BAD_ACCESS)
+
+ # And it should report the correct line number.
+ self.expect("thread backtrace all", substrs = ['main.c:%d' % self.line1])
+
+ def inferior_not_crashing(self):
+ """Test lldb reloads the inferior after it was changed during the session."""
+ self.runCmd("process kill")
+ self.runCmd("run", RUN_SUCCEEDED)
+ self.runCmd("process status")
+
+ self.assertNotEqual(
+ len(lldbutil.get_crashed_threads(self, self.dbg.GetSelectedTarget().GetProcess())),
+ 1,
+ "Inferior changed, but lldb did not perform a reload")
+
+ # Break inside the main.
+ lldbutil.run_break_set_by_file_and_line (self, "main2.c", self.line2, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ self.runCmd("frame variable int_ptr")
+ self.expect("frame variable *int_ptr",
+ substrs = ['= 7'])
+ self.expect("expression *int_ptr",
+ substrs = ['= 7'])
diff --git a/packages/Python/lldbsuite/test/functionalities/inferior-changed/main.c b/packages/Python/lldbsuite/test/functionalities/inferior-changed/main.c
new file mode 100644
index 000000000000..9d0706a0862d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/inferior-changed/main.c
@@ -0,0 +1,16 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+int main(int argc, const char* argv[])
+{
+ int *null_ptr = 0;
+ printf("Hello, segfault!\n");
+ printf("Now crash %d\n", *null_ptr); // Crash here.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/inferior-changed/main2.c b/packages/Python/lldbsuite/test/functionalities/inferior-changed/main2.c
new file mode 100644
index 000000000000..9173e8c30b59
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/inferior-changed/main2.c
@@ -0,0 +1,18 @@
+//===-- main2.c -------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, const char* argv[])
+{
+ int *int_ptr = (int *)malloc(sizeof(int));
+ *int_ptr = 7;
+ printf("Hello, world!\n");
+ printf("Now not crash %d\n", *int_ptr); // Not crash here.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/inferior-crashing/Makefile b/packages/Python/lldbsuite/test/functionalities/inferior-crashing/Makefile
new file mode 100644
index 000000000000..0d70f2595019
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/inferior-crashing/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/inferior-crashing/TestInferiorCrashing.py b/packages/Python/lldbsuite/test/functionalities/inferior-crashing/TestInferiorCrashing.py
new file mode 100644
index 000000000000..c547df116c16
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/inferior-crashing/TestInferiorCrashing.py
@@ -0,0 +1,220 @@
+"""Test that lldb functions correctly after the inferior has crashed."""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+import lldbsuite.test.lldbplatformutil as lldbplatformutil
+from lldbsuite.test.lldbtest import *
+
+class CrashingInferiorTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureFreeBSD("llvm.org/pr23699 SIGSEGV is reported as exception, not signal")
+ @expectedFailureWindows("llvm.org/pr24778") # This actually works, but the test relies on the output format instead of the API
+ def test_inferior_crashing(self):
+ """Test that lldb reliably catches the inferior crashing (command)."""
+ self.build()
+ self.inferior_crashing()
+
+ @expectedFailureWindows("llvm.org/pr24778")
+ def test_inferior_crashing_register(self):
+ """Test that lldb reliably reads registers from the inferior after crashing (command)."""
+ self.build()
+ self.inferior_crashing_registers()
+
+ @add_test_categories(['pyapi'])
+ @expectedFailureWindows("llvm.org/pr24778")
+ def test_inferior_crashing_python(self):
+ """Test that lldb reliably catches the inferior crashing (Python API)."""
+ self.build()
+ self.inferior_crashing_python()
+
+ @expectedFailureWindows("llvm.org/pr24778")
+ def test_inferior_crashing_expr(self):
+ """Test that the lldb expression interpreter can read from the inferior after crashing (command)."""
+ self.build()
+ self.inferior_crashing_expr()
+
+ @expectedFailureWindows("llvm.org/pr24778")
+ def test_inferior_crashing_step(self):
+ """Test that stepping after a crash behaves correctly."""
+ self.build()
+ self.inferior_crashing_step()
+
+ @expectedFailureFreeBSD('llvm.org/pr24939')
+ @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAndroid(archs=['aarch64'], api_levels=list(range(21 + 1))) # No eh_frame for sa_restorer
+ def test_inferior_crashing_step_after_break(self):
+ """Test that lldb functions correctly after stepping through a crash."""
+ self.build()
+ self.inferior_crashing_step_after_break()
+
+ @expectedFailureWindows("llvm.org/pr24778")
+ @skipIfLinux # Inferior exits after stepping after a segfault. This is working as intended IMHO.
+ def test_inferior_crashing_expr_step_and_expr(self):
+ """Test that lldb expressions work before and after stepping after a crash."""
+ self.build()
+ self.inferior_crashing_expr_step_expr()
+
+ def set_breakpoint(self, line):
+ lldbutil.run_break_set_by_file_and_line (self, "main.c", line, num_expected_locations=1, loc_exact=True)
+
+ def check_stop_reason(self):
+ # We should have one crashing thread
+ self.assertEqual(
+ len(lldbutil.get_crashed_threads(self, self.dbg.GetSelectedTarget().GetProcess())),
+ 1,
+ STOPPED_DUE_TO_EXC_BAD_ACCESS)
+
+ def get_api_stop_reason(self):
+ return lldb.eStopReasonException
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number of the crash.
+ self.line = line_number('main.c', '// Crash here.')
+
+ def inferior_crashing(self):
+ """Inferior crashes upon launching; lldb should catch the event and stop."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+ # The exact stop reason depends on the platform
+ if self.platformIsDarwin():
+ stop_reason = 'stop reason = EXC_BAD_ACCESS'
+ elif self.getPlatform() == "linux":
+ stop_reason = 'stop reason = signal SIGSEGV'
+ else:
+ stop_reason = 'stop reason = invalid address'
+ self.expect("thread list", STOPPED_DUE_TO_EXC_BAD_ACCESS,
+ substrs = ['stopped',
+ stop_reason])
+
+ # And it should report the correct line number.
+ self.expect("thread backtrace all",
+ substrs = [stop_reason,
+ 'main.c:%d' % self.line])
+
+ def inferior_crashing_python(self):
+ """Inferior crashes upon launching; lldb should catch the event and stop."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Now launch the process, and do not stop at entry point.
+ # Both argv and envp are null.
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ if process.GetState() != lldb.eStateStopped:
+ self.fail("Process should be in the 'stopped' state, "
+ "instead the actual state is: '%s'" %
+ lldbutil.state_type_to_str(process.GetState()))
+
+ threads = lldbutil.get_crashed_threads(self, process)
+ self.assertEqual(len(threads), 1, "Failed to stop the thread upon bad access exception")
+
+ if self.TraceOn():
+ lldbutil.print_stacktrace(threads[0])
+
+ def inferior_crashing_registers(self):
+ """Test that lldb can read registers after crashing."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+ self.check_stop_reason()
+
+ # lldb should be able to read from registers from the inferior after crashing.
+ lldbplatformutil.check_first_register_readable(self)
+
+ def inferior_crashing_expr(self):
+ """Test that the lldb expression interpreter can read symbols after crashing."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+ self.check_stop_reason()
+
+ # The lldb expression interpreter should be able to read from addresses of the inferior after a crash.
+ self.expect("p argc",
+ startstr = '(int) $0 = 1')
+
+ self.expect("p hello_world",
+ substrs = ['Hello'])
+
+ def inferior_crashing_step(self):
+ """Test that lldb functions correctly after stepping through a crash."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ self.set_breakpoint(self.line)
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['main.c:%d' % self.line,
+ 'stop reason = breakpoint'])
+
+ self.runCmd("next")
+ self.check_stop_reason()
+
+ # The lldb expression interpreter should be able to read from addresses of the inferior after a crash.
+ self.expect("p argv[0]",
+ substrs = ['a.out'])
+ self.expect("p null_ptr",
+ substrs = ['= 0x0'])
+
+ # lldb should be able to read from registers from the inferior after crashing.
+ lldbplatformutil.check_first_register_readable(self)
+
+ # And it should report the correct line number.
+ self.expect("thread backtrace all",
+ substrs = ['main.c:%d' % self.line])
+
+ def inferior_crashing_step_after_break(self):
+ """Test that lldb behaves correctly when stepping after a crash."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+ self.check_stop_reason()
+
+ expected_state = 'exited' # Provide the exit code.
+ if self.platformIsDarwin():
+ expected_state = 'stopped' # TODO: Determine why 'next' and 'continue' have no effect after a crash.
+ elif re.match(".*-.*-.*-android", self.dbg.GetSelectedPlatform().GetTriple()):
+ expected_state = 'stopped' # android has a default SEGV handler, which will re-raise the signal, so we come up stopped again
+
+ self.expect("next",
+ substrs = ['Process', expected_state])
+
+ if expected_state == 'exited':
+ self.expect("thread list", error=True,substrs = ['Process must be launched'])
+ else:
+ self.check_stop_reason()
+
+ def inferior_crashing_expr_step_expr(self):
+ """Test that lldb expressions work before and after stepping after a crash."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+ self.check_stop_reason()
+
+ # The lldb expression interpreter should be able to read from addresses of the inferior after a crash.
+ self.expect("p argv[0]",
+ substrs = ['a.out'])
+
+ self.runCmd("next")
+ self.check_stop_reason()
+
+ # The lldb expression interpreter should be able to read from addresses of the inferior after a crash.
+ self.expect("p argv[0]",
+ substrs = ['a.out'])
diff --git a/packages/Python/lldbsuite/test/functionalities/inferior-crashing/main.c b/packages/Python/lldbsuite/test/functionalities/inferior-crashing/main.c
new file mode 100644
index 000000000000..3b7cfe4012bd
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/inferior-crashing/main.c
@@ -0,0 +1,18 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+const char *hello_world = "Hello, segfault!";
+
+int main(int argc, const char* argv[])
+{
+ int *null_ptr = 0;
+ printf("%s\n", hello_world);
+ printf("Now crash %d\n", *null_ptr); // Crash here.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/inferior-crashing/recursive-inferior/Makefile b/packages/Python/lldbsuite/test/functionalities/inferior-crashing/recursive-inferior/Makefile
new file mode 100644
index 000000000000..0f8e92e9193c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/inferior-crashing/recursive-inferior/Makefile
@@ -0,0 +1,7 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+CFLAGS_EXTRAS += -fomit-frame-pointer
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/inferior-crashing/recursive-inferior/TestRecursiveInferior.py b/packages/Python/lldbsuite/test/functionalities/inferior-crashing/recursive-inferior/TestRecursiveInferior.py
new file mode 100644
index 000000000000..8afc81f6892a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/inferior-crashing/recursive-inferior/TestRecursiveInferior.py
@@ -0,0 +1,220 @@
+"""Test that lldb functions correctly after the inferior has crashed while in a recursive routine."""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+import lldbsuite.test.lldbplatformutil as lldbplatformutil
+from lldbsuite.test.lldbtest import *
+
+class CrashingRecursiveInferiorTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureFreeBSD("llvm.org/pr23699 SIGSEGV is reported as exception, not signal")
+ @expectedFailureWindows("llvm.org/pr24778")
+ def test_recursive_inferior_crashing(self):
+ """Test that lldb reliably catches the inferior crashing (command)."""
+ self.build()
+ self.recursive_inferior_crashing()
+
+ @expectedFailureWindows("llvm.org/pr24778")
+ def test_recursive_inferior_crashing_register(self):
+ """Test that lldb reliably reads registers from the inferior after crashing (command)."""
+ self.build()
+ self.recursive_inferior_crashing_registers()
+
+ @add_test_categories(['pyapi'])
+ @expectedFailureWindows("llvm.org/pr24778")
+ def test_recursive_inferior_crashing_python(self):
+ """Test that lldb reliably catches the inferior crashing (Python API)."""
+ self.build()
+ self.recursive_inferior_crashing_python()
+
+ @expectedFailureWindows("llvm.org/pr24778")
+ def test_recursive_inferior_crashing_expr(self):
+ """Test that the lldb expression interpreter can read from the inferior after crashing (command)."""
+ self.build()
+ self.recursive_inferior_crashing_expr()
+
+ @expectedFailureWindows("llvm.org/pr24778")
+ def test_recursive_inferior_crashing_step(self):
+ """Test that stepping after a crash behaves correctly."""
+ self.build()
+ self.recursive_inferior_crashing_step()
+
+ @expectedFailureFreeBSD('llvm.org/pr24939')
+ @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAndroid(archs=['aarch64'], api_levels=list(range(21 + 1))) # No eh_frame for sa_restorer
+ def test_recursive_inferior_crashing_step_after_break(self):
+ """Test that lldb functions correctly after stepping through a crash."""
+ self.build()
+ self.recursive_inferior_crashing_step_after_break()
+
+ @expectedFailureFreeBSD('llvm.org/pr15989') # Couldn't allocate space for the stack frame
+ @skipIfLinux # Inferior exits after stepping after a segfault. This is working as intended IMHO.
+ @expectedFailureWindows("llvm.org/pr24778")
+ def test_recursive_inferior_crashing_expr_step_and_expr(self):
+ """Test that lldb expressions work before and after stepping after a crash."""
+ self.build()
+ self.recursive_inferior_crashing_expr_step_expr()
+
+ def set_breakpoint(self, line):
+ lldbutil.run_break_set_by_file_and_line (self, "main.c", line, num_expected_locations=1, loc_exact=True)
+
+ def check_stop_reason(self):
+ # We should have one crashing thread
+ self.assertEqual(
+ len(lldbutil.get_crashed_threads(self, self.dbg.GetSelectedTarget().GetProcess())),
+ 1,
+ STOPPED_DUE_TO_EXC_BAD_ACCESS)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number of the crash.
+ self.line = line_number('main.c', '// Crash here.')
+
+ def recursive_inferior_crashing(self):
+ """Inferior crashes upon launching; lldb should catch the event and stop."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The exact stop reason depends on the platform
+ if self.platformIsDarwin():
+ stop_reason = 'stop reason = EXC_BAD_ACCESS'
+ elif self.getPlatform() == "linux":
+ stop_reason = 'stop reason = signal SIGSEGV'
+ else:
+ stop_reason = 'stop reason = invalid address'
+ self.expect("thread list", STOPPED_DUE_TO_EXC_BAD_ACCESS,
+ substrs = ['stopped',
+ stop_reason])
+
+ # And it should report a backtrace that includes main and the crash site.
+ self.expect("thread backtrace all",
+ substrs = [stop_reason, 'main', 'argc', 'argv', 'recursive_function'])
+
+ # And it should report the correct line number.
+ self.expect("thread backtrace all",
+ substrs = [stop_reason,
+ 'main.c:%d' % self.line])
+
+ def recursive_inferior_crashing_python(self):
+ """Inferior crashes upon launching; lldb should catch the event and stop."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Now launch the process, and do not stop at entry point.
+ # Both argv and envp are null.
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ if process.GetState() != lldb.eStateStopped:
+ self.fail("Process should be in the 'stopped' state, "
+ "instead the actual state is: '%s'" %
+ lldbutil.state_type_to_str(process.GetState()))
+
+ threads = lldbutil.get_crashed_threads(self, process)
+ self.assertEqual(len(threads), 1, "Failed to stop the thread upon bad access exception")
+
+ if self.TraceOn():
+ lldbutil.print_stacktrace(threads[0])
+
+ def recursive_inferior_crashing_registers(self):
+ """Test that lldb can read registers after crashing."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+ self.check_stop_reason()
+
+ # lldb should be able to read from registers from the inferior after crashing.
+ lldbplatformutil.check_first_register_readable(self)
+
+ def recursive_inferior_crashing_expr(self):
+ """Test that the lldb expression interpreter can read symbols after crashing."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+ self.check_stop_reason()
+
+ # The lldb expression interpreter should be able to read from addresses of the inferior after a crash.
+ self.expect("p i",
+ startstr = '(int) $0 =')
+
+ def recursive_inferior_crashing_step(self):
+ """Test that lldb functions correctly after stepping through a crash."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ self.set_breakpoint(self.line)
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['main.c:%d' % self.line,
+ 'stop reason = breakpoint'])
+
+ self.runCmd("next")
+ self.check_stop_reason()
+
+ # The lldb expression interpreter should be able to read from addresses of the inferior after a crash.
+ self.expect("p i",
+ substrs = ['(int) $0 ='])
+
+ # lldb should be able to read from registers from the inferior after crashing.
+ lldbplatformutil.check_first_register_readable(self)
+
+ # And it should report the correct line number.
+ self.expect("thread backtrace all",
+ substrs = ['main.c:%d' % self.line])
+
+ def recursive_inferior_crashing_step_after_break(self):
+ """Test that lldb behaves correctly when stepping after a crash."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+ self.check_stop_reason()
+
+ expected_state = 'exited' # Provide the exit code.
+ if self.platformIsDarwin():
+ expected_state = 'stopped' # TODO: Determine why 'next' and 'continue' have no effect after a crash.
+ elif re.match(".*-.*-.*-android", self.dbg.GetSelectedPlatform().GetTriple()):
+ expected_state = 'stopped' # android has a default SEGV handler, which will re-raise the signal, so we come up stopped again
+
+
+ self.expect("next",
+ substrs = ['Process', expected_state])
+
+ if expected_state == 'exited':
+ self.expect("thread list", error=True,substrs = ['Process must be launched'])
+ else:
+ self.check_stop_reason()
+
+ def recursive_inferior_crashing_expr_step_expr(self):
+ """Test that lldb expressions work before and after stepping after a crash."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+ self.check_stop_reason()
+
+ # The lldb expression interpreter should be able to read from addresses of the inferior after a crash.
+ self.expect("p null",
+ startstr = '(char *) $0 = 0x0')
+
+ self.runCmd("next")
+
+ # The lldb expression interpreter should be able to read from addresses of the inferior after a step.
+ self.expect("p null",
+ startstr = '(char *) $1 = 0x0')
+
+ self.check_stop_reason()
diff --git a/packages/Python/lldbsuite/test/functionalities/inferior-crashing/recursive-inferior/main.c b/packages/Python/lldbsuite/test/functionalities/inferior-crashing/recursive-inferior/main.c
new file mode 100644
index 000000000000..25e6e8df0b9b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/inferior-crashing/recursive-inferior/main.c
@@ -0,0 +1,19 @@
+void recursive_function(int i)
+{
+ if (i < 10)
+ {
+ recursive_function(i + 1);
+ }
+ else
+ {
+ char *null=0;
+ *null = 0; // Crash here.
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ recursive_function(0);
+ return 0;
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/inline-stepping/Makefile b/packages/Python/lldbsuite/test/functionalities/inline-stepping/Makefile
new file mode 100644
index 000000000000..532f49555e5f
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/inline-stepping/Makefile
@@ -0,0 +1,9 @@
+LEVEL = ../../make
+
+CXX_SOURCES := calling.cpp
+
+ifneq (,$(findstring icc,$(CC)))
+ CXXFLAGS += -debug inline-debug-info
+endif
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/inline-stepping/TestInlineStepping.py b/packages/Python/lldbsuite/test/functionalities/inline-stepping/TestInlineStepping.py
new file mode 100644
index 000000000000..3bdf6ec70e34
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/inline-stepping/TestInlineStepping.py
@@ -0,0 +1,270 @@
+"""Test stepping over and into inlined functions."""
+
+from __future__ import print_function
+
+
+
+import os, time, sys
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+class TestInlineStepping(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @add_test_categories(['pyapi'])
+ @expectedFailureFreeBSD('llvm.org/pr17214')
+ @expectedFailureIcc # Not really a bug. ICC combines two inlined functions.
+ @expectedFailureWindows("llvm.org/pr24778")
+ # failed 1/365 dosep runs, (i386-clang), TestInlineStepping.py:237 failed to stop at first breakpoint in main
+ @expectedFailureAll(oslist=["linux"], archs=["i386"])
+ def test_with_python_api(self):
+ """Test stepping over and into inlined functions."""
+ self.build()
+ self.inline_stepping()
+
+ @add_test_categories(['pyapi'])
+ def test_step_over_with_python_api(self):
+ """Test stepping over and into inlined functions."""
+ self.build()
+ self.inline_stepping_step_over()
+
+ @add_test_categories(['pyapi'])
+ def test_step_in_template_with_python_api(self):
+ """Test stepping in to templated functions."""
+ self.build()
+ self.step_in_template()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line numbers that we will step to in main:
+ self.main_source = "calling.cpp"
+ self.source_lines = {}
+ functions = ['caller_ref_1', 'caller_ref_2', 'inline_ref_1', 'inline_ref_2', 'called_by_inline_ref', 'caller_trivial_1', 'caller_trivial_2', 'inline_trivial_1', 'inline_trivial_2', 'called_by_inline_trivial' ]
+ for name in functions:
+ self.source_lines[name] = line_number(self.main_source, "// In " + name + ".")
+ self.main_source_spec = lldb.SBFileSpec (self.main_source)
+
+ def do_step(self, step_type, destination_line_entry, test_stack_depth):
+ expected_stack_depth = self.thread.GetNumFrames()
+ if step_type == "into":
+ expected_stack_depth += 1
+ self.thread.StepInto()
+ elif step_type == "out":
+ expected_stack_depth -= 1
+ self.thread.StepOut()
+ elif step_type == "over":
+ self.thread.StepOver()
+ else:
+ self.fail ("Unrecognized step type: " + step_type)
+
+ threads = lldbutil.get_stopped_threads (self.process, lldb.eStopReasonPlanComplete)
+ if len(threads) != 1:
+ destination_description = lldb.SBStream()
+ destination_line_entry.GetDescription(destination_description)
+ self.fail ("Failed to stop due to step " + step_type + " operation stepping to: " + destination_description.GetData())
+
+ self.thread = threads[0]
+
+ stop_line_entry = self.thread.GetFrameAtIndex(0).GetLineEntry()
+ self.assertTrue (stop_line_entry.IsValid(), "Stop line entry was not valid.")
+
+ # Don't use the line entry equal operator because we don't care about the column number.
+ stop_at_right_place = (stop_line_entry.GetFileSpec() == destination_line_entry.GetFileSpec() and stop_line_entry.GetLine() == destination_line_entry.GetLine())
+ if stop_at_right_place == False:
+ destination_description = lldb.SBStream()
+ destination_line_entry.GetDescription(destination_description)
+
+ actual_description = lldb.SBStream()
+ stop_line_entry.GetDescription(actual_description)
+
+ self.fail ("Step " + step_type + " stopped at wrong place: expected: " + destination_description.GetData() + " got: " + actual_description.GetData() + ".")
+
+ real_stack_depth = self.thread.GetNumFrames()
+
+ if test_stack_depth and real_stack_depth != expected_stack_depth:
+ destination_description = lldb.SBStream()
+ destination_line_entry.GetDescription(destination_description)
+ self.fail ("Step %s to %s got wrong number of frames, should be: %d was: %d."%(step_type, destination_description.GetData(), expected_stack_depth, real_stack_depth))
+
+ def run_step_sequence(self, step_sequence):
+ """This function takes a list of duples instructing how to run the program. The first element in each duple is
+ a source pattern for the target location, and the second is the operation that will take you from the current
+ source location to the target location. It will then run all the steps in the sequence.
+ It will check that you arrived at the expected source location at each step, and that the stack depth changed
+ correctly for the operation in the sequence."""
+
+ target_line_entry = lldb.SBLineEntry()
+ target_line_entry.SetFileSpec(self.main_source_spec)
+
+ test_stack_depth = True
+ # Work around for <rdar://problem/16363195>, the darwin unwinder seems flakey about whether it duplicates the first frame
+ # or not, which makes counting stack depth unreliable.
+ if self.platformIsDarwin():
+ test_stack_depth = False
+
+ for step_pattern in step_sequence:
+ step_stop_line = line_number (self.main_source, step_pattern[0])
+ target_line_entry.SetLine(step_stop_line)
+ self.do_step (step_pattern[1], target_line_entry, test_stack_depth)
+
+ def inline_stepping(self):
+ """Use Python APIs to test stepping over and hitting breakpoints."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ break_1_in_main = target.BreakpointCreateBySourceRegex ('// Stop here and step over to set up stepping over.', self.main_source_spec)
+ self.assertTrue(break_1_in_main, VALID_BREAKPOINT)
+
+ # Now launch the process, and do not stop at entry point.
+ self.process = target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+
+ # The stop reason of the thread should be breakpoint.
+ threads = lldbutil.get_threads_stopped_at_breakpoint (self.process, break_1_in_main)
+
+ if len(threads) != 1:
+ self.fail ("Failed to stop at first breakpoint in main.")
+
+ self.thread = threads[0]
+
+ # Step over the inline_value = 0 line to get us to inline_trivial_1 called from main. Doing it this way works
+ # around a bug in lldb where the breakpoint on the containing line of an inlined function with no return value
+ # gets set past the insertion line in the function.
+ # Then test stepping over a simple inlined function. Note, to test all the parts of the inlined stepping
+ # the calls inline_stepping_1 and inline_stepping_2 should line up at the same address, that way we will test
+ # the "virtual" stepping.
+ # FIXME: Put in a check to see if that is true and warn if it is not.
+
+ step_sequence = [["// At inline_trivial_1 called from main.", "over"],
+ ["// At first call of caller_trivial_1 in main.", "over"]]
+ self.run_step_sequence(step_sequence)
+
+ # Now step from caller_ref_1 all the way into called_by_inline_trivial
+
+ step_sequence = [["// In caller_trivial_1.", "into"],
+ ["// In caller_trivial_2.", "into"],
+ ["// In inline_trivial_1.", "into"],
+ ["// In inline_trivial_2.", "into"],
+ ["// At caller_by_inline_trivial in inline_trivial_2.", "over"],
+ ["// In called_by_inline_trivial.", "into"]]
+ self.run_step_sequence(step_sequence)
+
+ # Now run to the inline_trivial_1 just before the immediate step into inline_trivial_2:
+
+ break_2_in_main = target.BreakpointCreateBySourceRegex ('// At second call of caller_trivial_1 in main.', self.main_source_spec)
+ self.assertTrue(break_2_in_main, VALID_BREAKPOINT)
+
+ threads = lldbutil.continue_to_breakpoint (self.process, break_2_in_main)
+ self.assertTrue (len(threads) == 1, "Successfully ran to call site of second caller_trivial_1 call.")
+ self.thread = threads[0]
+
+ step_sequence = [["// In caller_trivial_1.", "into"],
+ ["// In caller_trivial_2.", "into"],
+ ["// In inline_trivial_1.", "into"]]
+ self.run_step_sequence(step_sequence)
+
+ # Then call some trivial function, and make sure we end up back where we were in the inlined call stack:
+
+ frame = self.thread.GetFrameAtIndex(0)
+ before_line_entry = frame.GetLineEntry()
+ value = frame.EvaluateExpression ("function_to_call()")
+ after_line_entry = frame.GetLineEntry()
+
+ self.assertTrue (before_line_entry.GetLine() == after_line_entry.GetLine(), "Line entry before and after function calls are the same.")
+
+ # Now make sure stepping OVER in the middle of the stack works, and then check finish from the inlined frame:
+
+ step_sequence = [["// At increment in inline_trivial_1.", "over"],
+ ["// At increment in caller_trivial_2.", "out"]]
+ self.run_step_sequence(step_sequence)
+
+
+ # Now run to the place in main just before the first call to caller_ref_1:
+
+ break_3_in_main = target.BreakpointCreateBySourceRegex ('// At first call of caller_ref_1 in main.', self.main_source_spec)
+ self.assertTrue(break_3_in_main, VALID_BREAKPOINT)
+
+ threads = lldbutil.continue_to_breakpoint (self.process, break_3_in_main)
+ self.assertTrue (len(threads) == 1, "Successfully ran to call site of first caller_ref_1 call.")
+ self.thread = threads[0]
+
+ step_sequence = [["// In caller_ref_1.", "into"],
+ ["// In caller_ref_2.", "into"],
+ ["// In inline_ref_1.", "into"],
+ ["// In inline_ref_2.", "into"],
+ ["// In called_by_inline_ref.", "into"],
+ ["// In inline_ref_2.", "out"],
+ ["// In inline_ref_1.", "out"],
+ ["// At increment in inline_ref_1.", "over"],
+ ["// In caller_ref_2.", "out"],
+ ["// At increment in caller_ref_2.", "over"]]
+ self.run_step_sequence (step_sequence)
+
+ def inline_stepping_step_over(self):
+ """Use Python APIs to test stepping over and hitting breakpoints."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ break_1_in_main = target.BreakpointCreateBySourceRegex ('// At second call of caller_ref_1 in main.', self.main_source_spec)
+ self.assertTrue(break_1_in_main, VALID_BREAKPOINT)
+
+ # Now launch the process, and do not stop at entry point.
+ self.process = target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+
+ # The stop reason of the thread should be breakpoint.
+ threads = lldbutil.get_threads_stopped_at_breakpoint (self.process, break_1_in_main)
+
+ if len(threads) != 1:
+ self.fail ("Failed to stop at first breakpoint in main.")
+
+ self.thread = threads[0]
+
+ step_sequence = [["// In caller_ref_1.", "into"],
+ ["// In caller_ref_2.", "into"],
+ ["// At increment in caller_ref_2.", "over"]]
+ self.run_step_sequence (step_sequence)
+
+ def step_in_template(self):
+ """Use Python APIs to test stepping in to templated functions."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ break_1_in_main = target.BreakpointCreateBySourceRegex ('// Call max_value template', self.main_source_spec)
+ self.assertTrue(break_1_in_main, VALID_BREAKPOINT)
+
+ break_2_in_main = target.BreakpointCreateBySourceRegex ('// Call max_value specialized', self.main_source_spec)
+ self.assertTrue(break_2_in_main, VALID_BREAKPOINT)
+
+ # Now launch the process, and do not stop at entry point.
+ self.process = target.LaunchSimple (None, None, self.get_process_working_directory())
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+
+ # The stop reason of the thread should be breakpoint.
+ threads = lldbutil.get_threads_stopped_at_breakpoint (self.process, break_1_in_main)
+
+ if len(threads) != 1:
+ self.fail ("Failed to stop at first breakpoint in main.")
+
+ self.thread = threads[0]
+
+ step_sequence = [["// In max_value template", "into"]]
+ self.run_step_sequence(step_sequence)
+
+ threads = lldbutil.continue_to_breakpoint (self.process, break_2_in_main)
+ self.assertEqual(len(threads), 1, "Successfully ran to call site of second caller_trivial_1 call.")
+ self.thread = threads[0]
+
+ step_sequence = [["// In max_value specialized", "into"]]
+ self.run_step_sequence(step_sequence)
diff --git a/packages/Python/lldbsuite/test/functionalities/inline-stepping/calling.cpp b/packages/Python/lldbsuite/test/functionalities/inline-stepping/calling.cpp
new file mode 100644
index 000000000000..9982fbf42734
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/inline-stepping/calling.cpp
@@ -0,0 +1,136 @@
+#include <algorithm>
+#include <cstdio>
+#include <string>
+
+inline int inline_ref_1 (int &value) __attribute__((always_inline));
+inline int inline_ref_2 (int &value) __attribute__((always_inline));
+
+int caller_ref_1 (int &value);
+int caller_ref_2 (int &value);
+
+int called_by_inline_ref (int &value);
+
+inline void inline_trivial_1 () __attribute__((always_inline));
+inline void inline_trivial_2 () __attribute__((always_inline));
+
+void caller_trivial_1 ();
+void caller_trivial_2 ();
+
+void called_by_inline_trivial ();
+
+static int inline_value;
+
+int
+function_to_call ()
+{
+ return inline_value;
+}
+
+int
+caller_ref_1 (int &value)
+{
+ int increment = caller_ref_2(value); // In caller_ref_1.
+ value += increment; // At increment in caller_ref_1.
+ return value;
+}
+
+int
+caller_ref_2 (int &value)
+{
+ int increment = inline_ref_1 (value); // In caller_ref_2.
+ value += increment; // At increment in caller_ref_2.
+ return value;
+}
+
+int
+called_by_inline_ref (int &value)
+{
+ value += 1; // In called_by_inline_ref.
+ return value;
+}
+
+int
+inline_ref_1 (int &value)
+{
+ int increment = inline_ref_2(value); // In inline_ref_1.
+ value += increment; // At increment in inline_ref_1.
+ return value;
+}
+
+int
+inline_ref_2 (int &value)
+{
+ int increment = called_by_inline_ref (value); // In inline_ref_2.
+ value += 1; // At increment in inline_ref_2.
+ return value;
+}
+
+void
+caller_trivial_1 ()
+{
+ caller_trivial_2(); // In caller_trivial_1.
+ inline_value += 1;
+}
+
+void
+caller_trivial_2 ()
+{
+ inline_trivial_1 (); // In caller_trivial_2.
+ inline_value += 1; // At increment in caller_trivial_2.
+}
+
+void
+called_by_inline_trivial ()
+{
+ inline_value += 1; // In called_by_inline_trivial.
+}
+
+void
+inline_trivial_1 ()
+{
+ inline_trivial_2(); // In inline_trivial_1.
+ inline_value += 1; // At increment in inline_trivial_1.
+}
+
+void
+inline_trivial_2 ()
+{
+ inline_value += 1; // In inline_trivial_2.
+ called_by_inline_trivial (); // At caller_by_inline_trivial in inline_trivial_2.
+}
+
+template<typename T> T
+max_value(const T& lhs, const T& rhs)
+{
+ return std::max(lhs, rhs); // In max_value template
+}
+
+template<> std::string
+max_value(const std::string& lhs, const std::string& rhs)
+{
+ return (lhs.size() > rhs.size()) ? lhs : rhs; // In max_value specialized
+}
+
+int
+main (int argc, char **argv)
+{
+
+ inline_value = 0; // Stop here and step over to set up stepping over.
+
+ inline_trivial_1 (); // At inline_trivial_1 called from main.
+
+ caller_trivial_1(); // At first call of caller_trivial_1 in main.
+
+ caller_trivial_1(); // At second call of caller_trivial_1 in main.
+
+ caller_ref_1 (argc); // At first call of caller_ref_1 in main.
+
+ caller_ref_1 (argc); // At second call of caller_ref_1 in main.
+
+ function_to_call (); // Make sure debug info for this function gets generated.
+
+ max_value(123, 456); // Call max_value template
+ max_value(std::string("abc"), std::string("0022")); // Call max_value specialized
+
+ return 0; // About to return from main.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/Makefile b/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/Makefile
new file mode 100644
index 000000000000..0d70f2595019
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/TestJITLoaderGDB.py b/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/TestJITLoaderGDB.py
new file mode 100644
index 000000000000..c7abf3464412
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/TestJITLoaderGDB.py
@@ -0,0 +1,37 @@
+"""Test for the JITLoaderGDB interface"""
+
+from __future__ import print_function
+
+
+
+import unittest2
+import os
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+import re
+
+
+class JITLoaderGDBTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipTestIfFn(lambda x: True, "llvm.org/pr24702", "Skipped because the test crashes the test runner")
+ @unittest2.expectedFailure("llvm.org/pr24702")
+ def test_bogus_values(self):
+ """Test that we handle inferior misusing the GDB JIT interface"""
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # launch the process, do not stop at entry point.
+ process = target.LaunchSimple(None, None, self.get_process_working_directory())
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # The inferior will now pass bogus values over the interface. Make sure we don't crash.
+
+ self.assertEqual(process.GetState(), lldb.eStateExited)
+ self.assertEqual(process.GetExitStatus(), 0)
diff --git a/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/main.c b/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/main.c
new file mode 100644
index 000000000000..6a8ec50e6637
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/main.c
@@ -0,0 +1,44 @@
+#include <inttypes.h>
+
+// GDB JIT interface
+enum JITAction { JIT_NOACTION, JIT_REGISTER_FN, JIT_UNREGISTER_FN };
+
+struct JITCodeEntry
+{
+ struct JITCodeEntry* next;
+ struct JITCodeEntry* prev;
+ const char *symfile_addr;
+ uint64_t symfile_size;
+};
+
+struct JITDescriptor
+{
+ uint32_t version;
+ uint32_t action_flag;
+ struct JITCodeEntry* relevant_entry;
+ struct JITCodeEntry* first_entry;
+};
+
+struct JITDescriptor __jit_debug_descriptor = { 1, JIT_NOACTION, 0, 0 };
+
+void __jit_debug_register_code()
+{
+}
+// end GDB JIT interface
+
+struct JITCodeEntry entry;
+
+int main()
+{
+ // Create a code entry with a bogus size
+ entry.next = entry.prev = 0;
+ entry.symfile_addr = (char *)&entry;
+ entry.symfile_size = (uint64_t)47<<32;
+
+ __jit_debug_descriptor.relevant_entry = __jit_debug_descriptor.first_entry = &entry;
+ __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
+
+ __jit_debug_register_code();
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/Makefile b/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/Makefile
new file mode 100644
index 000000000000..8a7102e347af
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/TestLaunchWithShellExpand.py b/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/TestLaunchWithShellExpand.py
new file mode 100644
index 000000000000..8f712dc21110
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/TestLaunchWithShellExpand.py
@@ -0,0 +1,97 @@
+"""
+Test that argdumper is a viable launching strategy.
+"""
+from __future__ import print_function
+
+
+
+import lldb
+import os
+import time
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class LaunchWithShellExpandTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureFreeBSD("llvm.org/pr22627 process launch w/ shell expansion not working")
+ @expectedFailureLinux("llvm.org/pr22627 process launch w/ shell expansion not working")
+ @expectedFailureWindows("llvm.org/pr24778")
+ def test(self):
+ self.build()
+ exe = os.path.join (os.getcwd(), "a.out")
+
+ self.runCmd("target create %s" % exe)
+
+ # Create the target
+ target = self.dbg.CreateTarget(exe)
+
+ # Create any breakpoints we need
+ breakpoint = target.BreakpointCreateBySourceRegex ('break here', lldb.SBFileSpec ("main.cpp", False))
+ self.assertTrue(breakpoint, VALID_BREAKPOINT)
+
+ self.runCmd("process launch -X true -w %s -- fi*.tx?" % (os.getcwd()))
+
+ process = self.process()
+
+ self.assertTrue(process.GetState() == lldb.eStateStopped,
+ STOPPED_DUE_TO_BREAKPOINT)
+
+ thread = process.GetThreadAtIndex (0)
+
+ self.assertTrue (thread.IsValid(),
+ "Process stopped at 'main' should have a valid thread");
+
+ stop_reason = thread.GetStopReason()
+
+ self.assertTrue (stop_reason == lldb.eStopReasonBreakpoint,
+ "Thread in process stopped in 'main' should have a stop reason of eStopReasonBreakpoint");
+
+ self.expect("frame variable argv[1]", substrs=['file1.txt'])
+ self.expect("frame variable argv[2]", substrs=['file2.txt'])
+ self.expect("frame variable argv[3]", substrs=['file3.txt'])
+ self.expect("frame variable argv[4]", substrs=['file4.txy'])
+ self.expect("frame variable argv[5]", substrs=['file5.tyx'], matching=False)
+
+ self.runCmd("process kill")
+
+ self.runCmd('process launch -X true -w %s -- "foo bar"' % (os.getcwd()))
+
+ process = self.process()
+
+ self.assertTrue(process.GetState() == lldb.eStateStopped,
+ STOPPED_DUE_TO_BREAKPOINT)
+
+ thread = process.GetThreadAtIndex (0)
+
+ self.assertTrue (thread.IsValid(),
+ "Process stopped at 'main' should have a valid thread");
+
+ stop_reason = thread.GetStopReason()
+
+ self.assertTrue (stop_reason == lldb.eStopReasonBreakpoint,
+ "Thread in process stopped in 'main' should have a stop reason of eStopReasonBreakpoint");
+
+ self.expect("frame variable argv[1]", substrs=['foo bar'])
+
+ self.runCmd("process kill")
+
+ self.runCmd('process launch -X true -w %s -- foo\ bar' % (os.getcwd()))
+
+ process = self.process()
+
+ self.assertTrue(process.GetState() == lldb.eStateStopped,
+ STOPPED_DUE_TO_BREAKPOINT)
+
+ thread = process.GetThreadAtIndex (0)
+
+ self.assertTrue (thread.IsValid(),
+ "Process stopped at 'main' should have a valid thread");
+
+ stop_reason = thread.GetStopReason()
+
+ self.assertTrue (stop_reason == lldb.eStopReasonBreakpoint,
+ "Thread in process stopped in 'main' should have a stop reason of eStopReasonBreakpoint");
+
+ self.expect("frame variable argv[1]", substrs=['foo bar'])
diff --git a/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/file1.txt b/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/file1.txt
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/file1.txt
diff --git a/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/file2.txt b/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/file2.txt
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/file2.txt
diff --git a/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/file3.txt b/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/file3.txt
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/file3.txt
diff --git a/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/file4.txy b/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/file4.txy
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/file4.txy
diff --git a/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/file5.tyx b/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/file5.tyx
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/file5.tyx
diff --git a/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/foo bar b/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/foo bar
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/foo bar
diff --git a/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/main.cpp b/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/main.cpp
new file mode 100644
index 000000000000..cbef8d1e6da1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/main.cpp
@@ -0,0 +1,5 @@
+int
+main (int argc, char const **argv)
+{
+ return 0; // break here
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/load_unload/Makefile b/packages/Python/lldbsuite/test/functionalities/load_unload/Makefile
new file mode 100644
index 000000000000..779745c4d26c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/load_unload/Makefile
@@ -0,0 +1,24 @@
+LEVEL := ../../make
+
+LIB_PREFIX := loadunload_
+
+LD_EXTRAS := -L. -l$(LIB_PREFIX)d -ldl
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
+
+.PHONY:
+a.out: lib_a lib_b lib_c lib_d hidden_lib_d
+
+lib_%:
+ $(MAKE) -f $*.mk
+
+hidden_lib_d:
+ $(MAKE) -C hidden
+
+clean::
+ $(MAKE) -f a.mk clean
+ $(MAKE) -f b.mk clean
+ $(MAKE) -f c.mk clean
+ $(MAKE) -f d.mk clean
+ $(MAKE) -C hidden clean
diff --git a/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py b/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py
new file mode 100644
index 000000000000..481e7c887bd0
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py
@@ -0,0 +1,357 @@
+"""
+Test that breakpoint by symbol name works correctly with dynamic libs.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import re
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+@skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently
+class LoadUnloadTestCase(TestBase):
+
+ def getCategories (self):
+ return ['basic_process']
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break for main.cpp.
+ self.line = line_number('main.cpp',
+ '// Set break point at this line for test_lldb_process_load_and_unload_commands().')
+ self.line_d_function = line_number('d.cpp',
+ '// Find this line number within d_dunction().')
+ if not self.platformIsDarwin():
+ if not lldb.remote_platform and "LD_LIBRARY_PATH" in os.environ:
+ self.runCmd("settings set target.env-vars " + self.dylibPath + "=" + os.environ["LD_LIBRARY_PATH"] + ":" + os.getcwd())
+ else:
+ if lldb.remote_platform:
+ wd = lldb.remote_platform.GetWorkingDirectory()
+ else:
+ wd = os.getcwd()
+ self.runCmd("settings set target.env-vars " + self.dylibPath + "=" + wd)
+
+ def copy_shlibs_to_remote(self, hidden_dir=False):
+ """ Copies the shared libs required by this test suite to remote.
+ Does nothing in case of non-remote platforms.
+ """
+ if lldb.remote_platform:
+ cwd = os.getcwd()
+ shlibs = ['libloadunload_a.so', 'libloadunload_b.so',
+ 'libloadunload_c.so', 'libloadunload_d.so']
+ wd = lldb.remote_platform.GetWorkingDirectory()
+ for f in shlibs:
+ err = lldb.remote_platform.Put(
+ lldb.SBFileSpec(os.path.join(cwd, f)),
+ lldb.SBFileSpec(os.path.join(wd, f)))
+ if err.Fail():
+ raise RuntimeError(
+ "Unable copy '%s' to '%s'.\n>>> %s" %
+ (f, wd, err.GetCString()))
+ if hidden_dir:
+ shlib = 'libloadunload_d.so'
+ hidden_dir = os.path.join(wd, 'hidden')
+ hidden_file = os.path.join(hidden_dir, shlib)
+ err = lldb.remote_platform.MakeDirectory(hidden_dir)
+ if err.Fail():
+ raise RuntimeError(
+ "Unable to create a directory '%s'." % hidden_dir)
+ err = lldb.remote_platform.Put(
+ lldb.SBFileSpec(os.path.join(cwd, 'hidden', shlib)),
+ lldb.SBFileSpec(hidden_file))
+ if err.Fail():
+ raise RuntimeError(
+ "Unable copy 'libloadunload_d.so' to '%s'.\n>>> %s" %
+ (wd, err.GetCString()))
+
+ @skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
+ @not_remote_testsuite_ready
+ @skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently
+ def test_modules_search_paths(self):
+ """Test target modules list after loading a different copy of the library libd.dylib, and verifies that it works with 'target modules search-paths add'."""
+
+ # Invoke the default build rule.
+ self.build()
+
+ if self.platformIsDarwin():
+ dylibName = 'libloadunload_d.dylib'
+ else:
+ dylibName = 'libloadunload_d.so'
+
+ # The directory with the dynamic library we did not link to.
+ new_dir = os.path.join(os.getcwd(), "hidden")
+
+ old_dylib = os.path.join(os.getcwd(), dylibName)
+ new_dylib = os.path.join(new_dir, dylibName)
+
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ self.expect("target modules list",
+ substrs = [old_dylib])
+ #self.expect("target modules list -t 3",
+ # patterns = ["%s-[^-]*-[^-]*" % self.getArchitecture()])
+ # Add an image search path substitution pair.
+ self.runCmd("target modules search-paths add %s %s" % (os.getcwd(), new_dir))
+
+ self.expect("target modules search-paths list",
+ substrs = [os.getcwd(), new_dir])
+
+ self.expect("target modules search-paths query %s" % os.getcwd(), "Image search path successfully transformed",
+ substrs = [new_dir])
+
+ # Obliterate traces of libd from the old location.
+ os.remove(old_dylib)
+ # Inform (DY)LD_LIBRARY_PATH of the new path, too.
+ env_cmd_string = "settings set target.env-vars " + self.dylibPath + "=" + new_dir
+ if self.TraceOn():
+ print("Set environment to: ", env_cmd_string)
+ self.runCmd(env_cmd_string)
+ self.runCmd("settings show target.env-vars")
+
+ remove_dyld_path_cmd = "settings remove target.env-vars " + self.dylibPath
+ self.addTearDownHook(lambda: self.dbg.HandleCommand(remove_dyld_path_cmd))
+
+ self.runCmd("run")
+
+ self.expect("target modules list", "LLDB successfully locates the relocated dynamic library",
+ substrs = [new_dylib])
+
+ @skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
+ @skipUnlessListedRemote(['android'])
+ @expectedFailureAndroid # wrong source file shows up for hidden library
+ @skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently
+ def test_dyld_library_path(self):
+ """Test (DY)LD_LIBRARY_PATH after moving libd.dylib, which defines d_function, somewhere else."""
+
+ # Invoke the default build rule.
+ self.build()
+ self.copy_shlibs_to_remote(hidden_dir=True)
+
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ if self.platformIsDarwin():
+ dylibName = 'libloadunload_d.dylib'
+ dsymName = 'libloadunload_d.dylib.dSYM'
+ else:
+ dylibName = 'libloadunload_d.so'
+
+ # The directory to relocate the dynamic library and its debugging info.
+ special_dir = "hidden"
+ if lldb.remote_platform:
+ wd = lldb.remote_platform.GetWorkingDirectory()
+ else:
+ wd = os.getcwd()
+
+ old_dir = wd
+ new_dir = os.path.join(wd, special_dir)
+ old_dylib = os.path.join(old_dir, dylibName)
+
+ remove_dyld_path_cmd = "settings remove target.env-vars " + self.dylibPath
+ self.addTearDownHook(lambda: self.dbg.HandleCommand(remove_dyld_path_cmd))
+
+ # For now we don't track (DY)LD_LIBRARY_PATH, so the old library will be in
+ # the modules list.
+ self.expect("target modules list",
+ substrs = [os.path.basename(old_dylib)],
+ matching=True)
+
+ lldbutil.run_break_set_by_file_and_line (self, "d.cpp", self.line_d_function, num_expected_locations=1)
+ # After run, make sure the non-hidden library is picked up.
+ self.expect("run", substrs=["return", "700"])
+
+ self.runCmd("continue")
+
+ # Add the hidden directory first in the search path.
+ env_cmd_string = ("settings set target.env-vars %s=%s" %
+ (self.dylibPath, new_dir))
+ if not self.platformIsDarwin():
+ env_cmd_string += ":" + wd
+ self.runCmd(env_cmd_string)
+
+ # This time, the hidden library should be picked up.
+ self.expect("run", substrs=["return", "12345"])
+
+ @expectedFailureAll(bugnumber="llvm.org/pr25805", hostoslist=["windows"], compiler="gcc", archs=["i386"], triple='.*-android')
+ @skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
+ @skipUnlessListedRemote(['android'])
+ @skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently
+ def test_lldb_process_load_and_unload_commands(self):
+ """Test that lldb process load/unload command work correctly."""
+
+ # Invoke the default build rule.
+ self.build()
+ self.copy_shlibs_to_remote()
+
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Break at main.cpp before the call to dlopen().
+ # Use lldb's process load command to load the dylib, instead.
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ if lldb.remote_platform:
+ shlib_dir = lldb.remote_platform.GetWorkingDirectory()
+ else:
+ shlib_dir = self.mydir
+
+ if self.platformIsDarwin():
+ dylibName = 'libloadunload_a.dylib'
+ else:
+ dylibName = 'libloadunload_a.so'
+
+ # Make sure that a_function does not exist at this point.
+ self.expect("image lookup -n a_function", "a_function should not exist yet",
+ error=True, matching=False, patterns = ["1 match found"])
+
+ # Use lldb 'process load' to load the dylib.
+ self.expect("process load %s --install" % dylibName, "%s loaded correctly" % dylibName,
+ patterns = ['Loading "%s".*ok' % dylibName,
+ 'Image [0-9]+ loaded'])
+
+ # Search for and match the "Image ([0-9]+) loaded" pattern.
+ output = self.res.GetOutput()
+ pattern = re.compile("Image ([0-9]+) loaded")
+ for l in output.split(os.linesep):
+ #print("l:", l)
+ match = pattern.search(l)
+ if match:
+ break
+ index = match.group(1)
+
+ # Now we should have an entry for a_function.
+ self.expect("image lookup -n a_function", "a_function should now exist",
+ patterns = ["1 match found .*%s" % dylibName])
+
+ # Use lldb 'process unload' to unload the dylib.
+ self.expect("process unload %s" % index, "%s unloaded correctly" % dylibName,
+ patterns = ["Unloading .* with index %s.*ok" % index])
+
+ self.runCmd("process continue")
+
+ @skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
+ @skipUnlessListedRemote(['android'])
+ def test_load_unload(self):
+ """Test breakpoint by name works correctly with dlopen'ing."""
+
+ # Invoke the default build rule.
+ self.build()
+ self.copy_shlibs_to_remote()
+
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Break by function name a_function (not yet loaded).
+ lldbutil.run_break_set_by_symbol (self, "a_function", num_expected_locations=0)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint and at a_function.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'a_function',
+ 'stop reason = breakpoint'])
+
+ # The breakpoint should have a hit count of 1.
+ self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
+ substrs = [' resolved, hit count = 1'])
+
+ # Issue the 'contnue' command. We should stop agaian at a_function.
+ # The stop reason of the thread should be breakpoint and at a_function.
+ self.runCmd("continue")
+
+ # rdar://problem/8508987
+ # The a_function breakpoint should be encountered twice.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'a_function',
+ 'stop reason = breakpoint'])
+
+ # The breakpoint should have a hit count of 2.
+ self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
+ substrs = [' resolved, hit count = 2'])
+
+ @skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
+ @skipUnlessListedRemote(['android'])
+ @skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently
+ def test_step_over_load (self):
+ """Test stepping over code that loads a shared library works correctly."""
+
+ # Invoke the default build rule.
+ self.build()
+ self.copy_shlibs_to_remote()
+
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Break by function name a_function (not yet loaded).
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint and at a_function.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ self.runCmd("thread step-over", "Stepping over function that loads library")
+
+ # The stop reason should be step end.
+ self.expect("thread list", "step over succeeded.",
+ substrs = ['stopped',
+ 'stop reason = step over'])
+
+ @skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
+ @skipUnlessListedRemote(['android'])
+ @skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently
+ @unittest2.expectedFailure("llvm.org/pr25806")
+ def test_static_init_during_load (self):
+ """Test that we can set breakpoints correctly in static initializers"""
+
+ self.build()
+ self.copy_shlibs_to_remote()
+
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ a_init_bp_num = lldbutil.run_break_set_by_symbol(self, "a_init", num_expected_locations=0)
+ b_init_bp_num = lldbutil.run_break_set_by_symbol(self, "b_init", num_expected_locations=0)
+ d_init_bp_num = lldbutil.run_break_set_by_symbol(self, "d_init", num_expected_locations=1)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'd_init',
+ 'stop reason = breakpoint %d' % d_init_bp_num])
+
+ self.runCmd("continue")
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'a_init',
+ 'stop reason = breakpoint %d' % a_init_bp_num])
+ self.expect("thread backtrace",
+ substrs = ['a_init',
+ 'dlopen',
+ 'main'])
+
+ self.runCmd("continue")
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'b_init',
+ 'stop reason = breakpoint %d' % b_init_bp_num])
+ self.expect("thread backtrace",
+ substrs = ['b_init',
+ 'dlopen',
+ 'main'])
diff --git a/packages/Python/lldbsuite/test/functionalities/load_unload/a.cpp b/packages/Python/lldbsuite/test/functionalities/load_unload/a.cpp
new file mode 100644
index 000000000000..235749aef74a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/load_unload/a.cpp
@@ -0,0 +1,22 @@
+//===-- a.c -----------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+extern int b_function ();
+
+int a_init()
+{
+ return 234;
+}
+
+int a_global = a_init();
+
+extern "C" int
+a_function ()
+{
+ return b_function ();
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/load_unload/a.mk b/packages/Python/lldbsuite/test/functionalities/load_unload/a.mk
new file mode 100644
index 000000000000..0eb810e21787
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/load_unload/a.mk
@@ -0,0 +1,23 @@
+LEVEL := ../../make
+
+LIB_PREFIX := loadunload_
+
+CFLAGS_EXTRAS := -fPIC
+LD_EXTRAS := -L. -l$(LIB_PREFIX)b
+
+DYLIB_NAME := $(LIB_PREFIX)a
+DYLIB_CXX_SOURCES := a.cpp
+DYLIB_ONLY := YES
+
+CXXFLAGS += -fPIC
+
+include $(LEVEL)/Makefile.rules
+
+.PHONY:
+$(DYLIB_FILENAME): lib_b
+
+lib_b:
+ "$(MAKE)" -f b.mk
+
+clean::
+ "$(MAKE)" -f b.mk clean
diff --git a/packages/Python/lldbsuite/test/functionalities/load_unload/b.cpp b/packages/Python/lldbsuite/test/functionalities/load_unload/b.cpp
new file mode 100644
index 000000000000..4d383169b79c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/load_unload/b.cpp
@@ -0,0 +1,21 @@
+//===-- b.c -----------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int b_init()
+{
+ return 345;
+}
+
+int b_global = b_init();
+
+int
+b_function ()
+{
+ return 500;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/load_unload/b.mk b/packages/Python/lldbsuite/test/functionalities/load_unload/b.mk
new file mode 100644
index 000000000000..c1b0877d72a4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/load_unload/b.mk
@@ -0,0 +1,11 @@
+LEVEL := ../../make
+
+LIB_PREFIX := loadunload_
+
+DYLIB_NAME := $(LIB_PREFIX)b
+DYLIB_CXX_SOURCES := b.cpp
+DYLIB_ONLY := YES
+
+CXXFLAGS += -fPIC
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/load_unload/c.cpp b/packages/Python/lldbsuite/test/functionalities/load_unload/c.cpp
new file mode 100644
index 000000000000..f0dfb4ec0d38
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/load_unload/c.cpp
@@ -0,0 +1,13 @@
+//===-- c.c -----------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+extern "C" int
+c_function ()
+{
+ return 600;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/load_unload/c.mk b/packages/Python/lldbsuite/test/functionalities/load_unload/c.mk
new file mode 100644
index 000000000000..5b5691efeef4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/load_unload/c.mk
@@ -0,0 +1,11 @@
+LEVEL := ../../make
+
+LIB_PREFIX := loadunload_
+
+DYLIB_NAME := $(LIB_PREFIX)c
+DYLIB_CXX_SOURCES := c.cpp
+DYLIB_ONLY := YES
+
+CXXFLAGS += -fPIC
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/load_unload/cmds.txt b/packages/Python/lldbsuite/test/functionalities/load_unload/cmds.txt
new file mode 100644
index 000000000000..1e4b198dc0d3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/load_unload/cmds.txt
@@ -0,0 +1,2 @@
+breakpoint set -n a_function
+run
diff --git a/packages/Python/lldbsuite/test/functionalities/load_unload/d.cpp b/packages/Python/lldbsuite/test/functionalities/load_unload/d.cpp
new file mode 100644
index 000000000000..55f2a6b404b3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/load_unload/d.cpp
@@ -0,0 +1,21 @@
+//===-- c.c -----------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int d_init()
+{
+ return 123;
+}
+
+int d_global = d_init();
+
+int
+d_function ()
+{ // Find this line number within d_dunction().
+ return 700;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/load_unload/d.mk b/packages/Python/lldbsuite/test/functionalities/load_unload/d.mk
new file mode 100644
index 000000000000..b6b6eeacba26
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/load_unload/d.mk
@@ -0,0 +1,13 @@
+LEVEL := ../../make
+
+LIB_PREFIX := loadunload_
+
+DYLIB_EXECUTABLE_PATH := $(CURDIR)
+
+DYLIB_NAME := $(LIB_PREFIX)d
+DYLIB_CXX_SOURCES := d.cpp
+DYLIB_ONLY := YES
+
+CXXFLAGS += -fPIC
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/load_unload/hidden/Makefile b/packages/Python/lldbsuite/test/functionalities/load_unload/hidden/Makefile
new file mode 100644
index 000000000000..f84d8300843f
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/load_unload/hidden/Makefile
@@ -0,0 +1,11 @@
+LEVEL := ../../../make
+
+LIB_PREFIX := loadunload_
+
+DYLIB_NAME := $(LIB_PREFIX)d
+DYLIB_CXX_SOURCES := d.cpp
+DYLIB_ONLY := YES
+
+CXXFLAGS += -fPIC
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/load_unload/hidden/d.cpp b/packages/Python/lldbsuite/test/functionalities/load_unload/hidden/d.cpp
new file mode 100644
index 000000000000..6a7642c08b93
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/load_unload/hidden/d.cpp
@@ -0,0 +1,21 @@
+//===-- c.c -----------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int d_init()
+{
+ return 456;
+}
+
+int d_global = d_init();
+
+int
+d_function ()
+{ // Find this line number within d_dunction().
+ return 12345;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/load_unload/main.cpp b/packages/Python/lldbsuite/test/functionalities/load_unload/main.cpp
new file mode 100644
index 000000000000..bff9a3176060
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/load_unload/main.cpp
@@ -0,0 +1,80 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+#include <dlfcn.h>
+#include <limits.h>
+#include <string.h>
+#include <unistd.h>
+#include <libgen.h>
+#include <stdlib.h>
+
+int
+main (int argc, char const *argv[])
+{
+#if defined (__APPLE__)
+ const char *a_name = "@executable_path/libloadunload_a.dylib";
+ const char *c_name = "@executable_path/libloadunload_c.dylib";
+#else
+ const char *a_name = "libloadunload_a.so";
+ const char *c_name = "libloadunload_c.so";
+#endif
+ void *a_dylib_handle = NULL;
+ void *c_dylib_handle = NULL;
+ int (*a_function) (void);
+
+ a_dylib_handle = dlopen (a_name, RTLD_NOW); // Set break point at this line for test_lldb_process_load_and_unload_commands().
+ if (a_dylib_handle == NULL)
+ {
+ fprintf (stderr, "%s\n", dlerror());
+ exit (1);
+ }
+
+ a_function = (int (*) ()) dlsym (a_dylib_handle, "a_function");
+ if (a_function == NULL)
+ {
+ fprintf (stderr, "%s\n", dlerror());
+ exit (2);
+ }
+ printf ("First time around, got: %d\n", a_function ());
+ dlclose (a_dylib_handle);
+
+ c_dylib_handle = dlopen (c_name, RTLD_NOW);
+ if (c_dylib_handle == NULL)
+ {
+ fprintf (stderr, "%s\n", dlerror());
+ exit (3);
+ }
+ a_function = (int (*) ()) dlsym (c_dylib_handle, "c_function");
+ if (a_function == NULL)
+ {
+ fprintf (stderr, "%s\n", dlerror());
+ exit (4);
+ }
+
+ a_dylib_handle = dlopen (a_name, RTLD_NOW);
+ if (a_dylib_handle == NULL)
+ {
+ fprintf (stderr, "%s\n", dlerror());
+ exit (5);
+ }
+
+ a_function = (int (*) ()) dlsym (a_dylib_handle, "a_function");
+ if (a_function == NULL)
+ {
+ fprintf (stderr, "%s\n", dlerror());
+ exit (6);
+ }
+ printf ("Second time around, got: %d\n", a_function ());
+ dlclose (a_dylib_handle);
+
+ int d_function(void);
+ printf ("d_function returns: %d\n", d_function());
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/longjmp/Makefile b/packages/Python/lldbsuite/test/functionalities/longjmp/Makefile
new file mode 100644
index 000000000000..0d70f2595019
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/longjmp/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/longjmp/TestLongjmp.py b/packages/Python/lldbsuite/test/functionalities/longjmp/TestLongjmp.py
new file mode 100644
index 000000000000..1316a01c924c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/longjmp/TestLongjmp.py
@@ -0,0 +1,85 @@
+"""
+Test the use of setjmp/longjmp for non-local goto operations in a single-threaded inferior.
+"""
+
+from __future__ import print_function
+
+
+
+import os
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+class LongjmpTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ TestBase.setUp(self)
+
+ @skipIfDarwin # llvm.org/pr16769: LLDB on Mac OS X dies in function ReadRegisterBytes in GDBRemoteRegisterContext.cpp
+ @skipIfFreeBSD # llvm.org/pr17214
+ @expectedFailureLinux("llvm.org/pr20231")
+ @expectedFailureWindows("llvm.org/pr24778")
+ def test_step_out(self):
+ """Test stepping when the inferior calls setjmp/longjmp, in particular, thread step-out."""
+ self.build()
+ self.step_out()
+
+ @skipIfDarwin # llvm.org/pr16769: LLDB on Mac OS X dies in function ReadRegisterBytes in GDBRemoteRegisterContext.cpp
+ @skipIfFreeBSD # llvm.org/pr17214
+ @expectedFailureLinux("llvm.org/pr20231")
+ @expectedFailureWindows("llvm.org/pr24778")
+ def test_step_over(self):
+ """Test stepping when the inferior calls setjmp/longjmp, in particular, thread step-over a longjmp."""
+ self.build()
+ self.step_over()
+
+ @skipIfDarwin # llvm.org/pr16769: LLDB on Mac OS X dies in function ReadRegisterBytes in GDBRemoteRegisterContext.cpp
+ @skipIfFreeBSD # llvm.org/pr17214
+ @expectedFailureLinux("llvm.org/pr20231")
+ @expectedFailureWindows("llvm.org/pr24778")
+ def test_step_back_out(self):
+ """Test stepping when the inferior calls setjmp/longjmp, in particular, thread step-out after thread step-in."""
+ self.build()
+ self.step_back_out()
+
+ def start_test(self, symbol):
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Break in main().
+ lldbutil.run_break_set_by_symbol (self, symbol, num_expected_locations=-1)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped', 'stop reason = breakpoint'])
+
+ def check_status(self):
+ # Note: Depending on the generated mapping of DWARF to assembly,
+ # the process may have stopped or exited.
+ self.expect("process status", PROCESS_STOPPED,
+ patterns = ['Process .* exited with status = 0'])
+
+ def step_out(self):
+ self.start_test("do_jump")
+ self.runCmd("thread step-out", RUN_SUCCEEDED)
+ self.check_status()
+
+ def step_over(self):
+ self.start_test("do_jump")
+ self.runCmd("thread step-over", RUN_SUCCEEDED)
+ self.runCmd("thread step-over", RUN_SUCCEEDED)
+ self.check_status()
+
+ def step_back_out(self):
+ self.start_test("main")
+
+ self.runCmd("thread step-over", RUN_SUCCEEDED)
+ self.runCmd("thread step-in", RUN_SUCCEEDED)
+ self.runCmd("thread step-out", RUN_SUCCEEDED)
+ self.check_status()
diff --git a/packages/Python/lldbsuite/test/functionalities/longjmp/main.c b/packages/Python/lldbsuite/test/functionalities/longjmp/main.c
new file mode 100644
index 000000000000..3879311eb452
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/longjmp/main.c
@@ -0,0 +1,31 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <setjmp.h>
+#include <stdio.h>
+#include <time.h>
+
+jmp_buf j;
+
+void do_jump(void)
+{
+ // We can't let the compiler know this will always happen or it might make
+ // optimizations that break our test.
+ if (!clock())
+ longjmp(j, 1); // non-local goto
+}
+
+int main (void)
+{
+ if (setjmp(j) == 0)
+ do_jump();
+ else
+ return 0; // destination of longjmp
+
+ return 1;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/memory/read/Makefile b/packages/Python/lldbsuite/test/functionalities/memory/read/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/memory/read/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/memory/read/TestMemoryRead.py b/packages/Python/lldbsuite/test/functionalities/memory/read/TestMemoryRead.py
new file mode 100644
index 000000000000..7410650ad652
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/memory/read/TestMemoryRead.py
@@ -0,0 +1,99 @@
+"""
+Test the 'memory read' command.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import re
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class MemoryReadTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside main().
+ self.line = line_number('main.cpp', '// Set break point at this line.')
+
+ def test_memory_read(self):
+ """Test the 'memory read' command with plain and vector formats."""
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Break in main() aftre the variables are assigned values.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped', 'stop reason = breakpoint'])
+
+ # The breakpoint should have a hit count of 1.
+ self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
+ substrs = [' resolved, hit count = 1'])
+
+ # Test the memory read commands.
+
+ # (lldb) memory read -f d -c 1 `&argc`
+ # 0x7fff5fbff9a0: 1
+ self.runCmd("memory read -f d -c 1 `&argc`")
+
+ # Find the starting address for variable 'argc' to verify later that the
+ # '--format uint32_t[] --size 4 --count 4' option increments the address
+ # correctly.
+ line = self.res.GetOutput().splitlines()[0]
+ items = line.split(':')
+ address = int(items[0], 0)
+ argc = int(items[1], 0)
+ self.assertTrue(address > 0 and argc == 1)
+
+ # (lldb) memory read --format uint32_t[] --size 4 --count 4 `&argc`
+ # 0x7fff5fbff9a0: {0x00000001}
+ # 0x7fff5fbff9a4: {0x00000000}
+ # 0x7fff5fbff9a8: {0x0ec0bf27}
+ # 0x7fff5fbff9ac: {0x215db505}
+ self.runCmd("memory read --format uint32_t[] --size 4 --count 4 `&argc`")
+ lines = self.res.GetOutput().splitlines()
+ for i in range(4):
+ if i == 0:
+ # Verify that the printout for argc is correct.
+ self.assertTrue(argc == int(lines[i].split(':')[1].strip(' {}'), 0))
+ addr = int(lines[i].split(':')[0], 0)
+ # Verify that the printout for addr is incremented correctly.
+ self.assertTrue(addr == (address + i*4))
+
+ # (lldb) memory read --format char[] --size 7 --count 1 `&my_string`
+ # 0x7fff5fbff990: {abcdefg}
+ self.expect("memory read --format char[] --size 7 --count 1 `&my_string`",
+ substrs = ['abcdefg'])
+
+ # (lldb) memory read --format 'hex float' --size 16 `&argc`
+ # 0x7fff5fbff5b0: error: unsupported byte size (16) for hex float format
+ self.expect("memory read --format 'hex float' --size 16 `&argc`",
+ substrs = ['unsupported byte size (16) for hex float format'])
+
+ self.expect("memory read --format 'float' --count 1 --size 8 `&my_double`",
+ substrs = ['1234.'])
+
+ # (lldb) memory read --format 'float' --count 1 --size 20 `&my_double`
+ # 0x7fff5fbff598: error: unsupported byte size (20) for float format
+ self.expect("memory read --format 'float' --count 1 --size 20 `&my_double`",
+ substrs = ['unsupported byte size (20) for float format'])
+
+ self.expect('memory read --type int --count 5 `&my_ints[0]`',
+ substrs=['(int) 0x', '2','4','6','8','10'])
+
+ self.expect('memory read --type int --count 5 --format hex `&my_ints[0]`',
+ substrs=['(int) 0x', '0x','0a'])
+
+ self.expect('memory read --type int --count 5 --offset 5 `&my_ints[0]`',
+ substrs=['(int) 0x', '12', '14','16','18', '20'])
diff --git a/packages/Python/lldbsuite/test/functionalities/memory/read/main.cpp b/packages/Python/lldbsuite/test/functionalities/memory/read/main.cpp
new file mode 100644
index 000000000000..cd367ff318ab
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/memory/read/main.cpp
@@ -0,0 +1,19 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+int main (int argc, char const *argv[])
+{
+ char my_string[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 0};
+ double my_double = 1234.5678;
+ int my_ints[] = {2,4,6,8,10,12,14,16,18,20,22};
+ printf("my_string=%s\n", my_string); // Set break point at this line.
+ printf("my_double=%g\n", my_double);
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/non-overlapping-index-variable-i/Makefile b/packages/Python/lldbsuite/test/functionalities/non-overlapping-index-variable-i/Makefile
new file mode 100644
index 000000000000..8a7102e347af
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/non-overlapping-index-variable-i/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/non-overlapping-index-variable-i/TestIndexVariable.py b/packages/Python/lldbsuite/test/functionalities/non-overlapping-index-variable-i/TestIndexVariable.py
new file mode 100644
index 000000000000..5c53cfaf9120
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/non-overlapping-index-variable-i/TestIndexVariable.py
@@ -0,0 +1,43 @@
+"""Test evaluating expressions which ref. index variable 'i' which just goes
+from out of scope to in scope when stopped at the breakpoint."""
+
+from __future__ import print_function
+
+
+
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class NonOverlappingIndexVariableCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ TestBase.setUp(self)
+ self.source = 'main.cpp'
+ self.line_to_break = line_number(self.source, '// Set breakpoint here.')
+
+ # rdar://problem/9890530
+ def test_eval_index_variable(self):
+ """Test expressions of variable 'i' which appears in two for loops."""
+ self.build()
+ self.exe_name = 'a.out'
+ exe = os.path.join(os.getcwd(), self.exe_name)
+ self.runCmd("file %s" % exe, CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, self.source, self.line_to_break, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ self.runCmd('frame variable i')
+ self.runCmd('expr i')
+ self.runCmd('expr ptr[0]->point.x')
+ self.runCmd('expr ptr[0]->point.y')
+ self.runCmd('expr ptr[i]->point.x')
+ self.runCmd('expr ptr[i]->point.y')
diff --git a/packages/Python/lldbsuite/test/functionalities/non-overlapping-index-variable-i/main.cpp b/packages/Python/lldbsuite/test/functionalities/non-overlapping-index-variable-i/main.cpp
new file mode 100644
index 000000000000..b4f519cd25a8
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/non-overlapping-index-variable-i/main.cpp
@@ -0,0 +1,51 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+class Point {
+public:
+ int x;
+ int y;
+ Point(int a, int b):
+ x(a),
+ y(b)
+ {}
+};
+
+class Data {
+public:
+ int id;
+ Point point;
+ Data(int i):
+ id(i),
+ point(0, 0)
+ {}
+};
+
+int main(int argc, char const *argv[]) {
+ Data *data[1000];
+ Data **ptr = data;
+ for (int i = 0; i < 1000; ++i) {
+ ptr[i] = new Data(i);
+ ptr[i]->point.x = i;
+ ptr[i]->point.y = i+1;
+ }
+
+ printf("Finished populating data.\n");
+ for (int i = 0; i < 1000; ++i) {
+ bool dump = argc > 1; // Set breakpoint here.
+ // Evaluate a couple of expressions (2*1000 = 2000 exprs):
+ // expr ptr[i]->point.x
+ // expr ptr[i]->point.y
+ if (dump) {
+ printf("data[%d] = %d (%d, %d)\n", i, ptr[i]->id, ptr[i]->point.x, ptr[i]->point.y);
+ }
+ }
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/nosucharch/Makefile b/packages/Python/lldbsuite/test/functionalities/nosucharch/Makefile
new file mode 100644
index 000000000000..8a7102e347af
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/nosucharch/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/nosucharch/TestNoSuchArch.py b/packages/Python/lldbsuite/test/functionalities/nosucharch/TestNoSuchArch.py
new file mode 100644
index 000000000000..7a6c98d92c3e
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/nosucharch/TestNoSuchArch.py
@@ -0,0 +1,29 @@
+"""
+Test that using a non-existent architecture name does not crash LLDB.
+"""
+from __future__ import print_function
+
+
+
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class NoSuchArchTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test (self):
+ self.build()
+ exe = os.path.join (os.getcwd(), "a.out")
+
+ # Check that passing an invalid arch via the command-line fails but doesn't crash
+ self.expect("target crete --arch nothingtoseehere %s" % (exe), error=True)
+
+ # Check that passing an invalid arch via the SB API fails but doesn't crash
+ target = self.dbg.CreateTargetWithFileAndArch(exe,"nothingtoseehere")
+ self.assertFalse(target.IsValid(), "This target should not be valid")
+
+ # Now just create the target with the default arch and check it's fine
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target.IsValid(), "This target should now be valid")
diff --git a/packages/Python/lldbsuite/test/functionalities/nosucharch/main.cpp b/packages/Python/lldbsuite/test/functionalities/nosucharch/main.cpp
new file mode 100644
index 000000000000..4cce7f667ff7
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/nosucharch/main.cpp
@@ -0,0 +1,3 @@
+int main() {
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/object-file/TestImageListMultiArchitecture.py b/packages/Python/lldbsuite/test/functionalities/object-file/TestImageListMultiArchitecture.py
new file mode 100644
index 000000000000..4f4a22ed6067
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/object-file/TestImageListMultiArchitecture.py
@@ -0,0 +1,41 @@
+"""
+Test lldb 'image list' on object files across multiple architectures.
+This exercises classes like ObjectFileELF and their support for opening
+foreign-architecture object files.
+"""
+
+from __future__ import print_function
+
+
+
+import os.path
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+import re
+
+class TestImageListMultiArchitecture(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @no_debug_info_test
+ def test_image_list_shows_multiple_architectures(self):
+ """Test that image list properly shows the correct architecture for a set of different architecture object files."""
+ images = {
+ "hello-freebsd-10.0-x86_64-clang-3.3": re.compile(r"x86_64-(\*)?-freebsd10.0(-unknown)? x86_64"),
+ "hello-freebsd-10.0-x86_64-gcc-4.7.3": re.compile(r"x86_64-(\*)?-freebsd10.0(-unknown)? x86_64"),
+ "hello-netbsd-6.1-x86_64-gcc-4.5.3": re.compile(r"x86_64-(\*)?-netbsd(-unknown)? x86_64"),
+ "hello-ubuntu-14.04-x86_64-gcc-4.8.2": re.compile(r"x86_64-(\*)?-linux(-unknown)? x86_64"),
+ "hello-ubuntu-14.04-x86_64-clang-3.5pre": re.compile(r"x86_64-(\*)?-linux(-unknown)? x86_64"),
+ "hello-unknown-kalimba_arch4-kcc-36": re.compile(r"kalimba4-csr-(unknown|\*)(-unknown)? kalimba"),
+ "hello-unknown-kalimba_arch5-kcc-39": re.compile(r"kalimba5-csr-(unknown|\*)(-unknown)? kalimba"),
+ }
+
+ for image_name in images:
+ file_name = os.path.abspath(os.path.join(os.path.dirname(__file__), "bin", image_name))
+ expected_triple_and_arch_regex = images[image_name]
+
+ self.runCmd("file {}".format(file_name))
+ self.match("image list -t -A", [expected_triple_and_arch_regex])
+ # Revert to the host platform after all of this is done
+ self.runCmd("platform select host")
diff --git a/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-freebsd-10.0-x86_64-clang-3.3 b/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-freebsd-10.0-x86_64-clang-3.3
new file mode 100644
index 000000000000..cea323639b46
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-freebsd-10.0-x86_64-clang-3.3
Binary files differ
diff --git a/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-freebsd-10.0-x86_64-gcc-4.7.3 b/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-freebsd-10.0-x86_64-gcc-4.7.3
new file mode 100644
index 000000000000..38f43f8acb9d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-freebsd-10.0-x86_64-gcc-4.7.3
Binary files differ
diff --git a/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-netbsd-6.1-x86_64-gcc-4.5.3 b/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-netbsd-6.1-x86_64-gcc-4.5.3
new file mode 100644
index 000000000000..6d531320ae96
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-netbsd-6.1-x86_64-gcc-4.5.3
Binary files differ
diff --git a/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-ubuntu-14.04-x86_64-clang-3.5pre b/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-ubuntu-14.04-x86_64-clang-3.5pre
new file mode 100644
index 000000000000..8bdcf4d5b59e
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-ubuntu-14.04-x86_64-clang-3.5pre
Binary files differ
diff --git a/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-ubuntu-14.04-x86_64-gcc-4.8.2 b/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-ubuntu-14.04-x86_64-gcc-4.8.2
new file mode 100644
index 000000000000..01efbb061b73
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-ubuntu-14.04-x86_64-gcc-4.8.2
Binary files differ
diff --git a/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-unknown-kalimba_arch4-kcc-36 b/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-unknown-kalimba_arch4-kcc-36
new file mode 100644
index 000000000000..8e4dd8c883c9
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-unknown-kalimba_arch4-kcc-36
Binary files differ
diff --git a/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-unknown-kalimba_arch5-kcc-39 b/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-unknown-kalimba_arch5-kcc-39
new file mode 100644
index 000000000000..f80268a08e5e
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello-unknown-kalimba_arch5-kcc-39
Binary files differ
diff --git a/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello.c b/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello.c
new file mode 100644
index 000000000000..8c804005afe3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ printf("Hello, world\n");
+ return 0;
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello.cpp b/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello.cpp
new file mode 100644
index 000000000000..8c804005afe3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/object-file/bin/hello.cpp
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ printf("Hello, world\n");
+ return 0;
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/paths/TestPaths.py b/packages/Python/lldbsuite/test/functionalities/paths/TestPaths.py
new file mode 100644
index 000000000000..f718b62f95ea
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/paths/TestPaths.py
@@ -0,0 +1,48 @@
+"""
+Test some lldb command abbreviations.
+"""
+from __future__ import print_function
+
+
+
+import lldb
+import os
+import time
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class TestPaths(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @no_debug_info_test
+ def test_paths (self):
+ '''Test to make sure no file names are set in the lldb.SBFileSpec objects returned by lldb.SBHostOS.GetLLDBPath() for paths that are directories'''
+ dir_path_types = [lldb.ePathTypeLLDBShlibDir,
+ lldb.ePathTypeSupportExecutableDir,
+ lldb.ePathTypeHeaderDir,
+ lldb.ePathTypePythonDir,
+ lldb.ePathTypeLLDBSystemPlugins,
+ lldb.ePathTypeLLDBUserPlugins,
+ lldb.ePathTypeLLDBTempSystemDir]
+
+ for path_type in dir_path_types:
+ f = lldb.SBHostOS.GetLLDBPath(path_type);
+ # No directory path types should have the filename set
+ self.assertTrue (f.GetFilename() == None);
+
+ @no_debug_info_test
+ def test_directory_doesnt_end_with_slash(self):
+ current_directory_spec = lldb.SBFileSpec(os.path.curdir)
+ current_directory_string = current_directory_spec.GetDirectory()
+ self.assertNotEqual(current_directory_string[-1:], '/')
+ pass
+
+ @skipUnlessPlatform(["windows"])
+ @no_debug_info_test
+ def test_windows_double_slash (self):
+ '''Test to check the path with double slash is handled correctly '''
+ # Create a path and see if lldb gets the directory and file right
+ fspec = lldb.SBFileSpec("C:\\dummy1\\dummy2//unknown_file", True);
+ self.assertEqual(os.path.normpath(fspec.GetDirectory()), os.path.normpath("C:/dummy1/dummy2"));
+ self.assertEqual(fspec.GetFilename(), "unknown_file");
diff --git a/packages/Python/lldbsuite/test/functionalities/platform/TestPlatformCommand.py b/packages/Python/lldbsuite/test/functionalities/platform/TestPlatformCommand.py
new file mode 100644
index 000000000000..6b3eedaf603a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/platform/TestPlatformCommand.py
@@ -0,0 +1,65 @@
+"""
+Test some lldb platform commands.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+
+class PlatformCommandTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @no_debug_info_test
+ def test_help_platform(self):
+ self.runCmd("help platform")
+
+ @no_debug_info_test
+ def test_list(self):
+ self.expect("platform list",
+ patterns = ['^Available platforms:'])
+
+ @no_debug_info_test
+ def test_process_list(self):
+ self.expect("platform process list",
+ substrs = ['PID', 'TRIPLE', 'NAME'])
+
+ @no_debug_info_test
+ def test_process_info_with_no_arg(self):
+ """This is expected to fail and to return a proper error message."""
+ self.expect("platform process info", error=True,
+ substrs = ['one or more process id(s) must be specified'])
+
+ @no_debug_info_test
+ def test_status(self):
+ self.expect("platform status",
+ substrs = ['Platform', 'Triple', 'OS Version', 'Kernel', 'Hostname'])
+
+ @no_debug_info_test
+ def test_shell(self):
+ """ Test that the platform shell command can invoke ls. """
+ triple = self.dbg.GetSelectedPlatform().GetTriple()
+ if re.match(".*-.*-windows", triple):
+ self.expect("platform shell dir c:\\", substrs = ["Windows", "Program Files"])
+ elif re.match(".*-.*-.*-android", triple):
+ self.expect("platform shell ls /", substrs = ["cache", "dev", "system"])
+ else:
+ self.expect("platform shell ls /", substrs = ["dev", "tmp", "usr"])
+
+ @no_debug_info_test
+ def test_shell_builtin(self):
+ """ Test a shell built-in command (echo) """
+ self.expect("platform shell echo hello lldb",
+ substrs = ["hello lldb"])
+
+ #FIXME: re-enable once platform shell -t can specify the desired timeout
+ @no_debug_info_test
+ def test_shell_timeout(self):
+ """ Test a shell built-in command (sleep) that times out """
+ self.skipTest("due to taking too long to complete.")
+ self.expect("platform shell sleep 15", error=True,
+ substrs = ["error: timed out waiting for shell command to complete"])
diff --git a/packages/Python/lldbsuite/test/functionalities/plugins/commands/Makefile b/packages/Python/lldbsuite/test/functionalities/plugins/commands/Makefile
new file mode 100644
index 000000000000..8af06446ecef
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/plugins/commands/Makefile
@@ -0,0 +1,8 @@
+LEVEL = ../../../make
+
+DYLIB_CXX_SOURCES := plugin.cpp
+DYLIB_NAME := plugin
+DYLIB_ONLY := YES
+MAKE_DSYM := NO
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/plugins/commands/TestPluginCommands.py b/packages/Python/lldbsuite/test/functionalities/plugins/commands/TestPluginCommands.py
new file mode 100644
index 000000000000..b62c30bcf4e7
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/plugins/commands/TestPluginCommands.py
@@ -0,0 +1,58 @@
+"""
+Test that plugins that load commands work correctly.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import re
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class PluginCommandTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipIfNoSBHeaders
+ @skipIfHostIncompatibleWithRemote # Requires a compatible arch and platform to link against the host's built lldb lib.
+ @expectedFailureWindows("llvm.org/pr24778")
+ @no_debug_info_test
+ def test_load_plugin(self):
+ """Test that plugins that load commands work correctly."""
+
+ plugin_name = "plugin"
+ if sys.platform.startswith("darwin"):
+ plugin_lib_name = "lib%s.dylib" % plugin_name
+ else:
+ plugin_lib_name = "lib%s.so" % plugin_name
+
+ # Invoke the library build rule.
+ self.buildLibrary("plugin.cpp", plugin_name)
+
+ debugger = lldb.SBDebugger.Create()
+
+ retobj = lldb.SBCommandReturnObject()
+
+ retval = debugger.GetCommandInterpreter().HandleCommand("plugin load %s" % plugin_lib_name, retobj)
+
+ retobj.Clear()
+
+ retval = debugger.GetCommandInterpreter().HandleCommand("plugin_loaded_command child abc def ghi",retobj)
+
+ if self.TraceOn():
+ print(retobj.GetOutput())
+
+ self.expect(retobj,substrs = ['abc def ghi'], exe=False)
+
+ retobj.Clear()
+
+ # check that abbreviations work correctly in plugin commands.
+ retval = debugger.GetCommandInterpreter().HandleCommand("plugin_loaded_ ch abc def ghi",retobj)
+
+ if self.TraceOn():
+ print(retobj.GetOutput())
+
+ self.expect(retobj,substrs = ['abc def ghi'], exe=False)
diff --git a/packages/Python/lldbsuite/test/functionalities/plugins/commands/plugin.cpp b/packages/Python/lldbsuite/test/functionalities/plugins/commands/plugin.cpp
new file mode 100644
index 000000000000..be3d29325de1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/plugins/commands/plugin.cpp
@@ -0,0 +1,62 @@
+//===-- plugin.cpp -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+/*
+An example plugin for LLDB that provides a new foo command with a child subcommand
+Compile this into a dylib foo.dylib and load by placing in appropriate locations on disk or
+by typing plugin load foo.dylib at the LLDB command line
+*/
+
+#if defined (__APPLE__)
+#include <LLDB/SBCommandInterpreter.h>
+#include <LLDB/SBCommandReturnObject.h>
+#include <LLDB/SBDebugger.h>
+#else
+#include <lldb/API/SBCommandInterpreter.h>
+#include <lldb/API/SBCommandReturnObject.h>
+#include <lldb/API/SBDebugger.h>
+#endif
+
+namespace lldb {
+ bool
+ PluginInitialize (lldb::SBDebugger debugger);
+}
+
+class ChildCommand : public lldb::SBCommandPluginInterface
+{
+public:
+ virtual bool
+ DoExecute (lldb::SBDebugger debugger,
+ char** command,
+ lldb::SBCommandReturnObject &result)
+ {
+ if (command)
+ {
+ const char* arg = *command;
+ while (arg)
+ {
+ result.Printf("%s ",arg);
+ arg = *(++command);
+ }
+ result.Printf("\n");
+ return true;
+ }
+ return false;
+ }
+
+};
+
+bool
+lldb::PluginInitialize (lldb::SBDebugger debugger)
+{
+ lldb::SBCommandInterpreter interpreter = debugger.GetCommandInterpreter();
+ lldb::SBCommand foo = interpreter.AddMultiwordCommand("plugin_loaded_command",NULL);
+ foo.AddCommand("child",new ChildCommand(),"a child of plugin_loaded_command");
+ return true;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/plugins/python_os_plugin/Makefile b/packages/Python/lldbsuite/test/functionalities/plugins/python_os_plugin/Makefile
new file mode 100644
index 000000000000..cd9ca5c86d84
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/plugins/python_os_plugin/Makefile
@@ -0,0 +1,3 @@
+LEVEL = ../../../make
+C_SOURCES := main.c
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/plugins/python_os_plugin/TestPythonOSPlugin.py b/packages/Python/lldbsuite/test/functionalities/plugins/python_os_plugin/TestPythonOSPlugin.py
new file mode 100644
index 000000000000..ebd96d9d4c02
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/plugins/python_os_plugin/TestPythonOSPlugin.py
@@ -0,0 +1,150 @@
+"""
+Test that the Python operating system plugin works correctly
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import re
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class PluginPythonOSPlugin(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test_python_os_plugin(self):
+ """Test that the Python operating system plugin works correctly"""
+ self.build()
+ self.run_python_os_funcionality()
+
+ def run_python_os_step(self):
+ """Test that the Python operating system plugin works correctly when single stepping a virtual thread"""
+ self.build()
+ self.run_python_os_step()
+
+ def verify_os_thread_registers(self, thread):
+ frame = thread.GetFrameAtIndex(0)
+ registers = frame.GetRegisters().GetValueAtIndex(0)
+ reg_value = thread.GetThreadID() + 1
+ for reg in registers:
+ self.assertTrue(reg.GetValueAsUnsigned() == reg_value, "Verify the registers contains the correct value")
+ reg_value = reg_value + 1
+
+ def run_python_os_funcionality(self):
+ """Test that the Python operating system plugin works correctly"""
+
+ # Set debugger into synchronous mode
+ self.dbg.SetAsync(False)
+
+ # Create a target by the debugger.
+ cwd = os.getcwd()
+ exe = os.path.join(cwd, "a.out")
+ python_os_plugin_path = os.path.join(cwd, "operating_system.py")
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Set breakpoints inside and outside methods that take pointers to the containing struct.
+ lldbutil.run_break_set_by_source_regexp (self, "// Set breakpoint here")
+
+ # Register our shared libraries for remote targets so they get automatically uploaded
+ arguments = None
+ environment = None
+
+ # Now launch the process, and do not stop at entry point.
+ process = target.LaunchSimple (arguments, environment, self.get_process_working_directory())
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # Make sure there are no OS plug-in created thread when we first stop at our breakpoint in main
+ thread = process.GetThreadByID(0x111111111);
+ self.assertFalse (thread.IsValid(), "Make sure there is no thread 0x111111111 before we load the python OS plug-in");
+ thread = process.GetThreadByID(0x222222222);
+ self.assertFalse (thread.IsValid(), "Make sure there is no thread 0x222222222 before we load the python OS plug-in");
+ thread = process.GetThreadByID(0x333333333);
+ self.assertFalse (thread.IsValid(), "Make sure there is no thread 0x333333333 before we load the python OS plug-in");
+
+
+ # Now load the python OS plug-in which should update the thread list and we should have
+ # OS plug-in created threads with the IDs: 0x111111111, 0x222222222, 0x333333333
+ command = "settings set target.process.python-os-plugin-path '%s'" % python_os_plugin_path
+ self.dbg.HandleCommand(command)
+
+ # Verify our OS plug-in threads showed up
+ thread = process.GetThreadByID(0x111111111);
+ self.assertTrue (thread.IsValid(), "Make sure there is a thread 0x111111111 after we load the python OS plug-in");
+ self.verify_os_thread_registers(thread)
+ thread = process.GetThreadByID(0x222222222);
+ self.assertTrue (thread.IsValid(), "Make sure there is a thread 0x222222222 after we load the python OS plug-in");
+ self.verify_os_thread_registers(thread)
+ thread = process.GetThreadByID(0x333333333);
+ self.assertTrue (thread.IsValid(), "Make sure there is a thread 0x333333333 after we load the python OS plug-in");
+ self.verify_os_thread_registers(thread)
+
+ # Now clear the OS plug-in path to make the OS plug-in created threads dissappear
+ self.dbg.HandleCommand("settings clear target.process.python-os-plugin-path")
+
+ # Verify the threads are gone after unloading the python OS plug-in
+ thread = process.GetThreadByID(0x111111111);
+ self.assertFalse (thread.IsValid(), "Make sure there is no thread 0x111111111 after we unload the python OS plug-in");
+ thread = process.GetThreadByID(0x222222222);
+ self.assertFalse (thread.IsValid(), "Make sure there is no thread 0x222222222 after we unload the python OS plug-in");
+ thread = process.GetThreadByID(0x333333333);
+ self.assertFalse (thread.IsValid(), "Make sure there is no thread 0x333333333 after we unload the python OS plug-in");
+
+ def run_python_os_step(self):
+ """Test that the Python operating system plugin works correctly and allows single stepping of a virtual thread that is backed by a real thread"""
+
+ # Set debugger into synchronous mode
+ self.dbg.SetAsync(False)
+
+ # Create a target by the debugger.
+ cwd = os.getcwd()
+ exe = os.path.join(cwd, "a.out")
+ python_os_plugin_path = os.path.join(cwd, "operating_system2.py")
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Set breakpoints inside and outside methods that take pointers to the containing struct.
+ lldbutil.run_break_set_by_source_regexp (self, "// Set breakpoint here")
+
+ # Register our shared libraries for remote targets so they get automatically uploaded
+ arguments = None
+ environment = None
+
+ # Now launch the process, and do not stop at entry point.
+ process = target.LaunchSimple (arguments, environment, self.get_process_working_directory())
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # Make sure there are no OS plug-in created thread when we first stop at our breakpoint in main
+ thread = process.GetThreadByID(0x111111111);
+ self.assertFalse (thread.IsValid(), "Make sure there is no thread 0x111111111 before we load the python OS plug-in");
+
+
+ # Now load the python OS plug-in which should update the thread list and we should have
+ # OS plug-in created threads with the IDs: 0x111111111, 0x222222222, 0x333333333
+ command = "settings set target.process.python-os-plugin-path '%s'" % python_os_plugin_path
+ self.dbg.HandleCommand(command)
+
+ # Verify our OS plug-in threads showed up
+ thread = process.GetThreadByID(0x111111111);
+ self.assertTrue (thread.IsValid(), "Make sure there is a thread 0x111111111 after we load the python OS plug-in");
+
+ frame = thread.GetFrameAtIndex(0)
+ self.assertTrue(frame.IsValid(), "Make sure we get a frame from thread 0x111111111")
+ line_entry = frame.GetLineEntry()
+
+ self.assertTrue(line_entry.GetFileSpec().GetFilename() == 'main.c', "Make sure we stopped on line 5 in main.c")
+ self.assertTrue(line_entry.GetLine() == 5, "Make sure we stopped on line 5 in main.c")
+
+ # Now single step thread 0x111111111 and make sure it does what we need it to
+ thread.StepOver()
+
+ frame = thread.GetFrameAtIndex(0)
+ self.assertTrue(frame.IsValid(), "Make sure we get a frame from thread 0x111111111")
+ line_entry = frame.GetLineEntry()
+
+ self.assertTrue(line_entry.GetFileSpec().GetFilename() == 'main.c', "Make sure we stepped from line 5 to line 6 in main.c")
+ self.assertTrue(line_entry.GetLine() == 6, "Make sure we stepped from line 5 to line 6 in main.c")
diff --git a/packages/Python/lldbsuite/test/functionalities/plugins/python_os_plugin/main.c b/packages/Python/lldbsuite/test/functionalities/plugins/python_os_plugin/main.c
new file mode 100644
index 000000000000..faa6dd58ecd6
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/plugins/python_os_plugin/main.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main (int argc, char const *argv[], char const *envp[])
+{
+ puts("stop here"); // Set breakpoint here
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/plugins/python_os_plugin/operating_system.py b/packages/Python/lldbsuite/test/functionalities/plugins/python_os_plugin/operating_system.py
new file mode 100644
index 000000000000..536092e40b38
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/plugins/python_os_plugin/operating_system.py
@@ -0,0 +1,90 @@
+#!/usr/bin/python
+
+import lldb
+import struct
+
+class OperatingSystemPlugIn(object):
+ """Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class"""
+
+ def __init__(self, process):
+ '''Initialization needs a valid.SBProcess object.
+
+ This plug-in will get created after a live process is valid and has stopped for the
+ first time.'''
+ self.process = None
+ self.registers = None
+ self.threads = None
+ if type(process) is lldb.SBProcess and process.IsValid():
+ self.process = process
+ self.threads = None # Will be an dictionary containing info for each thread
+
+ def get_target(self):
+ # NOTE: Don't use "lldb.target" when trying to get your target as the "lldb.target"
+ # tracks the current target in the LLDB command interpreter which isn't the
+ # correct thing to use for this plug-in.
+ return self.process.target
+
+ def create_thread(self, tid, context):
+ if tid == 0x444444444:
+ thread_info = { 'tid' : tid, 'name' : 'four' , 'queue' : 'queue4', 'state' : 'stopped', 'stop_reason' : 'none' }
+ self.threads.append(thread_info)
+ return thread_info
+ return None
+
+ def get_thread_info(self):
+ if not self.threads:
+ # The sample dictionary below shows the values that can be returned for a thread
+ # tid => thread ID (mandatory)
+ # name => thread name (optional key/value pair)
+ # queue => thread dispatch queue name (optional key/value pair)
+ # state => thred state (mandatory, set to 'stopped' for now)
+ # stop_reason => thread stop reason. (mandatory, usually set to 'none')
+ # Possible values include:
+ # 'breakpoint' if the thread is stopped at a breakpoint
+ # 'none' thread is just stopped because the process is stopped
+ # 'trace' the thread just single stepped
+ # The usual value for this while threads are in memory is 'none'
+ # register_data_addr => the address of the register data in memory (optional key/value pair)
+ # Specifying this key/value pair for a thread will avoid a call to get_register_data()
+ # and can be used when your registers are in a thread context structure that is contiguous
+ # in memory. Don't specify this if your register layout in memory doesn't match the layout
+ # described by the dictionary returned from a call to the get_register_info() method.
+ self.threads = [
+ { 'tid' : 0x111111111, 'name' : 'one' , 'queue' : 'queue1', 'state' : 'stopped', 'stop_reason' : 'breakpoint'},
+ { 'tid' : 0x222222222, 'name' : 'two' , 'queue' : 'queue2', 'state' : 'stopped', 'stop_reason' : 'none' },
+ { 'tid' : 0x333333333, 'name' : 'three', 'queue' : 'queue3', 'state' : 'stopped', 'stop_reason' : 'trace' }
+ ]
+ return self.threads
+
+ def get_register_info(self):
+ if self.registers == None:
+ self.registers = dict()
+ self.registers['sets'] = ['GPR']
+ self.registers['registers'] = [
+ { 'name':'rax' , 'bitsize' : 64, 'offset' : 0, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 0, 'dwarf' : 0},
+ { 'name':'rbx' , 'bitsize' : 64, 'offset' : 8, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 3, 'dwarf' : 3},
+ { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', },
+ { 'name':'rdx' , 'bitsize' : 64, 'offset' : 24, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 1, 'dwarf' : 1, 'generic':'arg3', 'alt-name':'arg3', },
+ { 'name':'rdi' , 'bitsize' : 64, 'offset' : 32, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 5, 'dwarf' : 5, 'generic':'arg1', 'alt-name':'arg1', },
+ { 'name':'rsi' , 'bitsize' : 64, 'offset' : 40, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 4, 'dwarf' : 4, 'generic':'arg2', 'alt-name':'arg2', },
+ { 'name':'rbp' , 'bitsize' : 64, 'offset' : 48, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 6, 'dwarf' : 6, 'generic':'fp' , 'alt-name':'fp', },
+ { 'name':'rsp' , 'bitsize' : 64, 'offset' : 56, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 7, 'dwarf' : 7, 'generic':'sp' , 'alt-name':'sp', },
+ { 'name':'r8' , 'bitsize' : 64, 'offset' : 64, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 8, 'dwarf' : 8, 'generic':'arg5', 'alt-name':'arg5', },
+ { 'name':'r9' , 'bitsize' : 64, 'offset' : 72, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 9, 'dwarf' : 9, 'generic':'arg6', 'alt-name':'arg6', },
+ { 'name':'r10' , 'bitsize' : 64, 'offset' : 80, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 10, 'dwarf' : 10},
+ { 'name':'r11' , 'bitsize' : 64, 'offset' : 88, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 11, 'dwarf' : 11},
+ { 'name':'r12' , 'bitsize' : 64, 'offset' : 96, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 12, 'dwarf' : 12},
+ { 'name':'r13' , 'bitsize' : 64, 'offset' : 104, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 13, 'dwarf' : 13},
+ { 'name':'r14' , 'bitsize' : 64, 'offset' : 112, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 14, 'dwarf' : 14},
+ { 'name':'r15' , 'bitsize' : 64, 'offset' : 120, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 15, 'dwarf' : 15},
+ { 'name':'rip' , 'bitsize' : 64, 'offset' : 128, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 16, 'dwarf' : 16, 'generic':'pc', 'alt-name':'pc' },
+ { 'name':'rflags' , 'bitsize' : 64, 'offset' : 136, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'generic':'flags', 'alt-name':'flags' },
+ { 'name':'cs' , 'bitsize' : 64, 'offset' : 144, 'encoding':'uint' , 'format':'hex' , 'set': 0 },
+ { 'name':'fs' , 'bitsize' : 64, 'offset' : 152, 'encoding':'uint' , 'format':'hex' , 'set': 0 },
+ { 'name':'gs' , 'bitsize' : 64, 'offset' : 160, 'encoding':'uint' , 'format':'hex' , 'set': 0 },
+ ]
+ return self.registers
+
+ def get_register_data(self, tid):
+ return struct.pack('21Q',tid + 1,tid + 2,tid + 3,tid + 4,tid + 5,tid + 6,tid + 7,tid + 8,tid + 9,tid + 10,tid + 11,tid + 12,tid + 13,tid + 14,tid + 15,tid + 16,tid + 17,tid + 18,tid + 19,tid + 20,tid + 21);
+
diff --git a/packages/Python/lldbsuite/test/functionalities/plugins/python_os_plugin/operating_system2.py b/packages/Python/lldbsuite/test/functionalities/plugins/python_os_plugin/operating_system2.py
new file mode 100644
index 000000000000..7a9435d44ed4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/plugins/python_os_plugin/operating_system2.py
@@ -0,0 +1,88 @@
+#!/usr/bin/python
+
+import lldb
+import struct
+
+class OperatingSystemPlugIn(object):
+ """Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class"""
+
+ def __init__(self, process):
+ '''Initialization needs a valid.SBProcess object.
+
+ This plug-in will get created after a live process is valid and has stopped for the
+ first time.'''
+ self.process = None
+ self.registers = None
+ self.threads = None
+ if type(process) is lldb.SBProcess and process.IsValid():
+ self.process = process
+ self.threads = None # Will be an dictionary containing info for each thread
+
+ def get_target(self):
+ # NOTE: Don't use "lldb.target" when trying to get your target as the "lldb.target"
+ # tracks the current target in the LLDB command interpreter which isn't the
+ # correct thing to use for this plug-in.
+ return self.process.target
+
+ def create_thread(self, tid, context):
+ if tid == 0x444444444:
+ thread_info = { 'tid' : tid, 'name' : 'four' , 'queue' : 'queue4', 'state' : 'stopped', 'stop_reason' : 'none' }
+ self.threads.append(thread_info)
+ return thread_info
+ return None
+
+ def get_thread_info(self):
+ if not self.threads:
+ # The sample dictionary below shows the values that can be returned for a thread
+ # tid => thread ID (mandatory)
+ # name => thread name (optional key/value pair)
+ # queue => thread dispatch queue name (optional key/value pair)
+ # state => thred state (mandatory, set to 'stopped' for now)
+ # stop_reason => thread stop reason. (mandatory, usually set to 'none')
+ # Possible values include:
+ # 'breakpoint' if the thread is stopped at a breakpoint
+ # 'none' thread is just stopped because the process is stopped
+ # 'trace' the thread just single stepped
+ # The usual value for this while threads are in memory is 'none'
+ # register_data_addr => the address of the register data in memory (optional key/value pair)
+ # Specifying this key/value pair for a thread will avoid a call to get_register_data()
+ # and can be used when your registers are in a thread context structure that is contiguous
+ # in memory. Don't specify this if your register layout in memory doesn't match the layout
+ # described by the dictionary returned from a call to the get_register_info() method.
+ self.threads = [
+ { 'tid' : 0x111111111, 'core' : 0 }
+ ]
+ return self.threads
+
+ def get_register_info(self):
+ if self.registers == None:
+ self.registers = dict()
+ self.registers['sets'] = ['GPR']
+ self.registers['registers'] = [
+ { 'name':'rax' , 'bitsize' : 64, 'offset' : 0, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 0, 'dwarf' : 0},
+ { 'name':'rbx' , 'bitsize' : 64, 'offset' : 8, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 3, 'dwarf' : 3},
+ { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', },
+ { 'name':'rdx' , 'bitsize' : 64, 'offset' : 24, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 1, 'dwarf' : 1, 'generic':'arg3', 'alt-name':'arg3', },
+ { 'name':'rdi' , 'bitsize' : 64, 'offset' : 32, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 5, 'dwarf' : 5, 'generic':'arg1', 'alt-name':'arg1', },
+ { 'name':'rsi' , 'bitsize' : 64, 'offset' : 40, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 4, 'dwarf' : 4, 'generic':'arg2', 'alt-name':'arg2', },
+ { 'name':'rbp' , 'bitsize' : 64, 'offset' : 48, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 6, 'dwarf' : 6, 'generic':'fp' , 'alt-name':'fp', },
+ { 'name':'rsp' , 'bitsize' : 64, 'offset' : 56, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 7, 'dwarf' : 7, 'generic':'sp' , 'alt-name':'sp', },
+ { 'name':'r8' , 'bitsize' : 64, 'offset' : 64, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 8, 'dwarf' : 8, 'generic':'arg5', 'alt-name':'arg5', },
+ { 'name':'r9' , 'bitsize' : 64, 'offset' : 72, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 9, 'dwarf' : 9, 'generic':'arg6', 'alt-name':'arg6', },
+ { 'name':'r10' , 'bitsize' : 64, 'offset' : 80, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 10, 'dwarf' : 10},
+ { 'name':'r11' , 'bitsize' : 64, 'offset' : 88, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 11, 'dwarf' : 11},
+ { 'name':'r12' , 'bitsize' : 64, 'offset' : 96, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 12, 'dwarf' : 12},
+ { 'name':'r13' , 'bitsize' : 64, 'offset' : 104, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 13, 'dwarf' : 13},
+ { 'name':'r14' , 'bitsize' : 64, 'offset' : 112, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 14, 'dwarf' : 14},
+ { 'name':'r15' , 'bitsize' : 64, 'offset' : 120, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 15, 'dwarf' : 15},
+ { 'name':'rip' , 'bitsize' : 64, 'offset' : 128, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 16, 'dwarf' : 16, 'generic':'pc', 'alt-name':'pc' },
+ { 'name':'rflags' , 'bitsize' : 64, 'offset' : 136, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'generic':'flags', 'alt-name':'flags' },
+ { 'name':'cs' , 'bitsize' : 64, 'offset' : 144, 'encoding':'uint' , 'format':'hex' , 'set': 0 },
+ { 'name':'fs' , 'bitsize' : 64, 'offset' : 152, 'encoding':'uint' , 'format':'hex' , 'set': 0 },
+ { 'name':'gs' , 'bitsize' : 64, 'offset' : 160, 'encoding':'uint' , 'format':'hex' , 'set': 0 },
+ ]
+ return self.registers
+
+ def get_register_data(self, tid):
+ return struct.pack('21Q',tid + 1,tid + 2,tid + 3,tid + 4,tid + 5,tid + 6,tid + 7,tid + 8,tid + 9,tid + 10,tid + 11,tid + 12,tid + 13,tid + 14,tid + 15,tid + 16,tid + 17,tid + 18,tid + 19,tid + 20,tid + 21);
+
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/Makefile b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/Makefile
new file mode 100644
index 000000000000..b3034c12abd9
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
+
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py
new file mode 100644
index 000000000000..53888502a3aa
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py
@@ -0,0 +1,128 @@
+"""
+Test basics of mini dump debugging.
+"""
+
+from __future__ import print_function
+
+
+
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class MiniDumpTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipUnlessWindows # for now mini-dump debugging is limited to Windows hosts
+ @no_debug_info_test
+ def test_process_info_in_mini_dump(self):
+ """Test that lldb can read the process information from the minidump."""
+ # target create -c fizzbuzz_no_heap.dmp
+ self.dbg.CreateTarget("")
+ self.target = self.dbg.GetSelectedTarget()
+ self.process = self.target.LoadCore("fizzbuzz_no_heap.dmp")
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+ self.assertEqual(self.process.GetNumThreads(), 1)
+ self.assertEqual(self.process.GetProcessID(), 4440)
+
+ @skipUnlessWindows # for now mini-dump debugging is limited to Windows hosts
+ @no_debug_info_test
+ def test_thread_info_in_mini_dump(self):
+ """Test that lldb can read the thread information from the minidump."""
+ # target create -c fizzbuzz_no_heap.dmp
+ self.dbg.CreateTarget("")
+ self.target = self.dbg.GetSelectedTarget()
+ self.process = self.target.LoadCore("fizzbuzz_no_heap.dmp")
+ # This process crashed due to an access violation (0xc0000005) in its one and only thread.
+ self.assertEqual(self.process.GetNumThreads(), 1)
+ thread = self.process.GetThreadAtIndex(0)
+ self.assertEqual(thread.GetStopReason(), lldb.eStopReasonException)
+ stop_description = thread.GetStopDescription(256);
+ self.assertTrue("0xc0000005" in stop_description);
+
+ @skipUnlessWindows # for now mini-dump debugging is limited to Windows hosts
+ @no_debug_info_test
+ def test_stack_info_in_mini_dump(self):
+ """Test that we can see a trivial stack in a VS-generate mini dump."""
+ # target create -c fizzbuzz_no_heap.dmp
+ self.dbg.CreateTarget("")
+ self.target = self.dbg.GetSelectedTarget()
+ self.process = self.target.LoadCore("fizzbuzz_no_heap.dmp")
+ self.assertEqual(self.process.GetNumThreads(), 1)
+ thread = self.process.GetThreadAtIndex(0)
+ # The crash is in main, so there should be one frame on the stack.
+ self.assertEqual(thread.GetNumFrames(), 1)
+ frame = thread.GetFrameAtIndex(0)
+ self.assertTrue(frame.IsValid())
+ pc = frame.GetPC()
+ eip = frame.FindRegister("pc")
+ self.assertTrue(eip.IsValid())
+ self.assertEqual(pc, eip.GetValueAsUnsigned())
+
+ @skipUnlessWindows
+ @not_remote_testsuite_ready
+ def test_deeper_stack_in_mini_dump(self):
+ """Test that we can examine a more interesting stack in a mini dump."""
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+ core = os.path.join(os.getcwd(), "core.dmp")
+ try:
+ # Set a breakpoint and capture a mini dump.
+ target = self.dbg.CreateTarget(exe)
+ breakpoint = target.BreakpointCreateByName("bar")
+ process = target.LaunchSimple(None, None, self.get_process_working_directory())
+ self.assertEqual(process.GetState(), lldb.eStateStopped)
+ self.assertTrue(process.SaveCore(core))
+ self.assertTrue(os.path.isfile(core))
+ self.assertTrue(process.Kill().Success())
+
+ # Launch with the mini dump, and inspect the stack.
+ target = self.dbg.CreateTarget(None)
+ process = target.LoadCore(core)
+ thread = process.GetThreadAtIndex(0)
+
+ expected_stack = { 0: 'bar', 1: 'foo', 2: 'main' }
+ self.assertEqual(thread.GetNumFrames(), len(expected_stack))
+ for index, name in expected_stack.iteritems():
+ frame = thread.GetFrameAtIndex(index)
+ self.assertTrue(frame.IsValid())
+ function_name = frame.GetFunctionName()
+ self.assertTrue(name in function_name)
+
+ finally:
+ # Clean up the mini dump file.
+ self.assertTrue(self.dbg.DeleteTarget(target))
+ if (os.path.isfile(core)):
+ os.unlink(core)
+
+ @skipUnlessWindows
+ @not_remote_testsuite_ready
+ def test_local_variables_in_mini_dump(self):
+ """Test that we can examine local variables in a mini dump."""
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+ core = os.path.join(os.getcwd(), "core.dmp")
+ try:
+ # Set a breakpoint and capture a mini dump.
+ target = self.dbg.CreateTarget(exe)
+ breakpoint = target.BreakpointCreateByName("bar")
+ process = target.LaunchSimple(None, None, self.get_process_working_directory())
+ self.assertEqual(process.GetState(), lldb.eStateStopped)
+ self.assertTrue(process.SaveCore(core))
+ self.assertTrue(os.path.isfile(core))
+ self.assertTrue(process.Kill().Success())
+
+ # Launch with the mini dump, and inspect a local variable.
+ target = self.dbg.CreateTarget(None)
+ process = target.LoadCore(core)
+ thread = process.GetThreadAtIndex(0)
+ frame = thread.GetFrameAtIndex(0)
+ value = frame.EvaluateExpression('x')
+ self.assertEqual(value.GetValueAsSigned(), 3)
+
+ finally:
+ # Clean up the mini dump file.
+ self.assertTrue(self.dbg.DeleteTarget(target))
+ if (os.path.isfile(core)):
+ os.unlink(core)
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/fizzbuzz.cpp b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/fizzbuzz.cpp
new file mode 100644
index 000000000000..eb6476bfd9a9
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/fizzbuzz.cpp
@@ -0,0 +1,31 @@
+// A sample program for getting minidumps on Windows.
+
+#include <iostream>
+
+bool
+fizz(int x)
+{
+ return x % 3 == 0;
+}
+
+bool
+buzz(int x)
+{
+ return x % 5 == 0;
+}
+
+int
+main()
+{
+ int *buggy = 0;
+
+ for (int i = 1; i <= 100; ++i)
+ {
+ if (fizz(i)) std::cout << "fizz";
+ if (buzz(i)) std::cout << "buzz";
+ if (!fizz(i) && !buzz(i)) std::cout << i;
+ std::cout << '\n';
+ }
+
+ return *buggy;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/fizzbuzz_no_heap.dmp b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/fizzbuzz_no_heap.dmp
new file mode 100644
index 000000000000..19008c91fc3e
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/fizzbuzz_no_heap.dmp
Binary files differ
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/main.cpp b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/main.cpp
new file mode 100644
index 000000000000..4037ea522cac
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/main.cpp
@@ -0,0 +1,21 @@
+int global = 42;
+
+int
+bar(int x)
+{
+ int y = 4*x + global;
+ return y;
+}
+
+int
+foo(int x)
+{
+ int y = 2*bar(3*x);
+ return y;
+}
+
+int
+main()
+{
+ return 0 * foo(1);
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/process_attach/Makefile b/packages/Python/lldbsuite/test/functionalities/process_attach/Makefile
new file mode 100644
index 000000000000..a964853f534b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/process_attach/Makefile
@@ -0,0 +1,7 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+EXE := ProcessAttach
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/process_attach/TestProcessAttach.py b/packages/Python/lldbsuite/test/functionalities/process_attach/TestProcessAttach.py
new file mode 100644
index 000000000000..83906b546300
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/process_attach/TestProcessAttach.py
@@ -0,0 +1,58 @@
+"""
+Test process attach.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+exe_name = "ProcessAttach" # Must match Makefile
+
+class ProcessAttachTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipIfiOSSimulator
+ def test_attach_to_process_by_id(self):
+ """Test attach by process id"""
+ self.build()
+ exe = os.path.join(os.getcwd(), exe_name)
+
+ # Spawn a new process
+ popen = self.spawnSubprocess(exe)
+ self.addTearDownHook(self.cleanupSubprocesses)
+
+ self.runCmd("process attach -p " + str(popen.pid))
+
+ target = self.dbg.GetSelectedTarget()
+
+ process = target.GetProcess()
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ def test_attach_to_process_by_name(self):
+ """Test attach by process name"""
+ self.build()
+ exe = os.path.join(os.getcwd(), exe_name)
+
+ # Spawn a new process
+ popen = self.spawnSubprocess(exe)
+ self.addTearDownHook(self.cleanupSubprocesses)
+
+ self.runCmd("process attach -n " + exe_name)
+
+ target = self.dbg.GetSelectedTarget()
+
+ process = target.GetProcess()
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ def tearDown(self):
+ # Destroy process before TestBase.tearDown()
+ self.dbg.GetSelectedTarget().GetProcess().Destroy()
+
+ # Call super's tearDown().
+ TestBase.tearDown(self)
diff --git a/packages/Python/lldbsuite/test/functionalities/process_attach/attach_denied/Makefile b/packages/Python/lldbsuite/test/functionalities/process_attach/attach_denied/Makefile
new file mode 100644
index 000000000000..87600bbccf9d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/process_attach/attach_denied/Makefile
@@ -0,0 +1,7 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+EXE := AttachDenied
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/process_attach/attach_denied/TestAttachDenied.py b/packages/Python/lldbsuite/test/functionalities/process_attach/attach_denied/TestAttachDenied.py
new file mode 100644
index 000000000000..ed9d58f90888
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/process_attach/attach_denied/TestAttachDenied.py
@@ -0,0 +1,60 @@
+"""
+Test denied process attach.
+"""
+
+from __future__ import print_function
+
+
+
+import os
+import time
+import lldb
+from lldbsuite.test.lldbtest import *
+
+exe_name = 'AttachDenied' # Must match Makefile
+
+class AttachDeniedTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def run_platform_command(self, cmd):
+ platform = self.dbg.GetSelectedPlatform()
+ shell_command = lldb.SBPlatformShellCommand(cmd)
+ err = platform.Run(shell_command)
+ return (err, shell_command.GetStatus(), shell_command.GetOutput())
+
+ @skipIfWindows
+ @skipIfiOSSimulator
+ def test_attach_to_process_by_id_denied(self):
+ """Test attach by process id denied"""
+ self.build()
+ exe = os.path.join(os.getcwd(), exe_name)
+
+ # Use a file as a synchronization point between test and inferior.
+ pid_file_path = lldbutil.append_to_process_working_directory(
+ "pid_file_%d" % (int(time.time())))
+ self.addTearDownHook(lambda: self.run_platform_command("rm %s" % (pid_file_path)))
+
+ # Spawn a new process
+ popen = self.spawnSubprocess(exe, [pid_file_path])
+ self.addTearDownHook(self.cleanupSubprocesses)
+
+ max_attempts = 5
+ for i in range(max_attempts):
+ err, retcode, msg = self.run_platform_command("ls %s" % pid_file_path)
+ if err.Success() and retcode == 0:
+ break
+ else:
+ print(msg)
+ if i < max_attempts:
+ # Exponential backoff!
+ time.sleep(pow(2, i) * 0.25)
+ else:
+ self.fail("Child PID file %s not found even after %d attempts." % (pid_file_path, max_attempts))
+ err, retcode, pid = self.run_platform_command("cat %s" % (pid_file_path))
+ self.assertTrue(err.Success() and retcode == 0,
+ "Failed to read file %s: %s, retcode: %d" % (pid_file_path, err.GetCString(), retcode))
+
+ self.expect('process attach -p ' + pid,
+ startstr = 'error: attach failed:',
+ error = True)
diff --git a/packages/Python/lldbsuite/test/functionalities/process_attach/attach_denied/main.cpp b/packages/Python/lldbsuite/test/functionalities/process_attach/attach_denied/main.cpp
new file mode 100644
index 000000000000..ff1fccae4b1c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/process_attach/attach_denied/main.cpp
@@ -0,0 +1,108 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#if defined(PTRACE_ATTACH)
+#define ATTACH_REQUEST PTRACE_ATTACH
+#define DETACH_REQUEST PTRACE_DETACH
+#elif defined(PT_ATTACH)
+#define ATTACH_REQUEST PT_ATTACH
+#define DETACH_REQUEST PT_DETACH
+#else
+#error "Unsupported platform"
+#endif
+
+bool writePid (const char* file_name, const pid_t pid)
+{
+ char *tmp_file_name = (char *)malloc(strlen(file_name) + 16);
+ strcpy(tmp_file_name, file_name);
+ strcat(tmp_file_name, "_tmp");
+ int fd = open (tmp_file_name, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR);
+ if (fd == -1)
+ {
+ fprintf (stderr, "open(%s) failed: %s\n", tmp_file_name, strerror (errno));
+ free(tmp_file_name);
+ return false;
+ }
+ char buffer[64];
+ snprintf (buffer, sizeof(buffer), "%ld", (long)pid);
+
+ bool res = true;
+ if (write (fd, buffer, strlen (buffer)) == -1)
+ {
+ fprintf (stderr, "write(%s) failed: %s\n", buffer, strerror (errno));
+ res = false;
+ }
+ close (fd);
+
+ if (rename (tmp_file_name, file_name) == -1)
+ {
+ fprintf (stderr, "rename(%s, %s) failed: %s\n", tmp_file_name, file_name, strerror (errno));
+ res = false;
+ }
+ free(tmp_file_name);
+
+ return res;
+}
+
+void signal_handler (int)
+{
+}
+
+int main (int argc, char const *argv[])
+{
+ if (argc < 2)
+ {
+ fprintf (stderr, "invalid number of command line arguments\n");
+ return 1;
+ }
+
+ const pid_t pid = fork ();
+ if (pid == -1)
+ {
+ fprintf (stderr, "fork failed: %s\n", strerror (errno));
+ return 1;
+ }
+
+ if (pid > 0)
+ {
+ // Make pause call to return when a signal is received. Normally this happens when the
+ // test runner tries to terminate us.
+ signal (SIGHUP, signal_handler);
+ signal (SIGTERM, signal_handler);
+ if (ptrace (ATTACH_REQUEST, pid, NULL, 0) == -1)
+ {
+ fprintf (stderr, "ptrace(ATTACH) failed: %s\n", strerror (errno));
+ }
+ else
+ {
+ if (writePid (argv[1], pid))
+ pause (); // Waiting for the debugger trying attach to the child.
+
+ if (ptrace (DETACH_REQUEST, pid, NULL, 0) != 0)
+ fprintf (stderr, "ptrace(DETACH) failed: %s\n", strerror (errno));
+ }
+
+ kill (pid, SIGTERM);
+ int status = 0;
+ if (waitpid (pid, &status, 0) == -1)
+ fprintf (stderr, "waitpid failed: %s\n", strerror (errno));
+ }
+ else
+ {
+ // child inferior.
+ pause ();
+ }
+
+ printf ("Exiting now\n");
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/process_attach/main.cpp b/packages/Python/lldbsuite/test/functionalities/process_attach/main.cpp
new file mode 100644
index 000000000000..8021feac5c71
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/process_attach/main.cpp
@@ -0,0 +1,37 @@
+#include <stdio.h>
+
+#if defined(__linux__)
+#include <sys/prctl.h>
+#endif
+
+#include <chrono>
+#include <thread>
+
+int main(int argc, char const *argv[]) {
+ int temp;
+#if defined(__linux__)
+ // Immediately enable any ptracer so that we can allow the stub attach
+ // operation to succeed. Some Linux kernels are locked down so that
+ // only an ancestor process can be a ptracer of a process. This disables that
+ // restriction. Without it, attach-related stub tests will fail.
+#if defined(PR_SET_PTRACER) && defined(PR_SET_PTRACER_ANY)
+ int prctl_result;
+
+ // For now we execute on best effort basis. If this fails for
+ // some reason, so be it.
+ prctl_result = prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0);
+ (void) prctl_result;
+#endif
+#endif
+
+ // Waiting to be attached by the debugger.
+ temp = 0;
+
+ while (temp < 30) // Waiting to be attached...
+ {
+ std::this_thread::sleep_for(std::chrono::seconds(2));
+ temp++;
+ }
+
+ printf("Exiting now\n");
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/process_group/Makefile b/packages/Python/lldbsuite/test/functionalities/process_group/Makefile
new file mode 100644
index 000000000000..0d70f2595019
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/process_group/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/process_group/TestChangeProcessGroup.py b/packages/Python/lldbsuite/test/functionalities/process_group/TestChangeProcessGroup.py
new file mode 100644
index 000000000000..25be37b2b12d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/process_group/TestChangeProcessGroup.py
@@ -0,0 +1,107 @@
+"""Test that we handle inferiors which change their process group"""
+
+from __future__ import print_function
+
+
+
+import os
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+
+class ChangeProcessGroupTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break for main.c.
+ self.line = line_number('main.c', '// Set breakpoint here')
+
+ @skipIfFreeBSD # Times out on FreeBSD llvm.org/pr23731
+ @skipIfWindows # setpgid call does not exist on Windows
+ @expectedFailureAndroid("http://llvm.org/pr23762", api_levels=[16])
+ def test_setpgid(self):
+ self.build()
+ exe = os.path.join(os.getcwd(), 'a.out')
+
+ # Use a file as a synchronization point between test and inferior.
+ pid_file_path = lldbutil.append_to_process_working_directory(
+ "pid_file_%d" % (int(time.time())))
+ self.addTearDownHook(lambda: self.run_platform_command("rm %s" % (pid_file_path)))
+
+ popen = self.spawnSubprocess(exe, [pid_file_path])
+ self.addTearDownHook(self.cleanupSubprocesses)
+
+ max_attempts = 5
+ for i in range(max_attempts):
+ err, retcode, msg = self.run_platform_command("ls %s" % pid_file_path)
+ if err.Success() and retcode == 0:
+ break
+ else:
+ print(msg)
+ if i < max_attempts:
+ # Exponential backoff!
+ time.sleep(pow(2, i) * 0.25)
+ else:
+ self.fail("Child PID file %s not found even after %d attempts." % (pid_file_path, max_attempts))
+
+ err, retcode, pid = self.run_platform_command("cat %s" % (pid_file_path))
+
+ self.assertTrue(err.Success() and retcode == 0,
+ "Failed to read file %s: %s, retcode: %d" % (pid_file_path, err.GetCString(), retcode))
+
+ # make sure we cleanup the forked child also
+ def cleanupChild():
+ if lldb.remote_platform:
+ lldb.remote_platform.Kill(int(pid))
+ else:
+ if os.path.exists("/proc/" + pid):
+ os.kill(int(pid), signal.SIGKILL)
+ self.addTearDownHook(cleanupChild)
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ listener = lldb.SBListener("my.attach.listener")
+ error = lldb.SBError()
+ process = target.AttachToProcessWithID(listener, int(pid), error)
+ self.assertTrue(error.Success() and process, PROCESS_IS_VALID)
+
+ # set a breakpoint just before the setpgid() call
+ lldbutil.run_break_set_by_file_and_line(self, 'main.c', self.line, num_expected_locations=-1)
+
+ thread = process.GetSelectedThread()
+
+ # release the child from its loop
+ value = thread.GetSelectedFrame().EvaluateExpression("release_child_flag = 1")
+ self.assertTrue(value.IsValid() and value.GetValueAsUnsigned(0) == 1);
+ process.Continue()
+
+ # make sure the child's process group id is different from its pid
+ value = thread.GetSelectedFrame().EvaluateExpression("(int)getpgid(0)")
+ self.assertTrue(value.IsValid())
+ self.assertNotEqual(value.GetValueAsUnsigned(0), int(pid));
+
+ # step over the setpgid() call
+ thread.StepOver()
+ self.assertEqual(thread.GetStopReason(), lldb.eStopReasonPlanComplete)
+
+ # verify that the process group has been set correctly
+ # this also checks that we are still in full control of the child
+ value = thread.GetSelectedFrame().EvaluateExpression("(int)getpgid(0)")
+ self.assertTrue(value.IsValid())
+ self.assertEqual(value.GetValueAsUnsigned(0), int(pid));
+
+ # run to completion
+ process.Continue()
+ self.assertEqual(process.GetState(), lldb.eStateExited)
+
+ def run_platform_command(self, cmd):
+ platform = self.dbg.GetSelectedPlatform()
+ shell_command = lldb.SBPlatformShellCommand(cmd)
+ err = platform.Run(shell_command)
+ return (err, shell_command.GetStatus(), shell_command.GetOutput())
diff --git a/packages/Python/lldbsuite/test/functionalities/process_group/main.c b/packages/Python/lldbsuite/test/functionalities/process_group/main.c
new file mode 100644
index 000000000000..c730c629e8b0
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/process_group/main.c
@@ -0,0 +1,86 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+#if defined(__linux__)
+#include <sys/prctl.h>
+#endif
+
+volatile int release_child_flag = 0;
+
+int main(int argc, char const *argv[])
+{
+ pid_t child = fork();
+ if (child == -1)
+ {
+ perror("fork");
+ return 1;
+ }
+
+ if (child > 0)
+ { // parent
+ if (argc < 2)
+ {
+ fprintf(stderr, "Need pid filename.\n");
+ return 2;
+ }
+
+ // Let the test suite know the child's pid.
+ FILE *pid_file = fopen(argv[1], "w");
+ if (pid_file == NULL)
+ {
+ perror("fopen");
+ return 3;
+ }
+
+ fprintf(pid_file, "%d\n", child);
+ if (fclose(pid_file) == EOF)
+ {
+ perror("fclose");
+ return 4;
+ }
+
+ // And wait for the child to finish it's work.
+ int status = 0;
+ pid_t wpid = wait(&status);
+ if (wpid == -1)
+ {
+ perror("wait");
+ return 5;
+ }
+ if (wpid != child)
+ {
+ fprintf(stderr, "wait() waited for wrong child\n");
+ return 6;
+ }
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
+ {
+ fprintf(stderr, "child did not exit correctly\n");
+ return 7;
+ }
+ }
+ else
+ { // child
+#if defined(__linux__)
+ // Immediately enable any ptracer so that we can allow the stub attach
+ // operation to succeed. Some Linux kernels are locked down so that
+ // only an ancestor process can be a ptracer of a process. This disables that
+ // restriction. Without it, attach-related stub tests will fail.
+#if defined(PR_SET_PTRACER) && defined(PR_SET_PTRACER_ANY)
+ // For now we execute on best effort basis. If this fails for
+ // some reason, so be it.
+ const int prctl_result = prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0);
+ (void) prctl_result;
+#endif
+#endif
+
+ while (! release_child_flag) // Wait for debugger to attach
+ sleep(1);
+
+ printf("Child's previous process group is: %d\n", getpgid(0));
+ setpgid(0, 0); // Set breakpoint here
+ printf("Child's process group set to: %d\n", getpgid(0));
+ }
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/process_launch/Makefile b/packages/Python/lldbsuite/test/functionalities/process_launch/Makefile
new file mode 100644
index 000000000000..313da706b4a2
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/process_launch/Makefile
@@ -0,0 +1,7 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+#CXX_SOURCES := print-cwd.cpp
+
+include $(LEVEL)/Makefile.rules
+
diff --git a/packages/Python/lldbsuite/test/functionalities/process_launch/TestProcessLaunch.py b/packages/Python/lldbsuite/test/functionalities/process_launch/TestProcessLaunch.py
new file mode 100644
index 000000000000..3131000be428
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/process_launch/TestProcessLaunch.py
@@ -0,0 +1,207 @@
+"""
+Test lldb process launch flags.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+
+class ProcessLaunchTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # disable "There is a running process, kill it and restart?" prompt
+ self.runCmd("settings set auto-confirm true")
+ self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
+
+ @not_remote_testsuite_ready
+ def test_io (self):
+ """Test that process launch I/O redirection flags work properly."""
+ self.build ()
+ exe = os.path.join (os.getcwd(), "a.out")
+ self.expect("file " + exe,
+ patterns = [ "Current executable set to .*a.out" ])
+
+ in_file = "input-file.txt"
+ out_file = "output-test.out"
+ err_file = "output-test.err"
+
+ # Make sure the output files do not exist before launching the process
+ try:
+ os.remove (out_file)
+ except OSError:
+ pass
+
+ try:
+ os.remove (err_file)
+ except OSError:
+ pass
+
+ launch_command = "process launch -i " + in_file + " -o " + out_file + " -e " + err_file
+
+ if lldb.remote_platform:
+ self.runCmd('platform put-file "{local}" "{remote}"'.format(
+ local=in_file, remote=in_file))
+
+ self.expect (launch_command,
+ patterns = [ "Process .* launched: .*a.out" ])
+
+ if lldb.remote_platform:
+ self.runCmd('platform get-file "{remote}" "{local}"'.format(
+ remote=out_file, local=out_file))
+ self.runCmd('platform get-file "{remote}" "{local}"'.format(
+ remote=err_file, local=err_file))
+
+ success = True
+ err_msg = ""
+
+ # Check to see if the 'stdout' file was created
+ try:
+ out_f = open (out_file)
+ except IOError:
+ success = False
+ err_msg = err_msg + " ERROR: stdout file was not created.\n"
+ else:
+ # Check to see if the 'stdout' file contains the right output
+ line = out_f.readline ();
+ if line != "This should go to stdout.\n":
+ success = False
+ err_msg = err_msg + " ERROR: stdout file does not contain correct output.\n"
+ out_f.close();
+
+ # Try to delete the 'stdout' file
+ try:
+ os.remove (out_file)
+ except OSError:
+ pass
+
+ # Check to see if the 'stderr' file was created
+ try:
+ err_f = open (err_file)
+ except IOError:
+ success = False
+ err_msg = err_msg + " ERROR: stderr file was not created.\n"
+ else:
+ # Check to see if the 'stderr' file contains the right output
+ line = err_f.readline ()
+ if line != "This should go to stderr.\n":
+ success = False
+ err_msg = err_msg + " ERROR: stderr file does not contain correct output.\n\
+"
+ err_f.close()
+
+ # Try to delete the 'stderr' file
+ try:
+ os.remove (err_file)
+ except OSError:
+ pass
+
+ if not success:
+ self.fail (err_msg)
+
+ # rdar://problem/9056462
+ # The process launch flag '-w' for setting the current working directory not working?
+ @not_remote_testsuite_ready
+ @expectedFailureLinux("llvm.org/pr20265")
+ def test_set_working_dir (self):
+ """Test that '-w dir' sets the working dir when running the inferior."""
+ d = {'CXX_SOURCES' : 'print_cwd.cpp'}
+ self.build(dictionary=d)
+ self.setTearDownCleanup(d)
+ exe = os.path.join (os.getcwd(), "a.out")
+ self.runCmd("file " + exe)
+
+ mywd = 'my_working_dir'
+ out_file_name = "my_working_dir_test.out"
+ err_file_name = "my_working_dir_test.err"
+
+ my_working_dir_path = os.path.join(os.getcwd(), mywd)
+ out_file_path = os.path.join(my_working_dir_path, out_file_name)
+ err_file_path = os.path.join(my_working_dir_path, err_file_name)
+
+ # Make sure the output files do not exist before launching the process
+ try:
+ os.remove (out_file_path)
+ os.remove (err_file_path)
+ except OSError:
+ pass
+
+ # Check that we get an error when we have a nonexisting path
+ launch_command = "process launch -w %s -o %s -e %s" % (my_working_dir_path + 'z',
+ out_file_path,
+ err_file_path)
+
+ self.expect(launch_command, error=True,
+ patterns = ["error:.* No such file or directory: %sz" % my_working_dir_path])
+
+ # Really launch the process
+ launch_command = "process launch -w %s -o %s -e %s" % (my_working_dir_path,
+ out_file_path,
+ err_file_path)
+
+ self.expect(launch_command,
+ patterns = [ "Process .* launched: .*a.out" ])
+
+ success = True
+ err_msg = ""
+
+ # Check to see if the 'stdout' file was created
+ try:
+ out_f = open(out_file_path)
+ except IOError:
+ success = False
+ err_msg = err_msg + "ERROR: stdout file was not created.\n"
+ else:
+ # Check to see if the 'stdout' file contains the right output
+ line = out_f.readline();
+ if self.TraceOn():
+ print("line:", line)
+ if not re.search(mywd, line):
+ success = False
+ err_msg = err_msg + "The current working directory was not set correctly.\n"
+ out_f.close();
+
+ # Try to delete the 'stdout' and 'stderr' files
+ try:
+ os.remove(out_file_path)
+ os.remove(err_file_path)
+ pass
+ except OSError:
+ pass
+
+ if not success:
+ self.fail(err_msg)
+
+ def test_environment_with_special_char (self):
+ """Test that environment variables containing '*' and '}' are communicated correctly to the lldb-server."""
+ d = {'CXX_SOURCES' : 'print_env.cpp'}
+ self.build(dictionary=d)
+ self.setTearDownCleanup(d)
+ exe = os.path.join (os.getcwd(), "a.out")
+
+ evil_var = 'INIT*MIDDLE}TAIL'
+
+ target = self.dbg.CreateTarget(exe)
+ process = target.LaunchSimple(None, ['EVIL=' + evil_var], self.get_process_working_directory())
+ self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
+
+ out = process.GetSTDOUT(len(evil_var))
+ self.assertIsNotNone(out, "Encountered an error reading the process's output")
+
+ out = out[:len(evil_var)]
+ if out != evil_var:
+ self.fail('The environment variable was mis-coded: %s\n' % repr(out))
+
+ newline = process.GetSTDOUT(1)
+ self.assertIsNotNone(newline, "Encountered an error reading the process's output")
+
+ newline = newline[0]
+ if newline != '\r' and newline != '\n':
+ self.fail('Garbage at end of environment variable')
diff --git a/packages/Python/lldbsuite/test/functionalities/process_launch/input-file.txt b/packages/Python/lldbsuite/test/functionalities/process_launch/input-file.txt
new file mode 100644
index 000000000000..cc269ba0ff8c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/process_launch/input-file.txt
@@ -0,0 +1,2 @@
+This should go to stdout.
+This should go to stderr.
diff --git a/packages/Python/lldbsuite/test/functionalities/process_launch/main.cpp b/packages/Python/lldbsuite/test/functionalities/process_launch/main.cpp
new file mode 100644
index 000000000000..f2035d551679
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/process_launch/main.cpp
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main (int argc, char **argv)
+{
+ char buffer[1024];
+
+ fgets (buffer, sizeof (buffer), stdin);
+ fprintf (stdout, "%s", buffer);
+
+
+ fgets (buffer, sizeof (buffer), stdin);
+ fprintf (stderr, "%s", buffer);
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/process_launch/my_working_dir/.keep b/packages/Python/lldbsuite/test/functionalities/process_launch/my_working_dir/.keep
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/process_launch/my_working_dir/.keep
diff --git a/packages/Python/lldbsuite/test/functionalities/process_launch/print_cwd.cpp b/packages/Python/lldbsuite/test/functionalities/process_launch/print_cwd.cpp
new file mode 100644
index 000000000000..b4b073fbcb8d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/process_launch/print_cwd.cpp
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+#ifdef _MSC_VER
+#define _CRT_NONSTDC_NO_WARNINGS
+#include <direct.h>
+#undef getcwd
+#define getcwd(buffer, length) _getcwd(buffer, length)
+#else
+#include <unistd.h>
+#endif
+
+int
+main (int argc, char **argv)
+{
+ char buffer[1024];
+
+ fprintf(stdout, "stdout: %s\n", getcwd(buffer, 1024));
+ fprintf(stderr, "stderr: %s\n", getcwd(buffer, 1024));
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/process_launch/print_env.cpp b/packages/Python/lldbsuite/test/functionalities/process_launch/print_env.cpp
new file mode 100644
index 000000000000..cbb9b2175916
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/process_launch/print_env.cpp
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int main (int argc, char **argv)
+{
+ char *evil = getenv("EVIL");
+ puts(evil);
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/process_save_core/Makefile b/packages/Python/lldbsuite/test/functionalities/process_save_core/Makefile
new file mode 100644
index 000000000000..b76d2cdb93f1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/process_save_core/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
+
diff --git a/packages/Python/lldbsuite/test/functionalities/process_save_core/TestProcessSaveCore.py b/packages/Python/lldbsuite/test/functionalities/process_save_core/TestProcessSaveCore.py
new file mode 100644
index 000000000000..0578bcf44b4c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/process_save_core/TestProcessSaveCore.py
@@ -0,0 +1,58 @@
+"""
+Test saving a core file (or mini dump).
+"""
+
+from __future__ import print_function
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+
+class ProcessSaveCoreTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @not_remote_testsuite_ready
+ @skipUnlessWindows
+ def test_cannot_save_core_unless_process_stopped(self):
+ """Test that SaveCore fails if the process isn't stopped."""
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+ core = os.path.join(os.getcwd(), "core.dmp")
+ target = self.dbg.CreateTarget(exe)
+ process = target.LaunchSimple(None, None, self.get_process_working_directory())
+ self.assertNotEqual(process.GetState(), lldb.eStateStopped)
+ error = process.SaveCore(core)
+ self.assertTrue(error.Fail())
+
+ @not_remote_testsuite_ready
+ @skipUnlessWindows
+ def test_save_windows_mini_dump(self):
+ """Test that we can save a Windows mini dump."""
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+ core = os.path.join(os.getcwd(), "core.dmp")
+ try:
+ target = self.dbg.CreateTarget(exe)
+ breakpoint = target.BreakpointCreateByName("bar")
+ process = target.LaunchSimple(None, None, self.get_process_working_directory())
+ self.assertEqual(process.GetState(), lldb.eStateStopped)
+ self.assertTrue(process.SaveCore(core))
+ self.assertTrue(os.path.isfile(core))
+ self.assertTrue(process.Kill().Success())
+
+ # To verify, we'll launch with the mini dump, and ensure that we see
+ # the executable in the module list.
+ target = self.dbg.CreateTarget(None)
+ process = target.LoadCore(core)
+ files = [target.GetModuleAtIndex(i).GetFileSpec() for i in range(0, target.GetNumModules())]
+ paths = [os.path.join(f.GetDirectory(), f.GetFilename()) for f in files]
+ self.assertTrue(exe in paths)
+
+ finally:
+ # Clean up the mini dump file.
+ self.assertTrue(self.dbg.DeleteTarget(target))
+ if (os.path.isfile(core)):
+ os.unlink(core)
+
+
diff --git a/packages/Python/lldbsuite/test/functionalities/process_save_core/main.cpp b/packages/Python/lldbsuite/test/functionalities/process_save_core/main.cpp
new file mode 100644
index 000000000000..4037ea522cac
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/process_save_core/main.cpp
@@ -0,0 +1,21 @@
+int global = 42;
+
+int
+bar(int x)
+{
+ int y = 4*x + global;
+ return y;
+}
+
+int
+foo(int x)
+{
+ int y = 2*bar(3*x);
+ return y;
+}
+
+int
+main()
+{
+ return 0 * foo(1);
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/recursion/Makefile b/packages/Python/lldbsuite/test/functionalities/recursion/Makefile
new file mode 100644
index 000000000000..8a7102e347af
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/recursion/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/recursion/TestValueObjectRecursion.py b/packages/Python/lldbsuite/test/functionalities/recursion/TestValueObjectRecursion.py
new file mode 100644
index 000000000000..fcb493bc9d95
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/recursion/TestValueObjectRecursion.py
@@ -0,0 +1,59 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class ValueObjectRecursionTestCase(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.')
+
+ def test_with_run_command(self):
+ """Test that deeply nested ValueObjects still work."""
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ root = self.frame().FindVariable("root")
+ child = root.GetChildAtIndex(1)
+ if self.TraceOn():
+ print(root)
+ print(child)
+ for i in range(0,15000):
+ child = child.GetChildAtIndex(1)
+ if self.TraceOn():
+ print(child)
+ self.assertTrue(child.IsValid(),"could not retrieve the deep ValueObject")
+ self.assertTrue(child.GetChildAtIndex(0).IsValid(),"the deep ValueObject has no value")
+ self.assertTrue(child.GetChildAtIndex(0).GetValueAsUnsigned() != 0,"the deep ValueObject has a zero value")
+ self.assertTrue(child.GetChildAtIndex(1).GetValueAsUnsigned() != 0, "the deep ValueObject has no next")
diff --git a/packages/Python/lldbsuite/test/functionalities/recursion/main.cpp b/packages/Python/lldbsuite/test/functionalities/recursion/main.cpp
new file mode 100644
index 000000000000..f75a7f8698bb
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/recursion/main.cpp
@@ -0,0 +1,41 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+struct node;
+struct node {
+ int value;
+ node* next;
+ node () : value(1),next(NULL) {}
+ node (int v) : value(v), next(NULL) {}
+};
+
+void make_tree(node* root, int count)
+{
+ int countdown=1;
+ if (!root)
+ return;
+ root->value = countdown;
+ while (count > 0)
+ {
+ root->next = new node(++countdown);
+ root = root->next;
+ count--;
+ }
+}
+
+int main (int argc, const char * argv[])
+{
+ node root(1);
+ make_tree(&root,25000);
+ return 0; // Set break point at this line.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/register/Makefile b/packages/Python/lldbsuite/test/functionalities/register/Makefile
new file mode 100644
index 000000000000..7144b25c58c9
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/register/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp a.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/register/TestRegisters.py b/packages/Python/lldbsuite/test/functionalities/register/TestRegisters.py
new file mode 100644
index 000000000000..c5d4650aa371
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/register/TestRegisters.py
@@ -0,0 +1,349 @@
+"""
+Test the 'register' command.
+"""
+
+from __future__ import print_function
+
+
+
+import os, sys, time
+import re
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class RegisterCommandsTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ TestBase.setUp(self)
+ self.has_teardown = False
+
+ def tearDown(self):
+ self.dbg.GetSelectedTarget().GetProcess().Destroy()
+ TestBase.tearDown(self)
+
+ @skipIfiOSSimulator
+ @skipUnlessArch(['amd64', 'arm', 'i386', 'x86_64'])
+ def test_register_commands(self):
+ """Test commands related to registers, in particular vector registers."""
+ self.build()
+ self.common_setup()
+
+ # verify that logging does not assert
+ self.log_enable("registers")
+
+ self.expect("register read -a", MISSING_EXPECTED_REGISTERS,
+ substrs = ['registers were unavailable'], matching = False)
+
+ if self.getArchitecture() in ['amd64', 'i386', 'x86_64']:
+ self.runCmd("register read xmm0")
+ self.runCmd("register read ymm15") # may be available
+ elif self.getArchitecture() in ['arm']:
+ self.runCmd("register read s0")
+ self.runCmd("register read q15") # may be available
+
+ self.expect("register read -s 3", substrs = ['invalid register set index: 3'], error = True)
+
+ @skipIfiOSSimulator
+ @skipIfTargetAndroid(archs=["i386"]) # Writing of mxcsr register fails, presumably due to a kernel/hardware problem
+ @skipUnlessArch(['amd64', 'arm', 'i386', 'x86_64'])
+ def test_fp_register_write(self):
+ """Test commands that write to registers, in particular floating-point registers."""
+ self.build()
+ self.fp_register_write()
+
+ @skipIfiOSSimulator
+ @expectedFailureAndroid(archs=["i386"]) # "register read fstat" always return 0xffff
+ @skipIfFreeBSD #llvm.org/pr25057
+ @skipUnlessArch(['amd64', 'i386', 'x86_64'])
+ def test_fp_special_purpose_register_read(self):
+ """Test commands that read fpu special purpose registers."""
+ self.build()
+ self.fp_special_purpose_register_read()
+
+ @skipIfiOSSimulator
+ @skipUnlessArch(['amd64', 'arm', 'i386', 'x86_64'])
+ def test_register_expressions(self):
+ """Test expression evaluation with commands related to registers."""
+ self.build()
+ self.common_setup()
+
+ if self.getArchitecture() in ['amd64', 'i386', 'x86_64']:
+ gpr = "eax"
+ vector = "xmm0"
+ elif self.getArchitecture() in ['arm']:
+ gpr = "r0"
+ vector = "q0"
+
+ self.expect("expr/x $%s" % gpr, substrs = ['unsigned int', ' = 0x'])
+ self.expect("expr $%s" % vector, substrs = ['vector_type'])
+ self.expect("expr (unsigned int)$%s[0]" % vector, substrs = ['unsigned int'])
+
+ if self.getArchitecture() in ['amd64', 'x86_64']:
+ self.expect("expr -- ($rax & 0xffffffff) == $eax", substrs = ['true'])
+
+ @skipIfiOSSimulator
+ @skipUnlessArch(['amd64', 'x86_64'])
+ def test_convenience_registers(self):
+ """Test convenience registers."""
+ self.build()
+ self.convenience_registers()
+
+ @skipIfiOSSimulator
+ @skipUnlessArch(['amd64', 'x86_64'])
+ def test_convenience_registers_with_process_attach(self):
+ """Test convenience registers after a 'process attach'."""
+ self.build()
+ self.convenience_registers_with_process_attach(test_16bit_regs=False)
+
+ @skipIfiOSSimulator
+ @skipUnlessArch(['amd64', 'x86_64'])
+ def test_convenience_registers_16bit_with_process_attach(self):
+ """Test convenience registers after a 'process attach'."""
+ self.build()
+ self.convenience_registers_with_process_attach(test_16bit_regs=True)
+
+ def common_setup(self):
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Break in main().
+ lldbutil.run_break_set_by_symbol (self, "main", num_expected_locations=-1)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped', 'stop reason = breakpoint'])
+
+ # platform specific logging of the specified category
+ def log_enable(self, category):
+ # This intentionally checks the host platform rather than the target
+ # platform as logging is host side.
+ self.platform = ""
+ if sys.platform.startswith("darwin"):
+ self.platform = "" # TODO: add support for "log enable darwin registers"
+
+ if sys.platform.startswith("freebsd"):
+ self.platform = "freebsd"
+
+ if sys.platform.startswith("linux"):
+ self.platform = "linux"
+
+ if sys.platform.startswith("netbsd"):
+ self.platform = "netbsd"
+
+ if self.platform != "":
+ self.log_file = os.path.join(os.getcwd(), 'TestRegisters.log')
+ self.runCmd("log enable " + self.platform + " " + str(category) + " registers -v -f " + self.log_file, RUN_SUCCEEDED)
+ if not self.has_teardown:
+ def remove_log(self):
+ if os.path.exists(self.log_file):
+ os.remove(self.log_file)
+ self.has_teardown = True
+ self.addTearDownHook(remove_log)
+
+ def write_and_read(self, frame, register, new_value, must_exist = True):
+ value = frame.FindValue(register, lldb.eValueTypeRegister)
+ if must_exist:
+ self.assertTrue(value.IsValid(), "finding a value for register " + register)
+ elif not value.IsValid():
+ return # If register doesn't exist, skip this test
+
+ self.runCmd("register write " + register + " \'" + new_value + "\'")
+ self.expect("register read " + register, substrs = [register + ' = ', new_value])
+
+ def fp_special_purpose_register_read(self):
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Launch the process and stop.
+ self.expect ("run", PROCESS_STOPPED, substrs = ['stopped'])
+
+ # Check stop reason; Should be either signal SIGTRAP or EXC_BREAKPOINT
+ output = self.res.GetOutput()
+ matched = False
+ substrs = ['stop reason = EXC_BREAKPOINT', 'stop reason = signal SIGTRAP']
+ for str1 in substrs:
+ matched = output.find(str1) != -1
+ with recording(self, False) as sbuf:
+ print("%s sub string: %s" % ('Expecting', str1), file=sbuf)
+ print("Matched" if matched else "Not Matched", file=sbuf)
+ if matched:
+ break
+ self.assertTrue(matched, STOPPED_DUE_TO_SIGNAL)
+
+ process = target.GetProcess()
+ self.assertTrue(process.GetState() == lldb.eStateStopped,
+ PROCESS_STOPPED)
+
+ thread = process.GetThreadAtIndex(0)
+ self.assertTrue(thread.IsValid(), "current thread is valid")
+
+ currentFrame = thread.GetFrameAtIndex(0)
+ self.assertTrue(currentFrame.IsValid(), "current frame is valid")
+
+ # Extract the value of fstat and ftag flag at the point just before
+ # we start pushing floating point values on st% register stack
+ value = currentFrame.FindValue("fstat", lldb.eValueTypeRegister)
+ error = lldb.SBError()
+ reg_value_fstat_initial = value.GetValueAsUnsigned(error, 0)
+
+ self.assertTrue(error.Success(), "reading a value for fstat")
+ value = currentFrame.FindValue("ftag", lldb.eValueTypeRegister)
+ error = lldb.SBError()
+ reg_value_ftag_initial = value.GetValueAsUnsigned(error, 0)
+
+ self.assertTrue(error.Success(), "reading a value for ftag")
+ fstat_top_pointer_initial = (reg_value_fstat_initial & 0x3800)>>11
+
+ # Execute 'si' aka 'thread step-inst' instruction 5 times and with
+ # every execution verify the value of fstat and ftag registers
+ for x in range(0,5):
+ # step into the next instruction to push a value on 'st' register stack
+ self.runCmd ("si", RUN_SUCCEEDED)
+
+ # Verify fstat and save it to be used for verification in next execution of 'si' command
+ if not (reg_value_fstat_initial & 0x3800):
+ self.expect("register read fstat",
+ substrs = ['fstat' + ' = ', str("0x%0.4x" %((reg_value_fstat_initial & ~(0x3800))| 0x3800))])
+ reg_value_fstat_initial = ((reg_value_fstat_initial & ~(0x3800))| 0x3800)
+ fstat_top_pointer_initial = 7
+ else :
+ self.expect("register read fstat",
+ substrs = ['fstat' + ' = ', str("0x%0.4x" % (reg_value_fstat_initial - 0x0800))])
+ reg_value_fstat_initial = (reg_value_fstat_initial - 0x0800)
+ fstat_top_pointer_initial -= 1
+
+ # Verify ftag and save it to be used for verification in next execution of 'si' command
+ self.expect("register read ftag",
+ substrs = ['ftag' + ' = ', str("0x%0.2x" % (reg_value_ftag_initial | (1<< fstat_top_pointer_initial)))])
+ reg_value_ftag_initial = reg_value_ftag_initial | (1<< fstat_top_pointer_initial)
+
+ def fp_register_write(self):
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ lldbutil.run_break_set_by_symbol (self, "main", num_expected_locations=-1)
+
+ # Launch the process, and do not stop at the entry point.
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ process = target.GetProcess()
+ self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED)
+
+ thread = process.GetThreadAtIndex(0)
+ self.assertTrue(thread.IsValid(), "current thread is valid")
+
+ currentFrame = thread.GetFrameAtIndex(0)
+ self.assertTrue(currentFrame.IsValid(), "current frame is valid")
+
+ if self.getArchitecture() in ['amd64', 'i386', 'x86_64']:
+ reg_list = [
+ # reg value must-have
+ ("fcw", "0x0000ff0e", False),
+ ("fsw", "0x0000ff0e", False),
+ ("ftw", "0x0000ff0e", False),
+ ("ip", "0x0000ff0e", False),
+ ("dp", "0x0000ff0e", False),
+ ("mxcsr", "0x0000ff0e", False),
+ ("mxcsrmask", "0x0000ff0e", False),
+ ]
+
+ st0regname = None
+ if currentFrame.FindRegister("st0").IsValid():
+ st0regname = "st0"
+ elif currentFrame.FindRegister("stmm0").IsValid():
+ st0regname = "stmm0"
+ if st0regname is not None:
+ # reg value must-have
+ reg_list.append((st0regname, "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00}", True))
+ reg_list.append(("xmm0", "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x09 0x0a 0x2f 0x2f 0x2f 0x2f 0x2f 0x2f}", True))
+ reg_list.append(("xmm15", "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x09 0x0a 0x2f 0x2f 0x2f 0x2f 0x0e 0x0f}", False))
+ elif self.getArchitecture() in ['arm']:
+ reg_list = [
+ # reg value must-have
+ ("fpscr", "0xfbf79f9f", True),
+ ("s0", "1.25", True),
+ ("s31", "0.75", True),
+ ("d1", "123", True),
+ ("d17", "987", False),
+ ("q1", "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x09 0x0a 0x2f 0x2f 0x2f 0x2f 0x2f 0x2f}", True),
+ ("q14", "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x09 0x0a 0x2f 0x2f 0x2f 0x2f 0x0e 0x0f}", False),
+ ]
+
+ for (reg, val, must) in reg_list:
+ self.write_and_read(currentFrame, reg, val, must)
+
+ if self.getArchitecture() in ['amd64', 'i386', 'x86_64']:
+ self.runCmd("register write " + st0regname + " \"{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}\"")
+ self.expect("register read " + st0regname + " --format f", substrs = [st0regname + ' = 0'])
+
+ has_avx = False
+ registerSets = currentFrame.GetRegisters() # Returns an SBValueList.
+ for registerSet in registerSets:
+ if 'advanced vector extensions' in registerSet.GetName().lower():
+ has_avx = True
+ break
+
+ if has_avx:
+ new_value = "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x09 0x0a 0x2f 0x2f 0x2f 0x2f 0x0e 0x0f 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0c 0x0d 0x0e 0x0f}"
+ self.write_and_read(currentFrame, "ymm0", new_value)
+ self.write_and_read(currentFrame, "ymm7", new_value)
+ self.expect("expr $ymm0", substrs = ['vector_type'])
+ else:
+ self.runCmd("register read ymm0")
+
+ def convenience_registers(self):
+ """Test convenience registers."""
+ self.common_setup()
+
+ # The command "register read -a" does output a derived register like eax...
+ self.expect("register read -a", matching=True,
+ substrs = ['eax'])
+
+ # ...however, the vanilla "register read" command should not output derived registers like eax.
+ self.expect("register read", matching=False,
+ substrs = ['eax'])
+
+ # Test reading of rax and eax.
+ self.expect("register read rax eax",
+ substrs = ['rax = 0x', 'eax = 0x'])
+
+ # Now write rax with a unique bit pattern and test that eax indeed represents the lower half of rax.
+ self.runCmd("register write rax 0x1234567887654321")
+ self.expect("register read rax 0x1234567887654321",
+ substrs = ['0x1234567887654321'])
+
+ def convenience_registers_with_process_attach(self, test_16bit_regs):
+ """Test convenience registers after a 'process attach'."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Spawn a new process
+ pid = self.spawnSubprocess(exe, ['wait_for_attach']).pid
+ self.addTearDownHook(self.cleanupSubprocesses)
+
+ if self.TraceOn():
+ print("pid of spawned process: %d" % pid)
+
+ self.runCmd("process attach -p %d" % pid)
+
+ # Check that "register read eax" works.
+ self.runCmd("register read eax")
+
+ if self.getArchitecture() in ['amd64', 'x86_64']:
+ self.expect("expr -- ($rax & 0xffffffff) == $eax",
+ substrs = ['true'])
+
+ if test_16bit_regs:
+ self.expect("expr -- $ax == (($ah << 8) | $al)",
+ substrs = ['true'])
diff --git a/packages/Python/lldbsuite/test/functionalities/register/a.cpp b/packages/Python/lldbsuite/test/functionalities/register/a.cpp
new file mode 100644
index 000000000000..fbacec1918e8
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/register/a.cpp
@@ -0,0 +1,44 @@
+//===-- a.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+long double
+return_long_double (long double value)
+{
+#if defined (__i386__) || defined (__x86_64__)
+ float a=2, b=4,c=8, d=16, e=32, f=64, k=128, l=256, add=0;
+ __asm__ (
+ "int3 ;"
+ "flds %1 ;"
+ "flds %2 ;"
+ "flds %3 ;"
+ "flds %4 ;"
+ "flds %5 ;"
+ "flds %6 ;"
+ "flds %7 ;"
+ "faddp ;" : "=g" (add) : "g" (a), "g" (b), "g" (c), "g" (d), "g" (e), "g" (f), "g" (k), "g" (l) ); // Set break point at this line.
+#endif // #if defined (__i386__) || defined (__x86_64__)
+ return value;
+}
+
+long double
+outer_return_long_double (long double value)
+{
+ long double val = return_long_double(value);
+ val *= 2 ;
+ return val;
+}
+
+long double
+outermost_return_long_double (long double value)
+{
+ long double val = outer_return_long_double(value);
+ val *= 2 ;
+ return val;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/register/main.cpp b/packages/Python/lldbsuite/test/functionalities/register/main.cpp
new file mode 100644
index 000000000000..876dd0833e54
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/register/main.cpp
@@ -0,0 +1,51 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+#if defined(__linux__)
+#include <sys/prctl.h>
+#endif
+
+#include <chrono>
+#include <thread>
+
+long double outermost_return_long_double (long double my_long_double);
+
+int main (int argc, char const *argv[])
+{
+#if defined(__linux__)
+ // Immediately enable any ptracer so that we can allow the stub attach
+ // operation to succeed. Some Linux kernels are locked down so that
+ // only an ancestor process can be a ptracer of a process. This disables that
+ // restriction. Without it, attach-related stub tests will fail.
+#if defined(PR_SET_PTRACER) && defined(PR_SET_PTRACER_ANY)
+ // For now we execute on best effort basis. If this fails for
+ // some reason, so be it.
+ const int prctl_result = prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0);
+ static_cast<void> (prctl_result);
+#endif
+#endif
+
+ char my_string[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 0};
+ double my_double = 1234.5678;
+ long double my_long_double = 1234.5678;
+
+ // For simplicity assume that any cmdline argument means wait for attach.
+ if (argc > 1)
+ {
+ volatile int wait_for_attach=1;
+ while (wait_for_attach)
+ std::this_thread::sleep_for(std::chrono::microseconds(1));
+ }
+
+ printf("my_string=%s\n", my_string);
+ printf("my_double=%g\n", my_double);
+ outermost_return_long_double (my_long_double);
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/rerun/Makefile b/packages/Python/lldbsuite/test/functionalities/rerun/Makefile
new file mode 100644
index 000000000000..8a7102e347af
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/rerun/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/rerun/TestRerun.py b/packages/Python/lldbsuite/test/functionalities/rerun/TestRerun.py
new file mode 100644
index 000000000000..0ed56de35699
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/rerun/TestRerun.py
@@ -0,0 +1,76 @@
+"""
+Test that argdumper is a viable launching strategy.
+"""
+from __future__ import print_function
+
+
+
+import lldb
+import os
+import time
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class TestRerun(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test (self):
+ self.build()
+ exe = os.path.join (os.getcwd(), "a.out")
+
+ self.runCmd("target create %s" % exe)
+
+ # Create the target
+ target = self.dbg.CreateTarget(exe)
+
+ # Create any breakpoints we need
+ breakpoint = target.BreakpointCreateBySourceRegex ('break here', lldb.SBFileSpec ("main.cpp", False))
+ self.assertTrue(breakpoint, VALID_BREAKPOINT)
+
+ self.runCmd("process launch 1 2 3")
+
+ process = self.process()
+
+ self.assertTrue(process.GetState() == lldb.eStateStopped,
+ STOPPED_DUE_TO_BREAKPOINT)
+
+ thread = process.GetThreadAtIndex (0)
+
+ self.assertTrue (thread.IsValid(),
+ "Process stopped at 'main' should have a valid thread");
+
+ stop_reason = thread.GetStopReason()
+
+ self.assertTrue (stop_reason == lldb.eStopReasonBreakpoint,
+ "Thread in process stopped in 'main' should have a stop reason of eStopReasonBreakpoint");
+
+ self.expect("frame variable argv[1]", substrs=['1'])
+ self.expect("frame variable argv[2]", substrs=['2'])
+ self.expect("frame variable argv[3]", substrs=['3'])
+
+ # Let program exit
+ self.runCmd("continue")
+
+ # Re-run with no args and make sure we still run with 1 2 3 as arguments as
+ # they should have been stored in "target.run-args"
+ self.runCmd("process launch")
+
+ process = self.process()
+
+ self.assertTrue(process.GetState() == lldb.eStateStopped,
+ STOPPED_DUE_TO_BREAKPOINT)
+
+ thread = process.GetThreadAtIndex (0)
+
+ self.assertTrue (thread.IsValid(),
+ "Process stopped at 'main' should have a valid thread");
+
+ stop_reason = thread.GetStopReason()
+
+ self.assertTrue (stop_reason == lldb.eStopReasonBreakpoint,
+ "Thread in process stopped in 'main' should have a stop reason of eStopReasonBreakpoint");
+
+ self.expect("frame variable argv[1]", substrs=['1'])
+ self.expect("frame variable argv[2]", substrs=['2'])
+ self.expect("frame variable argv[3]", substrs=['3'])
diff --git a/packages/Python/lldbsuite/test/functionalities/rerun/main.cpp b/packages/Python/lldbsuite/test/functionalities/rerun/main.cpp
new file mode 100644
index 000000000000..cbef8d1e6da1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/rerun/main.cpp
@@ -0,0 +1,5 @@
+int
+main (int argc, char const **argv)
+{
+ return 0; // break here
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/return-value/Makefile b/packages/Python/lldbsuite/test/functionalities/return-value/Makefile
new file mode 100644
index 000000000000..cb03eabfc274
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/return-value/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := call-func.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py b/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py
new file mode 100644
index 000000000000..246eb5c3fdbd
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py
@@ -0,0 +1,214 @@
+"""
+Test getting return-values correctly when stepping out
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import re
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+class ReturnValueTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureAll(oslist=["macosx","freebsd"], archs=["i386"])
+ @expectedFailureAll(oslist=["linux"], compiler="clang", compiler_version=["<=", "3.6"], archs=["i386"])
+ @expectedFailureAll(bugnumber="llvm.org/pr25785", hostoslist=["windows"], compiler="gcc", archs=["i386"], triple='.*-android')
+ @expectedFailureWindows("llvm.org/pr24778")
+ @add_test_categories(['pyapi'])
+ def test_with_python(self):
+ """Test getting return values from stepping out."""
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+ error = lldb.SBError()
+
+ self.target = self.dbg.CreateTarget(exe)
+ self.assertTrue(self.target, VALID_TARGET)
+
+ inner_sint_bkpt = self.target.BreakpointCreateByName("inner_sint", exe)
+ self.assertTrue(inner_sint_bkpt, VALID_BREAKPOINT)
+
+ # Now launch the process, and do not stop at entry point.
+ self.process = self.target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+
+ # The stop reason of the thread should be breakpoint.
+ self.assertTrue(self.process.GetState() == lldb.eStateStopped,
+ STOPPED_DUE_TO_BREAKPOINT)
+
+ # Now finish, and make sure the return value is correct.
+ thread = lldbutil.get_stopped_thread (self.process, lldb.eStopReasonBreakpoint)
+
+ # inner_sint returns the variable value, so capture that here:
+ in_int = thread.GetFrameAtIndex(0).FindVariable ("value").GetValueAsSigned(error)
+ self.assertTrue (error.Success())
+
+ thread.StepOut();
+
+ self.assertTrue (self.process.GetState() == lldb.eStateStopped)
+ self.assertTrue (thread.GetStopReason() == lldb.eStopReasonPlanComplete)
+
+ frame = thread.GetFrameAtIndex(0)
+ fun_name = frame.GetFunctionName()
+ self.assertTrue (fun_name == "outer_sint")
+
+ return_value = thread.GetStopReturnValue()
+ self.assertTrue (return_value.IsValid())
+
+ ret_int = return_value.GetValueAsSigned(error)
+ self.assertTrue (error.Success())
+ self.assertTrue (in_int == ret_int)
+
+ # Run again and we will stop in inner_sint the second time outer_sint is called.
+ #Then test stepping out two frames at once:
+
+ self.process.Continue()
+ thread_list = lldbutil.get_threads_stopped_at_breakpoint (self.process, inner_sint_bkpt)
+ self.assertTrue(len(thread_list) == 1)
+ thread = thread_list[0]
+
+ # We are done with the inner_sint breakpoint:
+ self.target.BreakpointDelete (inner_sint_bkpt.GetID())
+
+ frame = thread.GetFrameAtIndex(1)
+ fun_name = frame.GetFunctionName ()
+ self.assertTrue (fun_name == "outer_sint")
+ in_int = frame.FindVariable ("value").GetValueAsSigned(error)
+ self.assertTrue (error.Success())
+
+ thread.StepOutOfFrame (frame)
+
+ self.assertTrue (self.process.GetState() == lldb.eStateStopped)
+ self.assertTrue (thread.GetStopReason() == lldb.eStopReasonPlanComplete)
+ frame = thread.GetFrameAtIndex(0)
+ fun_name = frame.GetFunctionName()
+ self.assertTrue (fun_name == "main")
+
+ ret_value = thread.GetStopReturnValue()
+ self.assertTrue (return_value.IsValid())
+ ret_int = ret_value.GetValueAsSigned (error)
+ self.assertTrue (error.Success())
+ self.assertTrue (2 * in_int == ret_int)
+
+ # Now try some simple returns that have different types:
+ inner_float_bkpt = self.target.BreakpointCreateByName("inner_float", exe)
+ self.assertTrue(inner_float_bkpt, VALID_BREAKPOINT)
+ self.process.Continue()
+ thread_list = lldbutil.get_threads_stopped_at_breakpoint (self.process, inner_float_bkpt)
+ self.assertTrue (len(thread_list) == 1)
+ thread = thread_list[0]
+
+ self.target.BreakpointDelete (inner_float_bkpt.GetID())
+
+ frame = thread.GetFrameAtIndex(0)
+ in_value = frame.FindVariable ("value")
+ in_float = float (in_value.GetValue())
+ thread.StepOut()
+
+ self.assertTrue (self.process.GetState() == lldb.eStateStopped)
+ self.assertTrue (thread.GetStopReason() == lldb.eStopReasonPlanComplete)
+
+ frame = thread.GetFrameAtIndex(0)
+ fun_name = frame.GetFunctionName()
+ self.assertTrue (fun_name == "outer_float")
+
+ return_value = thread.GetStopReturnValue()
+ self.assertTrue (return_value.IsValid())
+ return_float = float (return_value.GetValue())
+
+ self.assertTrue(in_float == return_float)
+
+ self.return_and_test_struct_value ("return_one_int")
+ self.return_and_test_struct_value ("return_two_int")
+ self.return_and_test_struct_value ("return_three_int")
+ self.return_and_test_struct_value ("return_four_int")
+ self.return_and_test_struct_value ("return_five_int")
+
+ self.return_and_test_struct_value ("return_two_double")
+ self.return_and_test_struct_value ("return_one_double_two_float")
+ self.return_and_test_struct_value ("return_one_int_one_float_one_int")
+
+ self.return_and_test_struct_value ("return_one_pointer")
+ self.return_and_test_struct_value ("return_two_pointer")
+ self.return_and_test_struct_value ("return_one_float_one_pointer")
+ self.return_and_test_struct_value ("return_one_int_one_pointer")
+ self.return_and_test_struct_value ("return_three_short_one_float")
+
+ self.return_and_test_struct_value ("return_one_int_one_double")
+ self.return_and_test_struct_value ("return_one_int_one_double_one_int")
+ self.return_and_test_struct_value ("return_one_short_one_double_one_short")
+ self.return_and_test_struct_value ("return_one_float_one_int_one_float")
+ self.return_and_test_struct_value ("return_two_float")
+ # I am leaving out the packed test until we have a way to tell CLANG
+ # about alignment when reading DWARF for packed types.
+ #self.return_and_test_struct_value ("return_one_int_one_double_packed")
+ self.return_and_test_struct_value ("return_one_int_one_long")
+
+ # icc and gcc don't support this extension.
+ if self.getCompiler().endswith('clang'):
+ self.return_and_test_struct_value ("return_vector_size_float32_8")
+ self.return_and_test_struct_value ("return_vector_size_float32_16")
+ self.return_and_test_struct_value ("return_vector_size_float32_32")
+ self.return_and_test_struct_value ("return_ext_vector_size_float32_2")
+ self.return_and_test_struct_value ("return_ext_vector_size_float32_4")
+ self.return_and_test_struct_value ("return_ext_vector_size_float32_8")
+
+ def return_and_test_struct_value (self, func_name):
+ """Pass in the name of the function to return from - takes in value, returns value."""
+
+ # Set the breakpoint, run to it, finish out.
+ bkpt = self.target.BreakpointCreateByName (func_name)
+ self.assertTrue (bkpt.GetNumResolvedLocations() > 0)
+
+ self.process.Continue ()
+
+ thread_list = lldbutil.get_threads_stopped_at_breakpoint (self.process, bkpt)
+
+ self.assertTrue (len(thread_list) == 1)
+ thread = thread_list[0]
+
+ self.target.BreakpointDelete (bkpt.GetID())
+
+ in_value = thread.GetFrameAtIndex(0).FindVariable ("value")
+
+ self.assertTrue (in_value.IsValid())
+ num_in_children = in_value.GetNumChildren()
+
+ # This is a little hokey, but if we don't get all the children now, then
+ # once we've stepped we won't be able to get them?
+
+ for idx in range(0, num_in_children):
+ in_child = in_value.GetChildAtIndex (idx)
+ in_child_str = in_child.GetValue()
+
+ thread.StepOut()
+
+ self.assertTrue (self.process.GetState() == lldb.eStateStopped)
+ self.assertTrue (thread.GetStopReason() == lldb.eStopReasonPlanComplete)
+
+ # Assuming all these functions step out to main. Could figure out the caller dynamically
+ # if that would add something to the test.
+ frame = thread.GetFrameAtIndex(0)
+ fun_name = frame.GetFunctionName()
+ self.assertTrue (fun_name == "main")
+
+ frame = thread.GetFrameAtIndex(0)
+ ret_value = thread.GetStopReturnValue()
+
+ self.assertTrue (ret_value.IsValid())
+
+ num_ret_children = ret_value.GetNumChildren()
+ self.assertTrue (num_in_children == num_ret_children)
+ for idx in range(0, num_ret_children):
+ in_child = in_value.GetChildAtIndex(idx)
+ ret_child = ret_value.GetChildAtIndex(idx)
+ in_child_str = in_child.GetValue()
+ ret_child_str = ret_child.GetValue()
+
+ self.assertEqual(in_child_str, ret_child_str)
diff --git a/packages/Python/lldbsuite/test/functionalities/return-value/call-func.c b/packages/Python/lldbsuite/test/functionalities/return-value/call-func.c
new file mode 100644
index 000000000000..0c026ffcca17
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/return-value/call-func.c
@@ -0,0 +1,407 @@
+// Some convenient things to return:
+static char *g_first_pointer = "I am the first";
+static char *g_second_pointer = "I am the second";
+
+// First we have some simple functions that return standard types, ints, floats and doubles.
+// We have a function calling a function in a few cases to test that if you stop in the
+// inner function then do "up/fin" you get the return value from the outer-most frame.
+
+int
+inner_sint (int value)
+{
+ return value;
+}
+
+int
+outer_sint (int value)
+{
+ int outer_value = 2 * inner_sint (value);
+ return outer_value;
+}
+
+float
+inner_float (float value)
+{
+ return value;
+}
+
+float
+outer_float (float value)
+{
+ float outer_value = 2 * inner_float(value);
+ return outer_value;
+}
+
+double
+return_double (double value)
+{
+ return value;
+}
+
+long double
+return_long_double (long double value)
+{
+ return value;
+}
+
+char *
+return_pointer (char *value)
+{
+ return value;
+}
+
+struct one_int
+{
+ int one_field;
+};
+
+struct one_int
+return_one_int (struct one_int value)
+{
+ return value;
+}
+
+struct two_int
+{
+ int first_field;
+ int second_field;
+};
+
+struct two_int
+return_two_int (struct two_int value)
+{
+ return value;
+}
+
+struct three_int
+{
+ int first_field;
+ int second_field;
+ int third_field;
+};
+
+struct three_int
+return_three_int (struct three_int value)
+{
+ return value;
+}
+
+struct four_int
+{
+ int first_field;
+ int second_field;
+ int third_field;
+ int fourth_field;
+};
+
+struct four_int
+return_four_int (struct four_int value)
+{
+ return value;
+}
+
+struct five_int
+{
+ int first_field;
+ int second_field;
+ int third_field;
+ int fourth_field;
+ int fifth_field;
+};
+
+struct five_int
+return_five_int (struct five_int value)
+{
+ return value;
+}
+
+struct one_int_one_double
+{
+ int first_field;
+ double second_field;
+};
+
+struct one_int_one_double
+return_one_int_one_double (struct one_int_one_double value)
+{
+ return value;
+}
+
+struct one_int_one_double_one_int
+{
+ int one_field;
+ double second_field;
+ int third_field;
+};
+
+struct one_int_one_double_one_int
+return_one_int_one_double_one_int (struct one_int_one_double_one_int value)
+{
+ return value;
+}
+
+struct one_short_one_double_one_short
+{
+ int one_field;
+ double second_field;
+ int third_field;
+};
+
+struct one_short_one_double_one_short
+return_one_short_one_double_one_short (struct one_short_one_double_one_short value)
+{
+ return value;
+}
+
+struct three_short_one_float
+{
+ short one_field;
+ short second_field;
+ short third_field;
+ float fourth_field;
+};
+
+struct three_short_one_float
+return_three_short_one_float (struct three_short_one_float value)
+{
+ return value;
+}
+
+struct one_int_one_float_one_int
+{
+ int one_field;
+ float second_field;
+ int third_field;
+};
+
+struct one_int_one_float_one_int
+return_one_int_one_float_one_int (struct one_int_one_float_one_int value)
+{
+ return value;
+}
+
+struct one_float_one_int_one_float
+{
+ float one_field;
+ int second_field;
+ float third_field;
+};
+
+struct one_float_one_int_one_float
+return_one_float_one_int_one_float (struct one_float_one_int_one_float value)
+{
+ return value;
+}
+
+struct one_double_two_float
+{
+ double one_field;
+ float second_field;
+ float third_field;
+};
+
+struct one_double_two_float
+return_one_double_two_float (struct one_double_two_float value)
+{
+ return value;
+}
+
+struct two_double
+{
+ double first_field;
+ double second_field;
+};
+
+struct two_double
+return_two_double (struct two_double value)
+{
+ return value;
+}
+
+struct two_float
+{
+ float first_field;
+ float second_field;
+};
+
+struct two_float
+return_two_float (struct two_float value)
+{
+ return value;
+}
+
+struct one_int_one_double_packed
+{
+ int first_field;
+ double second_field;
+} __attribute__((__packed__));
+
+struct one_int_one_double_packed
+return_one_int_one_double_packed (struct one_int_one_double_packed value)
+{
+ return value;
+}
+
+struct one_int_one_long
+{
+ int first_field;
+ long second_field;
+};
+
+struct one_int_one_long
+return_one_int_one_long (struct one_int_one_long value)
+{
+ return value;
+}
+
+struct one_pointer
+{
+ char *first_field;
+};
+
+struct one_pointer
+return_one_pointer (struct one_pointer value)
+{
+ return value;
+}
+
+struct two_pointer
+{
+ char *first_field;
+ char *second_field;
+};
+
+struct two_pointer
+return_two_pointer (struct two_pointer value)
+{
+ return value;
+}
+
+struct one_float_one_pointer
+{
+ float first_field;
+ char *second_field;
+};
+
+struct one_float_one_pointer
+return_one_float_one_pointer (struct one_float_one_pointer value)
+{
+ return value;
+}
+
+struct one_int_one_pointer
+{
+ int first_field;
+ char *second_field;
+};
+
+struct one_int_one_pointer
+return_one_int_one_pointer (struct one_int_one_pointer value)
+{
+ return value;
+}
+
+typedef float vector_size_float32_8 __attribute__((__vector_size__(8)));
+typedef float vector_size_float32_16 __attribute__((__vector_size__(16)));
+typedef float vector_size_float32_32 __attribute__((__vector_size__(32)));
+
+typedef float ext_vector_size_float32_2 __attribute__((ext_vector_type(2)));
+typedef float ext_vector_size_float32_4 __attribute__((ext_vector_type(4)));
+typedef float ext_vector_size_float32_8 __attribute__((ext_vector_type(8)));
+
+vector_size_float32_8
+return_vector_size_float32_8 (vector_size_float32_8 value)
+{
+ return value;
+}
+
+vector_size_float32_16
+return_vector_size_float32_16 (vector_size_float32_16 value)
+{
+ return value;
+}
+
+vector_size_float32_32
+return_vector_size_float32_32 (vector_size_float32_32 value)
+{
+ return value;
+}
+
+ext_vector_size_float32_2
+return_ext_vector_size_float32_2 (ext_vector_size_float32_2 value)
+{
+ return value;
+}
+
+ext_vector_size_float32_4
+return_ext_vector_size_float32_4 (ext_vector_size_float32_4 value)
+{
+ return value;
+}
+
+ext_vector_size_float32_8
+return_ext_vector_size_float32_8 (ext_vector_size_float32_8 value)
+{
+ return value;
+}
+
+int
+main ()
+{
+ int first_int = 123456;
+ int second_int = 234567;
+
+ outer_sint (first_int);
+ outer_sint (second_int);
+
+ float first_float_value = 12.34;
+ float second_float_value = 23.45;
+
+ outer_float (first_float_value);
+ outer_float (second_float_value);
+
+ double double_value = -23.45;
+
+ return_double (double_value);
+
+ return_pointer(g_first_pointer);
+
+ long double long_double_value = -3456789.987654321;
+
+ return_long_double (long_double_value);
+
+ // Okay, now the structures:
+ return_one_int ((struct one_int) {10});
+ return_two_int ((struct two_int) {10, 20});
+ return_three_int ((struct three_int) {10, 20, 30});
+ return_four_int ((struct four_int) {10, 20, 30, 40});
+ return_five_int ((struct five_int) {10, 20, 30, 40, 50});
+
+ return_two_double ((struct two_double) {10.0, 20.0});
+ return_one_double_two_float ((struct one_double_two_float) {10.0, 20.0, 30.0});
+ return_one_int_one_float_one_int ((struct one_int_one_float_one_int) {10, 20.0, 30});
+
+ return_one_pointer ((struct one_pointer) {g_first_pointer});
+ return_two_pointer ((struct two_pointer) {g_first_pointer, g_second_pointer});
+ return_one_float_one_pointer ((struct one_float_one_pointer) {10.0, g_first_pointer});
+ return_one_int_one_pointer ((struct one_int_one_pointer) {10, g_first_pointer});
+ return_three_short_one_float ((struct three_short_one_float) {10, 20, 30, 40.0});
+
+ return_one_int_one_double ((struct one_int_one_double) {10, 20.0});
+ return_one_int_one_double_one_int ((struct one_int_one_double_one_int) {10, 20.0, 30});
+ return_one_short_one_double_one_short ((struct one_short_one_double_one_short) {10, 20.0, 30});
+ return_one_float_one_int_one_float ((struct one_float_one_int_one_float) {10.0, 20, 30.0});
+ return_two_float ((struct two_float) { 10.0, 20.0});
+ return_one_int_one_double_packed ((struct one_int_one_double_packed) {10, 20.0});
+ return_one_int_one_long ((struct one_int_one_long) {10, 20});
+
+ return_vector_size_float32_8 (( vector_size_float32_8 ){1.5, 2.25});
+ return_vector_size_float32_16 (( vector_size_float32_16 ){1.5, 2.25, 4.125, 8.0625});
+ return_vector_size_float32_32 (( vector_size_float32_32 ){1.5, 2.25, 4.125, 8.0625, 7.89, 8.52, 6.31, 9.12});
+
+ return_ext_vector_size_float32_2 ((ext_vector_size_float32_2){ 16.5, 32.25});
+ return_ext_vector_size_float32_4 ((ext_vector_size_float32_4){ 16.5, 32.25, 64.125, 128.0625});
+ return_ext_vector_size_float32_8 ((ext_vector_size_float32_8){ 16.5, 32.25, 64.125, 128.0625, 1.59, 3.57, 8.63, 9.12 });
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/set-data/Makefile b/packages/Python/lldbsuite/test/functionalities/set-data/Makefile
new file mode 100644
index 000000000000..9e1d63a183bc
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/set-data/Makefile
@@ -0,0 +1,7 @@
+LEVEL = ../../make
+
+OBJC_SOURCES := main.m
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation
diff --git a/packages/Python/lldbsuite/test/functionalities/set-data/TestSetData.py b/packages/Python/lldbsuite/test/functionalities/set-data/TestSetData.py
new file mode 100644
index 000000000000..3acad5f87be0
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/set-data/TestSetData.py
@@ -0,0 +1,62 @@
+"""
+Set the contents of variables and registers using raw data
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class SetDataTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipUnlessDarwin
+ def test_set_data(self):
+ """Test setting the contents of variables and registers using raw data."""
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ self.runCmd("br s -p First");
+ self.runCmd("br s -p Second");
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ self.expect("p myFoo.x", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['2'])
+
+ process = self.dbg.GetSelectedTarget().GetProcess()
+ frame = process.GetSelectedThread().GetFrameAtIndex(0)
+
+ x = frame.FindVariable("myFoo").GetChildMemberWithName("x")
+
+ my_data = lldb.SBData.CreateDataFromSInt32Array(lldb.eByteOrderLittle, 8, [4])
+ err = lldb.SBError()
+
+ self.assertTrue (x.SetData(my_data, err))
+
+ self.runCmd("continue")
+
+ self.expect("p myFoo.x", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['4'])
+
+ frame = process.GetSelectedThread().GetFrameAtIndex(0)
+
+ x = frame.FindVariable("string")
+
+ if process.GetAddressByteSize() == 8:
+ my_data = lldb.SBData.CreateDataFromUInt64Array(process.GetByteOrder(), 8, [0])
+ else:
+ my_data = lldb.SBData.CreateDataFromUInt32Array(process.GetByteOrder(), 4, [0])
+
+ err = lldb.SBError()
+
+ self.assertTrue (x.SetData(my_data, err))
+
+ self.expect("fr var -d run-target string", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['NSString *', 'nil'])
diff --git a/packages/Python/lldbsuite/test/functionalities/set-data/main.m b/packages/Python/lldbsuite/test/functionalities/set-data/main.m
new file mode 100644
index 000000000000..e1e69dc55715
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/set-data/main.m
@@ -0,0 +1,19 @@
+#import <Foundation/Foundation.h>
+
+int main ()
+{
+ @autoreleasepool
+ {
+ struct foo {
+ int x;
+ int y;
+ } myFoo;
+
+ myFoo.x = 2;
+ myFoo.y = 3; // First breakpoint
+
+ NSString *string = [NSString stringWithFormat:@"%s", "Hello world!"];
+
+ NSLog(@"%d %@", myFoo.x, string); // Second breakpoint
+ }
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/signal/Makefile b/packages/Python/lldbsuite/test/functionalities/signal/Makefile
new file mode 100644
index 000000000000..0d70f2595019
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/signal/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/signal/TestSendSignal.py b/packages/Python/lldbsuite/test/functionalities/signal/TestSendSignal.py
new file mode 100644
index 000000000000..971b82a7c75d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/signal/TestSendSignal.py
@@ -0,0 +1,105 @@
+"""Test that lldb command 'process signal SIGUSR1' to send a signal to the inferior works."""
+
+from __future__ import print_function
+
+
+
+import os, time, signal
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+
+class SendSignalTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside main().
+ self.line = line_number('main.c', 'Put breakpoint here')
+
+ @expectedFailureFreeBSD("llvm.org/pr23318: does not report running state")
+ @skipIfWindows # Windows does not support signals
+ def test_with_run_command(self):
+ """Test that lldb command 'process signal SIGUSR1' sends a signal to the inferior process."""
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Now create a breakpoint on main.c by name 'c'.
+ breakpoint = target.BreakpointCreateByLocation('main.c', self.line)
+ self.assertTrue(breakpoint and
+ breakpoint.GetNumLocations() == 1,
+ VALID_BREAKPOINT)
+
+ # Get the breakpoint location from breakpoint after we verified that,
+ # indeed, it has one location.
+ location = breakpoint.GetLocationAtIndex(0)
+ self.assertTrue(location and
+ location.IsEnabled(),
+ VALID_BREAKPOINT_LOCATION)
+
+ # Now launch the process, no arguments & do not stop at entry point.
+ launch_info = lldb.SBLaunchInfo([exe])
+ launch_info.SetWorkingDirectory(self.get_process_working_directory())
+
+ process_listener = lldb.SBListener("signal_test_listener")
+ launch_info.SetListener(process_listener)
+ error = lldb.SBError()
+ process = target.Launch(launch_info, error)
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ self.runCmd("process handle -n False -p True -s True SIGUSR1")
+
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertTrue(thread.IsValid(), "We hit the first breakpoint.")
+
+ # After resuming the process, send it a SIGUSR1 signal.
+
+ self.setAsync(True)
+
+ self.assertTrue(process_listener.IsValid(), "Got a good process listener")
+
+ # Disable our breakpoint, we don't want to hit it anymore...
+ breakpoint.SetEnabled(False)
+
+ # Now continue:
+ process.Continue()
+
+ # If running remote test, there should be a connected event
+ if lldb.remote_platform:
+ self.match_state(process_listener, lldb.eStateConnected)
+
+ self.match_state(process_listener, lldb.eStateRunning)
+
+ # Now signal the process, and make sure it stops:
+ process.Signal(lldbutil.get_signal_number('SIGUSR1'))
+
+ self.match_state(process_listener, lldb.eStateStopped)
+
+ # Now make sure the thread was stopped with a SIGUSR1:
+ threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonSignal)
+ self.assertTrue(len(threads) == 1, "One thread stopped for a signal.")
+ thread = threads[0]
+
+ self.assertTrue(thread.GetStopReasonDataCount() >= 1, "There was data in the event.")
+ self.assertTrue(thread.GetStopReasonDataAtIndex(0) == lldbutil.get_signal_number('SIGUSR1'),
+ "The stop signal was SIGUSR1")
+
+ def match_state(self, process_listener, expected_state):
+ num_seconds = 5
+ broadcaster = self.process().GetBroadcaster()
+ event_type_mask = lldb.SBProcess.eBroadcastBitStateChanged
+ event = lldb.SBEvent()
+ got_event = process_listener.WaitForEventForBroadcasterWithType(
+ num_seconds, broadcaster, event_type_mask, event)
+ self.assertTrue(got_event, "Got an event")
+ state = lldb.SBProcess.GetStateFromEvent(event)
+ self.assertTrue(state == expected_state,
+ "It was the %s state." %
+ lldb.SBDebugger_StateAsCString(expected_state))
diff --git a/packages/Python/lldbsuite/test/functionalities/signal/handle-segv/Makefile b/packages/Python/lldbsuite/test/functionalities/signal/handle-segv/Makefile
new file mode 100644
index 000000000000..b09a579159d4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/signal/handle-segv/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/signal/handle-segv/TestHandleSegv.py b/packages/Python/lldbsuite/test/functionalities/signal/handle-segv/TestHandleSegv.py
new file mode 100644
index 000000000000..feed5bfb3c76
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/signal/handle-segv/TestHandleSegv.py
@@ -0,0 +1,43 @@
+"""Test that we can debug inferiors that handle SIGSEGV by themselves"""
+
+from __future__ import print_function
+
+
+
+import os
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+import re
+
+
+class HandleSegvTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipIfWindows # signals do not exist on Windows
+ @skipIfDarwin
+ @expectedFailureFreeBSD("llvm.org/pr23699 SIGSEGV is reported as exception, not signal")
+ def test_inferior_handle_sigsegv(self):
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # launch
+ process = target.LaunchSimple(None, None, self.get_process_working_directory())
+ self.assertTrue(process, PROCESS_IS_VALID)
+ self.assertEqual(process.GetState(), lldb.eStateStopped)
+ signo = process.GetUnixSignals().GetSignalNumberFromName("SIGSEGV")
+
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal)
+ self.assertTrue(thread and thread.IsValid(), "Thread should be stopped due to a signal")
+ self.assertTrue(thread.GetStopReasonDataCount() >= 1, "There was data in the event.")
+ self.assertEqual(thread.GetStopReasonDataAtIndex(0), signo, "The stop signal was SIGSEGV")
+
+ # Continue until we exit.
+ process.Continue()
+ self.assertEqual(process.GetState(), lldb.eStateExited)
+ self.assertEqual(process.GetExitStatus(), 0)
diff --git a/packages/Python/lldbsuite/test/functionalities/signal/handle-segv/main.c b/packages/Python/lldbsuite/test/functionalities/signal/handle-segv/main.c
new file mode 100644
index 000000000000..27d9b8e500ab
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/signal/handle-segv/main.c
@@ -0,0 +1,58 @@
+#include <sys/mman.h>
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+
+enum {
+ kMmapSize = 0x1000,
+ kMagicValue = 47,
+};
+
+void *address;
+volatile sig_atomic_t signaled = 0;
+
+void handler(int sig)
+{
+ signaled = 1;
+ if (munmap(address, kMmapSize) != 0)
+ {
+ perror("munmap");
+ _exit(5);
+ }
+
+ void* newaddr = mmap(address, kMmapSize, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_FIXED | MAP_PRIVATE, -1, 0);
+ if (newaddr != address)
+ {
+ fprintf(stderr, "Newly mmaped address (%p) does not equal old address (%p).\n",
+ newaddr, address);
+ _exit(6);
+ }
+ *(int*)newaddr = kMagicValue;
+}
+
+int main()
+{
+ if (signal(SIGSEGV, handler) == SIG_ERR)
+ {
+ perror("signal");
+ return 1;
+ }
+
+ address = mmap(NULL, kMmapSize, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0);
+ if (address == MAP_FAILED)
+ {
+ perror("mmap");
+ return 2;
+ }
+
+ // This should first trigger a segfault. Our handler will make the memory readable and write
+ // the magic value into memory.
+ if (*(int*)address != kMagicValue)
+ return 3;
+
+ if (! signaled)
+ return 4;
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/signal/main.c b/packages/Python/lldbsuite/test/functionalities/signal/main.c
new file mode 100644
index 000000000000..77e760503410
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/signal/main.c
@@ -0,0 +1,27 @@
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+
+void handler_usr1 (int i)
+{
+ puts ("got signal usr1");
+}
+
+void handler_alrm (int i)
+{
+ puts ("got signal ALRM");
+}
+
+int main ()
+{
+ int i = 0;
+
+ signal (SIGUSR1, handler_usr1);
+ signal (SIGALRM, handler_alrm);
+
+ puts ("Put breakpoint here");
+
+ while (i++ < 20)
+ sleep (1);
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/signal/raise/Makefile b/packages/Python/lldbsuite/test/functionalities/signal/raise/Makefile
new file mode 100644
index 000000000000..b09a579159d4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/signal/raise/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/signal/raise/TestRaise.py b/packages/Python/lldbsuite/test/functionalities/signal/raise/TestRaise.py
new file mode 100644
index 000000000000..39e7753397d1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/signal/raise/TestRaise.py
@@ -0,0 +1,221 @@
+"""Test that we handle inferiors that send signals to themselves"""
+
+from __future__ import print_function
+
+
+
+import os
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+import re
+
+
+@skipIfWindows # signals do not exist on Windows
+class RaiseTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test_sigstop(self):
+ self.build()
+ self.signal_test('SIGSTOP', False)
+ # passing of SIGSTOP is not correctly handled, so not testing that scenario: https://llvm.org/bugs/show_bug.cgi?id=23574
+
+ @skipIfDarwin # darwin does not support real time signals
+ @skipIfTargetAndroid()
+ def test_sigsigrtmin(self):
+ self.build()
+ self.signal_test('SIGRTMIN', True)
+
+ def launch(self, target, signal):
+ # launch the process, do not stop at entry point.
+ process = target.LaunchSimple([signal], None, self.get_process_working_directory())
+ self.assertTrue(process, PROCESS_IS_VALID)
+ self.assertEqual(process.GetState(), lldb.eStateStopped)
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertTrue(thread.IsValid(), "Thread should be stopped due to a breakpoint")
+ return process
+
+ def set_handle(self, signal, pass_signal, stop_at_signal, notify_signal):
+ return_obj = lldb.SBCommandReturnObject()
+ self.dbg.GetCommandInterpreter().HandleCommand(
+ "process handle %s -p %s -s %s -n %s" % (signal, pass_signal, stop_at_signal, notify_signal),
+ return_obj)
+ self.assertTrue (return_obj.Succeeded() == True, "Setting signal handling failed")
+
+
+ def signal_test(self, signal, test_passing):
+ """Test that we handle inferior raising signals"""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+ lldbutil.run_break_set_by_symbol(self, "main")
+
+ # launch
+ process = self.launch(target, signal)
+ signo = process.GetUnixSignals().GetSignalNumberFromName(signal)
+
+ # retrieve default signal disposition
+ return_obj = lldb.SBCommandReturnObject()
+ self.dbg.GetCommandInterpreter().HandleCommand("process handle %s " % signal, return_obj)
+ match = re.match('NAME *PASS *STOP *NOTIFY.*(false|true) *(false|true) *(false|true)',
+ return_obj.GetOutput(), re.IGNORECASE | re.DOTALL)
+ if not match:
+ self.fail('Unable to retrieve default signal disposition.')
+ default_pass = match.group(1)
+ default_stop = match.group(2)
+ default_notify = match.group(3)
+
+ # Make sure we stop at the signal
+ self.set_handle(signal, "false", "true", "true")
+ process.Continue()
+ self.assertEqual(process.GetState(), lldb.eStateStopped)
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal)
+ self.assertTrue(thread.IsValid(), "Thread should be stopped due to a signal")
+ self.assertTrue(thread.GetStopReasonDataCount() >= 1, "There was data in the event.")
+ self.assertEqual(thread.GetStopReasonDataAtIndex(0), signo,
+ "The stop signal was %s" % signal)
+
+ # Continue until we exit.
+ process.Continue()
+ self.assertEqual(process.GetState(), lldb.eStateExited)
+ self.assertEqual(process.GetExitStatus(), 0)
+
+ # launch again
+ process = self.launch(target, signal)
+
+ # Make sure we do not stop at the signal. We should still get the notification.
+ self.set_handle(signal, "false", "false", "true")
+ self.expect("process continue", substrs=["stopped and restarted", signal])
+ self.assertEqual(process.GetState(), lldb.eStateExited)
+ self.assertEqual(process.GetExitStatus(), 0)
+
+ # launch again
+ process = self.launch(target, signal)
+
+ # Make sure we do not stop at the signal, and we do not get the notification.
+ self.set_handle(signal, "false", "false", "false")
+ self.expect("process continue", substrs=["stopped and restarted"], matching=False)
+ self.assertEqual(process.GetState(), lldb.eStateExited)
+ self.assertEqual(process.GetExitStatus(), 0)
+
+ if not test_passing:
+ # reset signal handling to default
+ self.set_handle(signal, default_pass, default_stop, default_notify)
+ return
+
+ # launch again
+ process = self.launch(target, signal)
+
+ # Make sure we stop at the signal
+ self.set_handle(signal, "true", "true", "true")
+ process.Continue()
+ self.assertEqual(process.GetState(), lldb.eStateStopped)
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal)
+ self.assertTrue(thread.IsValid(), "Thread should be stopped due to a signal")
+ self.assertTrue(thread.GetStopReasonDataCount() >= 1, "There was data in the event.")
+ self.assertEqual(thread.GetStopReasonDataAtIndex(0),
+ process.GetUnixSignals().GetSignalNumberFromName(signal),
+ "The stop signal was %s" % signal)
+
+ # Continue until we exit. The process should receive the signal.
+ process.Continue()
+ self.assertEqual(process.GetState(), lldb.eStateExited)
+ self.assertEqual(process.GetExitStatus(), signo)
+
+ # launch again
+ process = self.launch(target, signal)
+
+ # Make sure we do not stop at the signal. We should still get the notification. Process
+ # should receive the signal.
+ self.set_handle(signal, "true", "false", "true")
+ self.expect("process continue", substrs=["stopped and restarted", signal])
+ self.assertEqual(process.GetState(), lldb.eStateExited)
+ self.assertEqual(process.GetExitStatus(), signo)
+
+ # launch again
+ process = self.launch(target, signal)
+
+ # Make sure we do not stop at the signal, and we do not get the notification. Process
+ # should receive the signal.
+ self.set_handle(signal, "true", "false", "false")
+ self.expect("process continue", substrs=["stopped and restarted"], matching=False)
+ self.assertEqual(process.GetState(), lldb.eStateExited)
+ self.assertEqual(process.GetExitStatus(), signo)
+
+ # reset signal handling to default
+ self.set_handle(signal, default_pass, default_stop, default_notify)
+
+ @expectedFailureLinux("llvm.org/pr24530") # the signal the inferior generates gets lost
+ @expectedFailureDarwin("llvm.org/pr24530") # the signal the inferior generates gets lost
+ def test_restart_bug(self):
+ """Test that we catch a signal in the edge case where the process receives it while we are
+ about to interrupt it"""
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+ bkpt = target.BreakpointCreateByName("main")
+ self.assertTrue(bkpt.IsValid(), VALID_BREAKPOINT)
+
+ # launch the inferior and don't wait for it to stop
+ self.dbg.SetAsync(True)
+ error = lldb.SBError()
+ listener = lldb.SBListener("my listener")
+ process = target.Launch (listener,
+ ["SIGSTOP"], # argv
+ None, # envp
+ None, # stdin_path
+ None, # stdout_path
+ None, # stderr_path
+ None, # working directory
+ 0, # launch flags
+ False, # Stop at entry
+ error) # error
+
+ self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID)
+
+ event = lldb.SBEvent()
+
+ # Give the child enough time to reach the breakpoint,
+ # while clearing out all the pending events.
+ # The last WaitForEvent call will time out after 2 seconds.
+ while listener.WaitForEvent(2, event):
+ if self.TraceOn():
+ print("Process changing state to:", self.dbg.StateAsCString(process.GetStateFromEvent(event)))
+
+ # now the process should be stopped
+ self.assertEqual(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
+ self.assertEqual(len(lldbutil.get_threads_stopped_at_breakpoint(process, bkpt)), 1,
+ "A thread should be stopped at breakpoint")
+
+ # Remove all breakpoints. This makes sure we don't have to single-step over them when we
+ # resume the process below
+ target.DeleteAllBreakpoints()
+
+ # resume the process and immediately try to set another breakpoint. When using the remote
+ # stub, this will trigger a request to stop the process just as it is about to stop
+ # naturally due to a SIGSTOP signal it raises. Make sure we do not lose this signal.
+ process.Continue()
+ self.assertTrue(target.BreakpointCreateByName("handler").IsValid(), VALID_BREAKPOINT)
+
+ # Clear the events again
+ while listener.WaitForEvent(2, event):
+ if self.TraceOn():
+ print("Process changing state to:", self.dbg.StateAsCString(process.GetStateFromEvent(event)))
+
+ # The process should be stopped due to a signal
+ self.assertEqual(process.GetState(), lldb.eStateStopped)
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal)
+ self.assertTrue(thread.IsValid(), "Thread should be stopped due to a signal")
+ self.assertTrue(thread.GetStopReasonDataCount() >= 1, "There was data in the event.")
+ signo = process.GetUnixSignals().GetSignalNumberFromName("SIGSTOP")
+ self.assertEqual(thread.GetStopReasonDataAtIndex(0), signo,
+ "The stop signal was %s" % signal)
+
+ # We are done
+ process.Kill()
diff --git a/packages/Python/lldbsuite/test/functionalities/signal/raise/main.c b/packages/Python/lldbsuite/test/functionalities/signal/raise/main.c
new file mode 100644
index 000000000000..8827174e758e
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/signal/raise/main.c
@@ -0,0 +1,42 @@
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+void handler(int signo)
+{
+ _exit(signo);
+}
+
+int main (int argc, char *argv[])
+{
+#ifndef __APPLE__
+ // Real time signals not supported on apple platforms.
+ if (signal(SIGRTMIN, handler) == SIG_ERR)
+ {
+ perror("signal(SIGRTMIN)");
+ return 1;
+ }
+#endif
+
+ if (argc < 2)
+ {
+ puts("Please specify a signal to raise");
+ return 1;
+ }
+
+ if (strcmp(argv[1], "SIGSTOP") == 0)
+ raise(SIGSTOP);
+#ifndef __APPLE__
+ else if (strcmp(argv[1], "SIGRTMIN") == 0)
+ raise(SIGRTMIN);
+#endif
+ else
+ {
+ printf("Unknown signal: %s\n", argv[1]);
+ return 1;
+ }
+
+ return 0;
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/single-quote-in-filename-to-lldb/Makefile b/packages/Python/lldbsuite/test/functionalities/single-quote-in-filename-to-lldb/Makefile
new file mode 100644
index 000000000000..0d70f2595019
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/single-quote-in-filename-to-lldb/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/single-quote-in-filename-to-lldb/TestSingleQuoteInFilename.py b/packages/Python/lldbsuite/test/functionalities/single-quote-in-filename-to-lldb/TestSingleQuoteInFilename.py
new file mode 100644
index 000000000000..6a2dd74d3956
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/single-quote-in-filename-to-lldb/TestSingleQuoteInFilename.py
@@ -0,0 +1,71 @@
+"""
+Test the lldb command line takes a filename with single quote chars.
+"""
+
+from __future__ import print_function
+
+
+
+import os
+import lldb
+from lldbsuite.test.lldbtest import *
+
+class SingleQuoteInCommandLineTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+ myexe = "path with '09/a.out"
+
+ @classmethod
+ def classCleanup(cls):
+ """Cleanup the test byproducts."""
+ try:
+ os.remove("child_send.txt")
+ os.remove("child_read.txt")
+ os.remove(cls.myexe)
+ except:
+ pass
+
+ @expectedFailureHostWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @no_debug_info_test
+ def test_lldb_invocation_with_single_quote_in_filename(self):
+ """Test that 'lldb my_file_name' works where my_file_name is a string with a single quote char in it."""
+ import pexpect
+ self.buildDefault()
+ system([["cp", "a.out", "\"%s\"" % self.myexe]])
+
+ # The default lldb prompt.
+ prompt = "(lldb) "
+
+ # So that the child gets torn down after the test.
+ self.child = pexpect.spawn('%s %s "%s"' % (lldbtest_config.lldbExec, self.lldbOption, self.myexe))
+ child = self.child
+ child.setecho(True)
+ # Turn on logging for input/output to/from the child.
+ with open('child_send.txt', 'w') as f_send:
+ with open('child_read.txt', 'w') as f_read:
+ child.logfile_send = f_send
+ child.logfile_read = f_read
+
+ child.expect_exact(prompt)
+
+ child.send("help watchpoint")
+ child.sendline('')
+ child.expect_exact(prompt)
+
+ # Now that the necessary logging is done, restore logfile to None to
+ # stop further logging.
+ child.logfile_send = None
+ child.logfile_read = None
+
+ with open('child_send.txt', 'r') as fs:
+ if self.TraceOn():
+ print("\n\nContents of child_send.txt:")
+ print(fs.read())
+ with open('child_read.txt', 'r') as fr:
+ from_child = fr.read()
+ if self.TraceOn():
+ print("\n\nContents of child_read.txt:")
+ print(from_child)
+
+ self.expect(from_child, exe=False,
+ substrs = ["Current executable set to"])
diff --git a/packages/Python/lldbsuite/test/functionalities/single-quote-in-filename-to-lldb/main.c b/packages/Python/lldbsuite/test/functionalities/single-quote-in-filename-to-lldb/main.c
new file mode 100644
index 000000000000..7cee7306547a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/single-quote-in-filename-to-lldb/main.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main(int argc, const char *argv[])
+{
+ printf("Hello, world!\n");
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/single-quote-in-filename-to-lldb/path with '09/.keep b/packages/Python/lldbsuite/test/functionalities/single-quote-in-filename-to-lldb/path with '09/.keep
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/single-quote-in-filename-to-lldb/path with '09/.keep
diff --git a/packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/Makefile b/packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/Makefile
new file mode 100644
index 000000000000..45b69a5bb6eb
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/Makefile
@@ -0,0 +1,8 @@
+LEVEL = ../../make
+
+C_SOURCES := with-debug.c without-debug.c
+
+include $(LEVEL)/Makefile.rules
+
+without-debug.o: without-debug.c
+ $(CC) $(CFLAGS_NO_DEBUG) -c without-debug.c
diff --git a/packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/TestStepNoDebug.py b/packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/TestStepNoDebug.py
new file mode 100644
index 000000000000..6c1f2c3da41b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/TestStepNoDebug.py
@@ -0,0 +1,113 @@
+"""
+Test thread step-in, step-over and step-out work with the "Avoid no debug" option.
+"""
+
+from __future__ import print_function
+
+
+
+import os
+import re
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+import sys
+from lldbsuite.test.lldbtest import *
+
+class ReturnValueTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @add_test_categories(['pyapi'])
+ def test_step_out_with_python(self):
+ """Test stepping out using avoid-no-debug with dsyms."""
+ self.build()
+ self.get_to_starting_point()
+ self.do_step_out_past_nodebug()
+
+ @add_test_categories(['pyapi'])
+ @expectedFailureGcc("llvm.org/pr19247")
+ def test_step_over_with_python(self):
+ """Test stepping over using avoid-no-debug with dwarf."""
+ self.build()
+ self.get_to_starting_point()
+ self.do_step_over_past_nodebug()
+
+ @add_test_categories(['pyapi'])
+ @expectedFailureGcc("llvm.org/pr19247")
+ def test_step_in_with_python(self):
+ """Test stepping in using avoid-no-debug with dwarf."""
+ self.build()
+ self.get_to_starting_point()
+ self.do_step_in_past_nodebug()
+
+ def setUp (self):
+ TestBase.setUp(self)
+ self.main_source = "with-debug.c"
+ self.main_source_spec = lldb.SBFileSpec("with-debug.c")
+ self.dbg.HandleCommand ("settings set target.process.thread.step-out-avoid-nodebug true")
+
+ def tearDown (self):
+ self.dbg.HandleCommand ("settings set target.process.thread.step-out-avoid-nodebug false")
+ TestBase.tearDown(self)
+
+ def hit_correct_line (self, pattern):
+ target_line = line_number (self.main_source, pattern)
+ self.assertTrue (target_line != 0, "Could not find source pattern " + pattern)
+ cur_line = self.thread.frames[0].GetLineEntry().GetLine()
+ self.assertTrue (cur_line == target_line, "Stepped to line %d instead of expected %d with pattern '%s'."%(cur_line, target_line, pattern))
+
+ def hit_correct_function (self, pattern):
+ name = self.thread.frames[0].GetFunctionName()
+ self.assertTrue (pattern in name, "Got to '%s' not the expected function '%s'."%(name, pattern))
+
+ def get_to_starting_point (self):
+ exe = os.path.join(os.getcwd(), "a.out")
+ error = lldb.SBError()
+
+ self.target = self.dbg.CreateTarget(exe)
+ self.assertTrue(self.target, VALID_TARGET)
+
+ inner_bkpt = self.target.BreakpointCreateBySourceRegex("Stop here and step out of me", self.main_source_spec)
+ self.assertTrue(inner_bkpt, VALID_BREAKPOINT)
+
+ # Now launch the process, and do not stop at entry point.
+ self.process = self.target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+
+ # Now finish, and make sure the return value is correct.
+ threads = lldbutil.get_threads_stopped_at_breakpoint (self.process, inner_bkpt)
+ self.assertTrue(len(threads) == 1, "Stopped at inner breakpoint.")
+ self.thread = threads[0]
+
+ def do_step_out_past_nodebug(self):
+ # The first step out takes us to the called_from_nodebug frame, just to make sure setting
+ # step-out-avoid-nodebug doesn't change the behavior in frames with debug info.
+ self.thread.StepOut()
+ self.hit_correct_line ("intermediate_return_value = called_from_nodebug_actual(some_value)")
+ self.thread.StepOut()
+ self.hit_correct_line ("int return_value = no_debug_caller(5, called_from_nodebug)")
+
+ def do_step_over_past_nodebug (self):
+ self.thread.StepOver()
+ self.hit_correct_line ("intermediate_return_value = called_from_nodebug_actual(some_value)")
+ self.thread.StepOver()
+ self.hit_correct_line ("return intermediate_return_value")
+ self.thread.StepOver()
+ # Note, lldb doesn't follow gdb's distinction between "step-out" and "step-over/step-in"
+ # when exiting a frame. In all cases we leave the pc at the point where we exited the
+ # frame. In gdb, step-over/step-in move to the end of the line they stepped out to.
+ # If we ever change this we will need to fix this test.
+ self.hit_correct_line ("int return_value = no_debug_caller(5, called_from_nodebug)")
+
+ def do_step_in_past_nodebug (self):
+ self.thread.StepInto()
+ self.hit_correct_line ("intermediate_return_value = called_from_nodebug_actual(some_value)")
+ self.thread.StepInto()
+ self.hit_correct_line ("return intermediate_return_value")
+ self.thread.StepInto()
+ # Note, lldb doesn't follow gdb's distinction between "step-out" and "step-over/step-in"
+ # when exiting a frame. In all cases we leave the pc at the point where we exited the
+ # frame. In gdb, step-over/step-in move to the end of the line they stepped out to.
+ # If we ever change this we will need to fix this test.
+ self.hit_correct_line ("int return_value = no_debug_caller(5, called_from_nodebug)")
diff --git a/packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/with-debug.c b/packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/with-debug.c
new file mode 100644
index 000000000000..c7ac309d2c1a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/with-debug.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+
+typedef int (*debug_callee) (int);
+
+extern int no_debug_caller (int, debug_callee);
+
+int
+called_from_nodebug_actual(int some_value)
+{
+ int return_value = 0;
+ return_value = printf ("Length: %d.\n", some_value);
+ return return_value; // Stop here and step out of me
+}
+
+int
+called_from_nodebug(int some_value)
+{
+ int intermediate_return_value = 0;
+ intermediate_return_value = called_from_nodebug_actual(some_value);
+ return intermediate_return_value;
+}
+
+int
+main()
+{
+ int return_value = no_debug_caller(5, called_from_nodebug);
+ printf ("I got: %d.\n", return_value);
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/without-debug.c b/packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/without-debug.c
new file mode 100644
index 000000000000..d71d74af5e90
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/without-debug.c
@@ -0,0 +1,17 @@
+typedef int (*debug_callee) (int);
+
+int
+no_debug_caller_intermediate(int input, debug_callee callee)
+{
+ int return_value = 0;
+ return_value = callee(input);
+ return return_value;
+}
+
+int
+no_debug_caller (int input, debug_callee callee)
+{
+ int return_value = 0;
+ return_value = no_debug_caller_intermediate (input, callee);
+ return return_value;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/stop-hook/Makefile b/packages/Python/lldbsuite/test/functionalities/stop-hook/Makefile
new file mode 100644
index 000000000000..8a7102e347af
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/stop-hook/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookCmd.py b/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookCmd.py
new file mode 100644
index 000000000000..753491339c4c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookCmd.py
@@ -0,0 +1,65 @@
+"""
+Test lldb target stop-hook command.
+"""
+
+from __future__ import print_function
+
+
+
+import os
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class StopHookCmdTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line numbers inside main.cpp.
+ self.begl = line_number('main.cpp', '// Set breakpoint here to test target stop-hook.')
+ self.endl = line_number('main.cpp', '// End of the line range for which stop-hook is to be run.')
+ self.line = line_number('main.cpp', '// Another breakpoint which is outside of the stop-hook range.')
+
+ @no_debug_info_test
+ def test_not_crashing_if_no_target(self):
+ """target stop-hook list should not crash if no target has been set."""
+ self.runCmd("target stop-hook list", check=False)
+
+ def test(self):
+ """Test a sequence of target stop-hook commands."""
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.begl, num_expected_locations=1, loc_exact=True)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("target stop-hook add -f main.cpp -l %d -e %d -o 'expr ptr'" % (self.begl, self.endl))
+
+ self.expect('target stop-hook list', 'Stop Hook added successfully',
+ substrs = ['State: enabled',
+ 'expr ptr'])
+
+ self.runCmd('target stop-hook disable')
+
+ self.expect('target stop-hook list', 'Stop Hook disabled successfully',
+ substrs = ['State: disabled',
+ 'expr ptr'])
+
+ self.runCmd('target stop-hook enable')
+
+ self.expect('target stop-hook list', 'Stop Hook enabled successfully',
+ substrs = ['State: enabled',
+ 'expr ptr'])
+
+ self.runCmd("settings set auto-confirm true")
+ self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
+
+ self.runCmd('target stop-hook delete')
+
+ self.expect('target stop-hook list', 'Stop Hook deleted successfully',
+ substrs = ['No stop hooks.'])
diff --git a/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookMechanism.py b/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookMechanism.py
new file mode 100644
index 000000000000..7785d85772e2
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookMechanism.py
@@ -0,0 +1,101 @@
+"""
+Test lldb target stop-hook mechanism to see whether it fires off correctly .
+"""
+
+from __future__ import print_function
+
+
+
+import os
+import lldb
+from lldbsuite.test import configuration
+from lldbsuite.test.lldbtest import *
+
+class StopHookMechanismTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line numbers inside main.cpp.
+ self.begl = line_number('main.cpp', '// Set breakpoint here to test target stop-hook.')
+ self.endl = line_number('main.cpp', '// End of the line range for which stop-hook is to be run.')
+ self.correct_step_line = line_number ('main.cpp', '// We should stop here after stepping.')
+ self.line = line_number('main.cpp', '// Another breakpoint which is outside of the stop-hook range.')
+
+ @skipIfFreeBSD # llvm.org/pr15037
+ @expectedFlakeyLinux('llvm.org/pr15037') # stop-hooks sometimes fail to fire on Linux
+ @expectedFailureHostWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ def test(self):
+ """Test the stop-hook mechanism."""
+ self.build()
+
+ import pexpect
+ exe = os.path.join(os.getcwd(), "a.out")
+ prompt = "(lldb) "
+ add_prompt = "Enter your stop hook command(s). Type 'DONE' to end."
+ add_prompt1 = "> "
+
+ # So that the child gets torn down after the test.
+ self.child = pexpect.spawn('%s %s' % (lldbtest_config.lldbExec, self.lldbOption))
+ child = self.child
+ # Turn on logging for what the child sends back.
+ if self.TraceOn():
+ child.logfile_read = sys.stdout
+
+ if lldb.remote_platform:
+ child.expect_exact(prompt)
+ child.sendline('platform select %s' % lldb.remote_platform.GetName())
+ child.expect_exact(prompt)
+ child.sendline('platform connect %s' % configuration.lldb_platform_url)
+ child.expect_exact(prompt)
+ child.sendline('platform settings -w %s' % configuration.lldb_platform_working_dir)
+
+ child.expect_exact(prompt)
+ child.sendline('target create %s' % exe)
+
+ # Set the breakpoint, followed by the target stop-hook commands.
+ child.expect_exact(prompt)
+ child.sendline('breakpoint set -f main.cpp -l %d' % self.begl)
+ child.expect_exact(prompt)
+ child.sendline('breakpoint set -f main.cpp -l %d' % self.line)
+ child.expect_exact(prompt)
+ child.sendline('target stop-hook add -f main.cpp -l %d -e %d' % (self.begl, self.endl))
+ child.expect_exact(add_prompt)
+ child.expect_exact(add_prompt1)
+ child.sendline('expr ptr')
+ child.expect_exact(add_prompt1)
+ child.sendline('DONE')
+ child.expect_exact(prompt)
+ child.sendline('target stop-hook list')
+
+ # Now run the program, expect to stop at the first breakpoint which is within the stop-hook range.
+ child.expect_exact(prompt)
+ child.sendline('run')
+ # Make sure we see the stop hook text from the stop of the process from the run hitting the first breakpoint
+ child.expect_exact('(void *) $')
+ child.expect_exact(prompt)
+ child.sendline('thread step-over')
+ # Expecting to find the output emitted by the firing of our stop hook.
+ child.expect_exact('(void *) $')
+ # This is orthogonal to the main stop hook test, but this example shows a bug in
+ # CLANG where the line table entry for the "return -1" actually includes some code
+ # from the other branch of the if/else, so we incorrectly stop at the "return -1" line.
+ # I fixed that in lldb and I'm sticking in a test here because I don't want to have to
+ # make up a whole nother test case for it.
+ child.sendline('frame info')
+ at_line = 'at main.cpp:%d' % (self.correct_step_line)
+ print('expecting "%s"' % at_line)
+ child.expect_exact(at_line)
+
+ # Now continue the inferior, we'll stop at another breakpoint which is outside the stop-hook range.
+ child.sendline('process continue')
+ child.expect_exact('// Another breakpoint which is outside of the stop-hook range.')
+ #self.DebugPExpect(child)
+ child.sendline('thread step-over')
+ child.expect_exact('// Another breakpoint which is outside of the stop-hook range.')
+ #self.DebugPExpect(child)
+ # Verify that the 'Stop Hooks' mechanism is NOT BEING fired off.
+ self.expect(child.before, exe=False, matching=False,
+ substrs = ['(void *) $'])
diff --git a/packages/Python/lldbsuite/test/functionalities/stop-hook/main.cpp b/packages/Python/lldbsuite/test/functionalities/stop-hook/main.cpp
new file mode 100644
index 000000000000..c10c1e5ef0d2
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/stop-hook/main.cpp
@@ -0,0 +1,54 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+#include <stdlib.h>
+
+int a(int);
+int b(int);
+int c(int);
+
+int a(int val)
+{
+ if (val <= 1)
+ return b(val);
+ else if (val >= 3)
+ return c(val);
+
+ return val;
+}
+
+int b(int val)
+{
+ int rc = c(val);
+ void *ptr = malloc(1024);
+ if (!ptr) // Set breakpoint here to test target stop-hook.
+ return -1;
+ else
+ printf("ptr=%p\n", ptr); // We should stop here after stepping.
+ return rc; // End of the line range for which stop-hook is to be run.
+}
+
+int c(int val)
+{
+ return val + 3;
+}
+
+int main (int argc, char const *argv[])
+{
+ int A1 = a(1);
+ printf("a(1) returns %d\n", A1);
+
+ int C2 = c(2); // Another breakpoint which is outside of the stop-hook range.
+ printf("c(2) returns %d\n", C2);
+
+ int A3 = a(3);
+ printf("a(3) returns %d\n", A3);
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/Makefile b/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/Makefile
new file mode 100644
index 000000000000..035413ff763d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+ENABLE_THREADS := YES
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py b/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py
new file mode 100644
index 000000000000..c7fb53d495e6
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py
@@ -0,0 +1,77 @@
+"""
+Test that lldb stop-hook works for multiple threads.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test import configuration
+from lldbsuite.test.lldbtest import *
+
+class StopHookForMultipleThreadsTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Our simple source filename.
+ self.source = 'main.cpp'
+ # Find the line number to break inside main().
+ self.first_stop = line_number(self.source, '// Set break point at this line, and add a stop-hook.')
+ self.thread_function = line_number(self.source, '// Break here to test that the stop-hook mechanism works for multiple threads.')
+ # Build dictionary to have unique executable names for each test method.
+ self.exe_name = self.testMethodName
+ self.d = {'CXX_SOURCES': self.source, 'EXE': self.exe_name}
+
+ @expectedFlakeyFreeBSD("llvm.org/pr15037")
+ @expectedFlakeyLinux("llvm.org/pr15037") # stop hooks sometimes fail to fire on Linux
+ @expectedFailureHostWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ def test_stop_hook_multiple_threads(self):
+ """Test that lldb stop-hook works for multiple threads."""
+ self.build(dictionary=self.d)
+ self.setTearDownCleanup(dictionary=self.d)
+
+ import pexpect
+ exe = os.path.join(os.getcwd(), self.exe_name)
+ prompt = "(lldb) "
+
+ # So that the child gets torn down after the test.
+ self.child = pexpect.spawn('%s %s' % (lldbtest_config.lldbExec, self.lldbOption))
+ child = self.child
+ # Turn on logging for what the child sends back.
+ if self.TraceOn():
+ child.logfile_read = sys.stdout
+
+ if lldb.remote_platform:
+ child.expect_exact(prompt)
+ child.sendline('platform select %s' % lldb.remote_platform.GetName())
+ child.expect_exact(prompt)
+ child.sendline('platform connect %s' % configuration.lldb_platform_url)
+ child.expect_exact(prompt)
+ child.sendline('platform settings -w %s' % configuration.lldb_platform_working_dir)
+
+ child.expect_exact(prompt)
+ child.sendline('target create %s' % exe)
+
+ # Set the breakpoint, followed by the target stop-hook commands.
+ child.expect_exact(prompt)
+ child.sendline('breakpoint set -f main.cpp -l %d' % self.first_stop)
+ child.expect_exact(prompt)
+ child.sendline('breakpoint set -f main.cpp -l %d' % self.thread_function)
+ child.expect_exact(prompt)
+
+ # Now run the program, expect to stop at the first breakpoint which is within the stop-hook range.
+ child.sendline('run')
+ child.expect_exact("Process") # 'Process 2415 launched', 'Process 2415 stopped'
+ child.expect_exact(prompt)
+ child.sendline('target stop-hook add -o "frame variable --show-globals g_val"')
+ child.expect_exact("Stop hook") # 'Stop hook #1 added.'
+ child.expect_exact(prompt)
+
+ # Continue and expect to find the output emitted by the firing of our stop hook.
+ child.sendline('continue')
+ child.expect_exact('(uint32_t) ::g_val = ')
diff --git a/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/main.cpp b/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/main.cpp
new file mode 100644
index 000000000000..e193ae18e2c1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/main.cpp
@@ -0,0 +1,77 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <chrono>
+#include <cstdio>
+#include <mutex>
+#include <random>
+#include <thread>
+
+std::default_random_engine g_random_engine{std::random_device{}()};
+std::uniform_int_distribution<> g_distribution{0, 3000000};
+
+uint32_t g_val = 0;
+
+uint32_t
+access_pool (bool flag = false)
+{
+ static std::mutex g_access_mutex;
+ if (!flag)
+ g_access_mutex.lock();
+
+ uint32_t old_val = g_val;
+ if (flag)
+ g_val = old_val + 1;
+
+ if (!flag)
+ g_access_mutex.unlock();
+ return g_val;
+}
+
+void
+thread_func (uint32_t thread_index)
+{
+ // Break here to test that the stop-hook mechanism works for multiple threads.
+ printf ("%s (thread index = %u) startng...\n", __FUNCTION__, thread_index);
+
+ uint32_t count = 0;
+ uint32_t val;
+ while (count++ < 15)
+ {
+ // random micro second sleep from zero to 3 seconds
+ int usec = g_distribution(g_random_engine);
+ printf ("%s (thread = %u) doing a usleep (%d)...\n", __FUNCTION__, thread_index, usec);
+ std::this_thread::sleep_for(std::chrono::microseconds{usec});
+
+ if (count < 7)
+ val = access_pool ();
+ else
+ val = access_pool (true);
+
+ printf ("%s (thread = %u) after usleep access_pool returns %d (count=%d)...\n", __FUNCTION__, thread_index, val, count);
+ }
+ printf ("%s (thread index = %u) exiting...\n", __FUNCTION__, thread_index);
+}
+
+
+int main (int argc, char const *argv[])
+{
+ std::thread threads[3];
+
+ printf ("Before turning all three threads loose...\n"); // Set break point at this line, and add a stop-hook.
+ // Create 3 threads
+ for (auto &thread : threads)
+ thread = std::thread{thread_func, std::distance(threads, &thread)};
+
+ // Join all of our threads
+ for (auto &thread : threads)
+ thread.join();
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/target_command/Makefile b/packages/Python/lldbsuite/test/functionalities/target_command/Makefile
new file mode 100644
index 000000000000..9117ab9388b7
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/target_command/Makefile
@@ -0,0 +1,8 @@
+LEVEL = ../../make
+
+# Example:
+#
+# C_SOURCES := b.c
+# EXE := b.out
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/target_command/TestTargetCommand.py b/packages/Python/lldbsuite/test/functionalities/target_command/TestTargetCommand.py
new file mode 100644
index 000000000000..0ab965d2aa16
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/target_command/TestTargetCommand.py
@@ -0,0 +1,201 @@
+"""
+Test some target commands: create, list, select, variable.
+"""
+
+from __future__ import print_function
+
+
+
+import lldb
+import sys
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class targetCommandTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line numbers for our breakpoints.
+ self.line_b = line_number('b.c', '// Set break point at this line.')
+ self.line_c = line_number('c.c', '// Set break point at this line.')
+
+ def test_target_command(self):
+ """Test some target commands: create, list, select."""
+ da = {'C_SOURCES': 'a.c', 'EXE': 'a.out'}
+ self.build(dictionary=da)
+ self.addTearDownCleanup(dictionary=da)
+
+ db = {'C_SOURCES': 'b.c', 'EXE': 'b.out'}
+ self.build(dictionary=db)
+ self.addTearDownCleanup(dictionary=db)
+
+ dc = {'C_SOURCES': 'c.c', 'EXE': 'c.out'}
+ self.build(dictionary=dc)
+ self.addTearDownCleanup(dictionary=dc)
+
+ self.do_target_command()
+
+ # rdar://problem/9763907
+ # 'target variable' command fails if the target program has been run
+ @expectedFailureAndroid(archs=['aarch64'])
+ def test_target_variable_command(self):
+ """Test 'target variable' command before and after starting the inferior."""
+ d = {'C_SOURCES': 'globals.c', 'EXE': 'globals'}
+ self.build(dictionary=d)
+ self.addTearDownCleanup(dictionary=d)
+
+ self.do_target_variable_command('globals')
+
+ @expectedFailureAndroid(archs=['aarch64'])
+ def test_target_variable_command_no_fail(self):
+ """Test 'target variable' command before and after starting the inferior."""
+ d = {'C_SOURCES': 'globals.c', 'EXE': 'globals'}
+ self.build(dictionary=d)
+ self.addTearDownCleanup(dictionary=d)
+
+ self.do_target_variable_command_no_fail('globals')
+
+ def do_target_command(self):
+ """Exercise 'target create', 'target list', 'target select' commands."""
+ exe_a = os.path.join(os.getcwd(), "a.out")
+ exe_b = os.path.join(os.getcwd(), "b.out")
+ exe_c = os.path.join(os.getcwd(), "c.out")
+
+ self.runCmd("target list")
+ output = self.res.GetOutput()
+ if output.startswith("No targets"):
+ # We start from index 0.
+ base = 0
+ else:
+ # Find the largest index of the existing list.
+ import re
+ pattern = re.compile("target #(\d+):")
+ for line in reversed(output.split(os.linesep)):
+ match = pattern.search(line)
+ if match:
+ # We will start from (index + 1) ....
+ base = int(match.group(1), 10) + 1
+ #print("base is:", base)
+ break;
+
+ self.runCmd("target create " + exe_a, CURRENT_EXECUTABLE_SET)
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ self.runCmd("target create " + exe_b, CURRENT_EXECUTABLE_SET)
+ lldbutil.run_break_set_by_file_and_line (self, 'b.c', self.line_b, num_expected_locations=1, loc_exact=True)
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ self.runCmd("target create " + exe_c, CURRENT_EXECUTABLE_SET)
+ lldbutil.run_break_set_by_file_and_line (self, 'c.c', self.line_c, num_expected_locations=1, loc_exact=True)
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ self.runCmd("target list")
+
+ self.runCmd("target select %d" % base)
+ self.runCmd("thread backtrace")
+
+ self.runCmd("target select %d" % (base + 2))
+ self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['c.c:%d' % self.line_c,
+ 'stop reason = breakpoint'])
+
+ self.runCmd("target select %d" % (base + 1))
+ self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['b.c:%d' % self.line_b,
+ 'stop reason = breakpoint'])
+
+ self.runCmd("target list")
+
+ def do_target_variable_command(self, exe_name):
+ """Exercise 'target variable' command before and after starting the inferior."""
+ self.runCmd("file " + exe_name, CURRENT_EXECUTABLE_SET)
+
+ self.expect("target variable my_global_char", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ["my_global_char", "'X'"])
+ self.expect("target variable my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['my_global_str', '"abc"'])
+ self.expect("target variable my_static_int", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['my_static_int', '228'])
+ self.expect("target variable my_global_str_ptr", matching=False,
+ substrs = ['"abc"'])
+ self.expect("target variable *my_global_str_ptr", matching=True,
+ substrs = ['"abc"'])
+ self.expect("target variable *my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['a'])
+
+ self.runCmd("b main")
+ self.runCmd("run")
+
+ self.expect("target variable my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['my_global_str', '"abc"'])
+ self.expect("target variable my_static_int", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['my_static_int', '228'])
+ self.expect("target variable my_global_str_ptr", matching=False,
+ substrs = ['"abc"'])
+ self.expect("target variable *my_global_str_ptr", matching=True,
+ substrs = ['"abc"'])
+ self.expect("target variable *my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['a'])
+ self.expect("target variable my_global_char", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ["my_global_char", "'X'"])
+
+ self.runCmd("c")
+
+ # rdar://problem/9763907
+ # 'target variable' command fails if the target program has been run
+ self.expect("target variable my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['my_global_str', '"abc"'])
+ self.expect("target variable my_static_int", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['my_static_int', '228'])
+ self.expect("target variable my_global_str_ptr", matching=False,
+ substrs = ['"abc"'])
+ self.expect("target variable *my_global_str_ptr", matching=True,
+ substrs = ['"abc"'])
+ self.expect("target variable *my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['a'])
+ self.expect("target variable my_global_char", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ["my_global_char", "'X'"])
+
+ def do_target_variable_command_no_fail(self, exe_name):
+ """Exercise 'target variable' command before and after starting the inferior."""
+ self.runCmd("file " + exe_name, CURRENT_EXECUTABLE_SET)
+
+ self.expect("target variable my_global_char", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ["my_global_char", "'X'"])
+ self.expect("target variable my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['my_global_str', '"abc"'])
+ self.expect("target variable my_static_int", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['my_static_int', '228'])
+ self.expect("target variable my_global_str_ptr", matching=False,
+ substrs = ['"abc"'])
+ self.expect("target variable *my_global_str_ptr", matching=True,
+ substrs = ['"abc"'])
+ self.expect("target variable *my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['a'])
+
+ self.runCmd("b main")
+ self.runCmd("run")
+
+ # New feature: you don't need to specify the variable(s) to 'target vaiable'.
+ # It will find all the global and static variables in the current compile unit.
+ self.expect("target variable",
+ substrs = ['my_global_char',
+ 'my_global_str',
+ 'my_global_str_ptr',
+ 'my_static_int'])
+
+ self.expect("target variable my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['my_global_str', '"abc"'])
+ self.expect("target variable my_static_int", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['my_static_int', '228'])
+ self.expect("target variable my_global_str_ptr", matching=False,
+ substrs = ['"abc"'])
+ self.expect("target variable *my_global_str_ptr", matching=True,
+ substrs = ['"abc"'])
+ self.expect("target variable *my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['a'])
+ self.expect("target variable my_global_char", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ["my_global_char", "'X'"])
diff --git a/packages/Python/lldbsuite/test/functionalities/target_command/a.c b/packages/Python/lldbsuite/test/functionalities/target_command/a.c
new file mode 100644
index 000000000000..9d0706a0862d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/target_command/a.c
@@ -0,0 +1,16 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+int main(int argc, const char* argv[])
+{
+ int *null_ptr = 0;
+ printf("Hello, segfault!\n");
+ printf("Now crash %d\n", *null_ptr); // Crash here.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/target_command/b.c b/packages/Python/lldbsuite/test/functionalities/target_command/b.c
new file mode 100644
index 000000000000..62ec97f43284
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/target_command/b.c
@@ -0,0 +1,13 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int main (int argc, char const *argv[])
+{
+ return 0; // Set break point at this line.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/target_command/c.c b/packages/Python/lldbsuite/test/functionalities/target_command/c.c
new file mode 100644
index 000000000000..7c362cc437af
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/target_command/c.c
@@ -0,0 +1,29 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+int main (int argc, char const *argv[])
+{
+ enum days {
+ Monday = 10,
+ Tuesday,
+ Wednesday,
+ Thursday,
+ Friday,
+ Saturday,
+ Sunday,
+ kNumDays
+ };
+ enum days day;
+ for (day = Monday - 1; day <= kNumDays + 1; day++)
+ {
+ printf("day as int is %i\n", (int)day);
+ }
+ return 0; // Set break point at this line.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/target_command/globals.c b/packages/Python/lldbsuite/test/functionalities/target_command/globals.c
new file mode 100644
index 000000000000..6902bc415681
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/target_command/globals.c
@@ -0,0 +1,25 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+char my_global_char = 'X';
+const char* my_global_str = "abc";
+const char **my_global_str_ptr = &my_global_str;
+static int my_static_int = 228;
+
+int main (int argc, char const *argv[])
+{
+ printf("global char: %c\n", my_global_char);
+
+ printf("global str: %s\n", my_global_str);
+
+ printf("argc + my_static_int = %d\n", (argc + my_static_int));
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/Makefile b/packages/Python/lldbsuite/test/functionalities/thread/Makefile
new file mode 100644
index 000000000000..644e2971a2c1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+ENABLE_THREADS := YES
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/TestNumThreads.py b/packages/Python/lldbsuite/test/functionalities/thread/TestNumThreads.py
new file mode 100644
index 000000000000..8184ddcfbf48
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/TestNumThreads.py
@@ -0,0 +1,53 @@
+"""
+Test number of threads.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class NumberOfThreadsTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside main().
+ self.line = line_number('main.cpp', '// Set break point at this line.')
+
+ def test(self):
+ """Test number of threads."""
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # This should create a breakpoint with 1 location.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1)
+
+ # The breakpoint list should show 3 locations.
+ self.expect("breakpoint list -f", "Breakpoint location shown correctly",
+ substrs = ["1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % self.line])
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # Stopped once.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ["stop reason = breakpoint 1."])
+
+ # Get the target process
+ target = self.dbg.GetSelectedTarget()
+ process = target.GetProcess()
+
+ # Get the number of threads
+ num_threads = process.GetNumThreads()
+
+ # Using std::thread may involve extra threads, so we assert that there are
+ # at least 4 rather than exactly 4.
+ self.assertTrue(num_threads >= 4, 'Number of expected threads and actual threads do not match.')
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/Makefile b/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/Makefile
new file mode 100644
index 000000000000..24e68012ebd3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+CXXFLAGS += -std=c++11
+CXX_SOURCES := ParallelTask.cpp
+ENABLE_THREADS := YES
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/ParallelTask.cpp b/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/ParallelTask.cpp
new file mode 100755
index 000000000000..71fb8e3bb565
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/ParallelTask.cpp
@@ -0,0 +1,151 @@
+#include <cstdint>
+#include <thread>
+#include <vector>
+#include <queue>
+#include <future>
+#include <iostream>
+#include <cassert>
+
+class TaskPoolImpl
+{
+public:
+ TaskPoolImpl(uint32_t num_threads) :
+ m_stop(false)
+ {
+ for (uint32_t i = 0; i < num_threads; ++i)
+ m_threads.emplace_back(Worker, this);
+ }
+
+ ~TaskPoolImpl()
+ {
+ Stop();
+ }
+
+ template<typename F, typename... Args>
+ std::future<typename std::result_of<F(Args...)>::type>
+ AddTask(F&& f, Args&&... args)
+ {
+ auto task = std::make_shared<std::packaged_task<typename std::result_of<F(Args...)>::type()>>(
+ std::bind(std::forward<F>(f), std::forward<Args>(args)...));
+
+ std::unique_lock<std::mutex> lock(m_tasks_mutex);
+ assert(!m_stop && "Can't add task to TaskPool after it is stopped");
+ m_tasks.emplace([task](){ (*task)(); });
+ lock.unlock();
+ m_tasks_cv.notify_one();
+
+ return task->get_future();
+ }
+
+ void
+ Stop()
+ {
+ std::unique_lock<std::mutex> lock(m_tasks_mutex);
+ m_stop = true;
+ m_tasks_mutex.unlock();
+ m_tasks_cv.notify_all();
+ for (auto& t : m_threads)
+ t.join();
+ }
+
+private:
+ static void
+ Worker(TaskPoolImpl* pool)
+ {
+ while (true)
+ {
+ std::unique_lock<std::mutex> lock(pool->m_tasks_mutex);
+ if (pool->m_tasks.empty())
+ pool->m_tasks_cv.wait(lock, [pool](){ return !pool->m_tasks.empty() || pool->m_stop; });
+ if (pool->m_tasks.empty())
+ break;
+
+ std::function<void()> f = pool->m_tasks.front();
+ pool->m_tasks.pop();
+ lock.unlock();
+
+ f();
+ }
+ }
+
+ std::queue<std::function<void()>> m_tasks;
+ std::mutex m_tasks_mutex;
+ std::condition_variable m_tasks_cv;
+ bool m_stop;
+ std::vector<std::thread> m_threads;
+};
+
+class TaskPool
+{
+public:
+ // Add a new task to the thread pool and return a std::future belongs for the newly created task.
+ // The caller of this function have to wait on the future for this task to complete.
+ template<typename F, typename... Args>
+ static std::future<typename std::result_of<F(Args...)>::type>
+ AddTask(F&& f, Args&&... args)
+ {
+ return GetImplementation().AddTask(std::forward<F>(f), std::forward<Args>(args)...);
+ }
+
+ // Run all of the specified tasks on the thread pool and wait until all of them are finished
+ // before returning
+ template<typename... T>
+ static void
+ RunTasks(T&&... t)
+ {
+ RunTaskImpl<T...>::Run(std::forward<T>(t)...);
+ }
+
+private:
+ static TaskPoolImpl&
+ GetImplementation()
+ {
+ static TaskPoolImpl g_task_pool_impl(std::thread::hardware_concurrency());
+ return g_task_pool_impl;
+ }
+
+ template<typename... T>
+ struct RunTaskImpl;
+};
+
+template<typename H, typename... T>
+struct TaskPool::RunTaskImpl<H, T...>
+{
+ static void
+ Run(H&& h, T&&... t)
+ {
+ auto f = AddTask(std::forward<H>(h));
+ RunTaskImpl<T...>::Run(std::forward<T>(t)...);
+ f.wait();
+ }
+};
+
+template<>
+struct TaskPool::RunTaskImpl<>
+{
+ static void
+ Run() {}
+};
+
+int main()
+{
+ std::vector<std::future<uint32_t>> tasks;
+ for (int i = 0; i < 100000; ++i)
+ {
+ tasks.emplace_back(TaskPool::AddTask([](int i){
+ uint32_t s = 0;
+ for (int j = 0; j <= i; ++j)
+ s += j;
+ return s;
+ },
+ i));
+ }
+
+ for (auto& it : tasks) // Set breakpoint here
+ it.wait();
+
+ TaskPool::RunTasks(
+ []() { return 1; },
+ []() { return "aaaa"; }
+ );
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/TestBacktraceAll.py b/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/TestBacktraceAll.py
new file mode 100644
index 000000000000..91bc68577a43
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/TestBacktraceAll.py
@@ -0,0 +1,57 @@
+"""
+Test regression for Bug 25251.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class BreakpointAfterJoinTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number for our breakpoint.
+ self.breakpoint = line_number('ParallelTask.cpp', '// Set breakpoint here')
+
+ @skipIfTargetAndroid(archs=["arm"]) # The android-arm compiler can't compile the inferior
+ # because of an issue around std::future.
+ # TODO: Change the test to don't depend on std::future<T>
+ def test(self):
+ """Test breakpoint handling after a thread join."""
+ self.build(dictionary=self.getBuildFlags())
+
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # This should create a breakpoint
+ lldbutil.run_break_set_by_file_and_line (self, "ParallelTask.cpp", self.breakpoint, num_expected_locations=-1)
+
+ # The breakpoint list should show 1 location.
+ self.expect("breakpoint list -f", "Breakpoint location shown correctly",
+ substrs = ["1: file = 'ParallelTask.cpp', line = %d, exact_match = 0" % self.breakpoint])
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # This should not result in a segmentation fault
+ self.expect("thread backtrace all", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ["stop reason = breakpoint 1."])
+
+ # Run to completion
+ self.runCmd("continue")
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/Makefile b/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/Makefile
new file mode 100644
index 000000000000..67aa16625bff
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+ENABLE_THREADS := YES
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/TestBreakAfterJoin.py b/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/TestBreakAfterJoin.py
new file mode 100644
index 000000000000..43397a122391
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/TestBreakAfterJoin.py
@@ -0,0 +1,77 @@
+"""
+Test number of threads.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class BreakpointAfterJoinTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number for our breakpoint.
+ self.breakpoint = line_number('main.cpp', '// Set breakpoint here')
+
+ @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained
+ @expectedFailureFreeBSD("llvm.org/pr18190") # thread states not properly maintained
+ @expectedFailureLinux("llvm.org/pr15824") # thread states not properly maintained
+ def test(self):
+ """Test breakpoint handling after a thread join."""
+ self.build(dictionary=self.getBuildFlags())
+
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # This should create a breakpoint in the main thread.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.breakpoint, num_expected_locations=1)
+
+ # The breakpoint list should show 1 location.
+ self.expect("breakpoint list -f", "Breakpoint location shown correctly",
+ substrs = ["1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % self.breakpoint])
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Get the target process
+ target = self.dbg.GetSelectedTarget()
+ process = target.GetProcess()
+
+ # The exit probably occurred during breakpoint handling, but it isn't
+ # guaranteed. The main thing we're testing here is that the debugger
+ # handles this cleanly is some way.
+
+ # Get the number of threads
+ num_threads = process.GetNumThreads()
+
+ # Make sure we see at least six threads
+ self.assertTrue(num_threads >= 6, 'Number of expected threads and actual threads do not match.')
+
+ # Make sure all threads are stopped
+ for i in range(0, num_threads):
+ self.assertTrue(process.GetThreadAtIndex(i).IsStopped(),
+ "Thread {0} didn't stop during breakpoint.".format(i))
+
+ # Run to completion
+ self.runCmd("continue")
+
+ # If the process hasn't exited, collect some information
+ if process.GetState() != lldb.eStateExited:
+ self.runCmd("thread list")
+ self.runCmd("process status")
+
+ # At this point, the inferior process should have exited.
+ self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED)
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/main.cpp
new file mode 100644
index 000000000000..a63079524ee2
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/main.cpp
@@ -0,0 +1,118 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// This test is intended to create a situation in which one thread will exit
+// while a breakpoint is being handled in another thread. This may not always
+// happen because it's possible that the exiting thread will exit before the
+// breakpoint is hit. The test case should be flexible enough to treat that
+// as success.
+
+#include <atomic>
+#include <chrono>
+#include <thread>
+
+volatile int g_test = 0;
+
+// Note that although hogging the CPU while waiting for a variable to change
+// would be terrible in production code, it's great for testing since it
+// avoids a lot of messy context switching to get multiple threads synchronized.
+#define do_nothing()
+
+#define pseudo_barrier_wait(bar) \
+ --bar; \
+ while (bar > 0) \
+ do_nothing();
+
+#define pseudo_barrier_init(bar, count) (bar = count)
+
+// A barrier to synchronize all the threads.
+std::atomic_int g_barrier1;
+
+// A barrier to keep the threads from exiting until after the breakpoint has
+// been passed.
+std::atomic_int g_barrier2;
+
+void *
+break_thread_func ()
+{
+ // Wait until all the threads are running
+ pseudo_barrier_wait(g_barrier1);
+
+ // Wait for the join thread to join
+ std::this_thread::sleep_for(std::chrono::microseconds(50));
+
+ // Do something
+ g_test++; // Set breakpoint here
+
+ // Synchronize after the breakpoint
+ pseudo_barrier_wait(g_barrier2);
+
+ // Return
+ return NULL;
+}
+
+void *
+wait_thread_func ()
+{
+ // Wait until the entire first group of threads is running
+ pseudo_barrier_wait(g_barrier1);
+
+ // Wait until the breakpoint has been passed
+ pseudo_barrier_wait(g_barrier2);
+
+ // Return
+ return NULL;
+}
+
+void *
+join_thread_func (void *input)
+{
+ std::thread *thread_to_join = (std::thread *)input;
+
+ // Sync up with the rest of the threads.
+ pseudo_barrier_wait(g_barrier1);
+
+ // Join the other thread
+ thread_to_join->join();
+
+ // Return
+ return NULL;
+}
+
+int main ()
+{
+ // The first barrier waits for the non-joining threads to start.
+ // This thread will also participate in that barrier.
+ // The idea here is to guarantee that the joining thread will be
+ // last in the internal list maintained by the debugger.
+ pseudo_barrier_init(g_barrier1, 5);
+
+ // The second barrier keeps the waiting threads around until the breakpoint
+ // has been passed.
+ pseudo_barrier_init(g_barrier2, 4);
+
+ // Create a thread to hit the breakpoint
+ std::thread thread_1(break_thread_func);
+
+ // Create more threads to slow the debugger down during processing.
+ std::thread thread_2(wait_thread_func);
+ std::thread thread_3(wait_thread_func);
+ std::thread thread_4(wait_thread_func);
+
+ // Create a thread to join the breakpoint thread
+ std::thread thread_5(join_thread_func, &thread_1);
+
+ // Wait for the threads to finish
+ thread_5.join(); // implies thread_1 is already finished
+ thread_4.join();
+ thread_3.join();
+ thread_2.join();
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/Makefile b/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/Makefile
new file mode 100644
index 000000000000..469c0809aa24
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/Makefile
@@ -0,0 +1,7 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+ENABLE_THREADS := YES
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentEvents.py b/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentEvents.py
new file mode 100644
index 000000000000..9eb25b68765a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentEvents.py
@@ -0,0 +1,491 @@
+"""
+A stress-test of sorts for LLDB's handling of threads in the inferior.
+
+This test sets a breakpoint in the main thread where test parameters (numbers of
+threads) can be adjusted, runs the inferior to that point, and modifies the
+locals that control the event thread counts. This test also sets a breakpoint in
+breakpoint_func (the function executed by each 'breakpoint' thread) and a
+watchpoint on a global modified in watchpoint_func. The inferior is continued
+until exit or a crash takes place, and the number of events seen by LLDB is
+verified to match the expected number of events.
+"""
+
+from __future__ import print_function
+
+
+
+import unittest2
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+@skipIfWindows
+@expectedFailureAll(archs=['mips64', 'mips64el']) # Atomic sequences are not supported yet for MIPS in LLDB.
+class ConcurrentEventsTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ #
+ ## Tests for multiple threads that generate a single event.
+ #
+ @unittest2.skipIf(TestBase.skipLongRunningTest(), "Skip this long running test")
+ def test_many_breakpoints(self):
+ """Test 100 breakpoints from 100 threads."""
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_breakpoint_threads=100)
+
+ @unittest2.skipIf(TestBase.skipLongRunningTest(), "Skip this long running test")
+ def test_many_watchpoints(self):
+ """Test 100 watchpoints from 100 threads."""
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_watchpoint_threads=100)
+
+ @unittest2.skipIf(TestBase.skipLongRunningTest(), "Skip this long running test")
+ def test_many_signals(self):
+ """Test 100 signals from 100 threads."""
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_signal_threads=100)
+
+ @unittest2.skipIf(TestBase.skipLongRunningTest(), "Skip this long running test")
+ def test_many_crash(self):
+ """Test 100 threads that cause a segfault."""
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_crash_threads=100)
+
+
+ #
+ ## Tests for concurrent signal and breakpoint
+ #
+ @skipIfFreeBSD # timing out on buildbot
+ def test_signal_break(self):
+ """Test signal and a breakpoint in multiple threads."""
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_breakpoint_threads=1, num_signal_threads=1)
+
+ @skipIfFreeBSD # timing out on buildbot
+ def test_delay_signal_break(self):
+ """Test (1-second delay) signal and a breakpoint in multiple threads."""
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_breakpoint_threads=1, num_delay_signal_threads=1)
+
+ @skipIfFreeBSD # timing out on buildbot
+ def test_signal_delay_break(self):
+ """Test signal and a (1 second delay) breakpoint in multiple threads."""
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_delay_breakpoint_threads=1, num_signal_threads=1)
+
+
+ #
+ ## Tests for concurrent watchpoint and breakpoint
+ #
+ @skipIfFreeBSD # timing out on buildbot
+ @skipIfRemoteDueToDeadlock
+ def test_watch_break(self):
+ """Test watchpoint and a breakpoint in multiple threads."""
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_breakpoint_threads=1, num_watchpoint_threads=1)
+
+ @skipIfFreeBSD # timing out on buildbot
+ @skipIfRemoteDueToDeadlock
+ def test_delay_watch_break(self):
+ """Test (1-second delay) watchpoint and a breakpoint in multiple threads."""
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_breakpoint_threads=1, num_delay_watchpoint_threads=1)
+
+ @skipIfFreeBSD # timing out on buildbot
+ @skipIfRemoteDueToDeadlock
+ def test_watch_break_delay(self):
+ """Test watchpoint and a (1 second delay) breakpoint in multiple threads."""
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_delay_breakpoint_threads=1, num_watchpoint_threads=1)
+
+ #
+ ## Tests for concurrent signal and watchpoint
+ #
+ @skipIfFreeBSD # timing out on buildbot
+ @skipIfRemoteDueToDeadlock
+ def test_signal_watch(self):
+ """Test a watchpoint and a signal in multiple threads."""
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_signal_threads=1, num_watchpoint_threads=1)
+
+ @skipIfFreeBSD # timing out on buildbot
+ @skipIfRemoteDueToDeadlock
+ def test_delay_signal_watch(self):
+ """Test a watchpoint and a (1 second delay) signal in multiple threads."""
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_delay_signal_threads=1, num_watchpoint_threads=1)
+
+ @skipIfFreeBSD # timing out on buildbot
+ @skipIfRemoteDueToDeadlock
+ @expectedFailureAll("llvm.org/pr16714", oslist=["linux"], archs=["i386"])
+ def test_signal_delay_watch(self):
+ """Test a (1 second delay) watchpoint and a signal in multiple threads."""
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_signal_threads=1, num_delay_watchpoint_threads=1)
+
+
+ #
+ ## Tests for multiple breakpoint threads
+ #
+ @skipIfFreeBSD # timing out on buildbot
+ def test_two_breakpoint_threads(self):
+ """Test two threads that trigger a breakpoint. """
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_breakpoint_threads=2)
+
+ @skipIfFreeBSD # timing out on buildbot
+ def test_breakpoint_one_delay_breakpoint_threads(self):
+ """Test threads that trigger a breakpoint where one thread has a 1 second delay. """
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_breakpoint_threads=1,
+ num_delay_breakpoint_threads=1)
+
+ @skipIfFreeBSD # timing out on buildbot
+ def test_two_breakpoints_one_signal(self):
+ """Test two threads that trigger a breakpoint and one signal thread. """
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_breakpoint_threads=2, num_signal_threads=1)
+
+ @skipIfFreeBSD # timing out on buildbot
+ def test_breakpoint_delay_breakpoint_one_signal(self):
+ """Test two threads that trigger a breakpoint (one with a 1 second delay) and one signal thread. """
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_breakpoint_threads=1,
+ num_delay_breakpoint_threads=1,
+ num_signal_threads=1)
+
+ @skipIfFreeBSD # timing out on buildbot
+ def test_two_breakpoints_one_delay_signal(self):
+ """Test two threads that trigger a breakpoint and one (1 second delay) signal thread. """
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_breakpoint_threads=2, num_delay_signal_threads=1)
+
+ @skipIfFreeBSD # timing out on buildbot
+ @skipIfRemoteDueToDeadlock
+ def test_two_breakpoints_one_watchpoint(self):
+ """Test two threads that trigger a breakpoint and one watchpoint thread. """
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_breakpoint_threads=2, num_watchpoint_threads=1)
+
+ @skipIfFreeBSD # timing out on buildbot
+ @skipIfRemoteDueToDeadlock
+ def test_breakpoints_delayed_breakpoint_one_watchpoint(self):
+ """Test a breakpoint, a delayed breakpoint, and one watchpoint thread. """
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_breakpoint_threads=1,
+ num_delay_breakpoint_threads=1,
+ num_watchpoint_threads=1)
+
+ #
+ ## Tests for multiple watchpoint threads
+ #
+ @skipIfFreeBSD # timing out on buildbot
+ @skipIfRemoteDueToDeadlock
+ def test_two_watchpoint_threads(self):
+ """Test two threads that trigger a watchpoint. """
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_watchpoint_threads=2)
+
+ @skipIfFreeBSD # timing out on buildbot
+ @skipIfRemoteDueToDeadlock
+ def test_watchpoint_with_delay_watchpoint_threads(self):
+ """Test two threads that trigger a watchpoint where one thread has a 1 second delay. """
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_watchpoint_threads=1,
+ num_delay_watchpoint_threads=1)
+
+ @skipIfFreeBSD # timing out on buildbot
+ @skipIfRemoteDueToDeadlock
+ def test_two_watchpoints_one_breakpoint(self):
+ """Test two threads that trigger a watchpoint and one breakpoint thread. """
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_watchpoint_threads=2, num_breakpoint_threads=1)
+
+ @skipIfFreeBSD # timing out on buildbot
+ @skipIfRemoteDueToDeadlock
+ def test_two_watchpoints_one_delay_breakpoint(self):
+ """Test two threads that trigger a watchpoint and one (1 second delay) breakpoint thread. """
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_watchpoint_threads=2, num_delay_breakpoint_threads=1)
+
+ @skipIfFreeBSD # timing out on buildbot
+ @skipIfRemoteDueToDeadlock
+ def test_watchpoint_delay_watchpoint_one_breakpoint(self):
+ """Test two threads that trigger a watchpoint (one with a 1 second delay) and one breakpoint thread. """
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_watchpoint_threads=1,
+ num_delay_watchpoint_threads=1,
+ num_breakpoint_threads=1)
+
+ @skipIfFreeBSD # timing out on buildbot
+ @skipIfRemoteDueToDeadlock
+ def test_two_watchpoints_one_signal(self):
+ """Test two threads that trigger a watchpoint and one signal thread. """
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_watchpoint_threads=2, num_signal_threads=1)
+
+ #
+ ## Test for watchpoint, signal and breakpoint happening concurrently
+ #
+ @skipIfFreeBSD # timing out on buildbot
+ @skipIfRemoteDueToDeadlock
+ def test_signal_watch_break(self):
+ """Test a signal/watchpoint/breakpoint in multiple threads."""
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_signal_threads=1,
+ num_watchpoint_threads=1,
+ num_breakpoint_threads=1)
+
+ @skipIfFreeBSD # timing out on buildbot
+ @skipIfRemoteDueToDeadlock
+ def test_signal_watch_break(self):
+ """Test one signal thread with 5 watchpoint and breakpoint threads."""
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_signal_threads=1,
+ num_watchpoint_threads=5,
+ num_breakpoint_threads=5)
+
+ @skipIfFreeBSD # timing out on buildbot
+ @skipIfRemoteDueToDeadlock
+ def test_signal_watch_break(self):
+ """Test with 5 watchpoint and breakpoint threads."""
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_watchpoint_threads=5,
+ num_breakpoint_threads=5)
+
+
+ #
+ ## Test for crashing threads happening concurrently with other events
+ #
+ @skipIfFreeBSD # timing out on buildbot
+ def test_crash_with_break(self):
+ """ Test a thread that crashes while another thread hits a breakpoint."""
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_crash_threads=1, num_breakpoint_threads=1)
+
+ @skipIfFreeBSD # timing out on buildbot
+ @skipIfRemoteDueToDeadlock
+ def test_crash_with_watchpoint(self):
+ """ Test a thread that crashes while another thread hits a watchpoint."""
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_crash_threads=1, num_watchpoint_threads=1)
+
+ @skipIfFreeBSD # timing out on buildbot
+ def test_crash_with_signal(self):
+ """ Test a thread that crashes while another thread generates a signal."""
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_crash_threads=1, num_signal_threads=1)
+
+ @skipIfFreeBSD # timing out on buildbot
+ @skipIfRemoteDueToDeadlock
+ def test_crash_with_watchpoint_breakpoint_signal(self):
+ """ Test a thread that crashes while other threads generate a signal and hit a watchpoint and breakpoint. """
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_crash_threads=1,
+ num_breakpoint_threads=1,
+ num_signal_threads=1,
+ num_watchpoint_threads=1)
+
+ @skipIfFreeBSD # timing out on buildbot
+ @skipIfRemoteDueToDeadlock
+ def test_delayed_crash_with_breakpoint_watchpoint(self):
+ """ Test a thread with a delayed crash while other threads hit a watchpoint and a breakpoint. """
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_delay_crash_threads=1,
+ num_breakpoint_threads=1,
+ num_watchpoint_threads=1)
+
+ @skipIfFreeBSD # timing out on buildbot
+ def test_delayed_crash_with_breakpoint_signal(self):
+ """ Test a thread with a delayed crash while other threads generate a signal and hit a breakpoint. """
+ self.build(dictionary=self.getBuildFlags())
+ self.do_thread_actions(num_delay_crash_threads=1,
+ num_breakpoint_threads=1,
+ num_signal_threads=1)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number for our breakpoint.
+ self.filename = 'main.cpp'
+ self.thread_breakpoint_line = line_number(self.filename, '// Set breakpoint here')
+ self.setup_breakpoint_line = line_number(self.filename, '// Break here and adjust num')
+ self.finish_breakpoint_line = line_number(self.filename, '// Break here and verify one thread is active')
+
+ def describe_threads(self):
+ ret = []
+ for x in self.inferior_process:
+ id = x.GetIndexID()
+ reason = x.GetStopReason()
+ status = "stopped" if x.IsStopped() else "running"
+ reason_str = lldbutil.stop_reason_to_str(reason)
+ if reason == lldb.eStopReasonBreakpoint:
+ bpid = x.GetStopReasonDataAtIndex(0)
+ bp = self.inferior_target.FindBreakpointByID(bpid)
+ reason_str = "%s hit %d times" % (lldbutil.get_description(bp), bp.GetHitCount())
+ elif reason == lldb.eStopReasonWatchpoint:
+ watchid = x.GetStopReasonDataAtIndex(0)
+ watch = self.inferior_target.FindWatchpointByID(watchid)
+ reason_str = "%s hit %d times" % (lldbutil.get_description(watch), watch.GetHitCount())
+ elif reason == lldb.eStopReasonSignal:
+ signals = self.inferior_process.GetUnixSignals()
+ signal_name = signals.GetSignalAsCString(x.GetStopReasonDataAtIndex(0))
+ reason_str = "signal %s" % signal_name
+
+ location = "\t".join([lldbutil.get_description(x.GetFrameAtIndex(i)) for i in range(x.GetNumFrames())])
+ ret.append("thread %d %s due to %s at\n\t%s" % (id, status, reason_str, location))
+ return ret
+
+ def add_breakpoint(self, line, descriptions):
+ """ Adds a breakpoint at self.filename:line and appends its description to descriptions, and
+ returns the LLDB SBBreakpoint object.
+ """
+
+ bpno = lldbutil.run_break_set_by_file_and_line(self, self.filename, line, num_expected_locations=-1)
+ bp = self.inferior_target.FindBreakpointByID(bpno)
+ descriptions.append(": file = 'main.cpp', line = %d" % self.finish_breakpoint_line)
+ return bp
+
+ def inferior_done(self):
+ """ Returns true if the inferior is done executing all the event threads (and is stopped at self.finish_breakpoint,
+ or has terminated execution.
+ """
+ return self.finish_breakpoint.GetHitCount() > 0 or \
+ self.crash_count > 0 or \
+ self.inferior_process.GetState() == lldb.eStateExited
+
+ def count_signaled_threads(self):
+ count = 0
+ for thread in self.inferior_process:
+ if thread.GetStopReason() == lldb.eStopReasonSignal and thread.GetStopReasonDataAtIndex(0) == self.inferior_process.GetUnixSignals().GetSignalNumberFromName('SIGUSR1'):
+ count += 1
+ return count
+
+ def do_thread_actions(self,
+ num_breakpoint_threads = 0,
+ num_signal_threads = 0,
+ num_watchpoint_threads = 0,
+ num_crash_threads = 0,
+ num_delay_breakpoint_threads = 0,
+ num_delay_signal_threads = 0,
+ num_delay_watchpoint_threads = 0,
+ num_delay_crash_threads = 0):
+ """ Sets a breakpoint in the main thread where test parameters (numbers of threads) can be adjusted, runs the inferior
+ to that point, and modifies the locals that control the event thread counts. Also sets a breakpoint in
+ breakpoint_func (the function executed by each 'breakpoint' thread) and a watchpoint on a global modified in
+ watchpoint_func. The inferior is continued until exit or a crash takes place, and the number of events seen by LLDB
+ is verified to match the expected number of events.
+ """
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Get the target
+ self.inferior_target = self.dbg.GetSelectedTarget()
+
+ expected_bps = []
+
+ # Initialize all the breakpoints (main thread/aux thread)
+ self.setup_breakpoint = self.add_breakpoint(self.setup_breakpoint_line, expected_bps)
+ self.finish_breakpoint = self.add_breakpoint(self.finish_breakpoint_line, expected_bps)
+
+ # Set the thread breakpoint
+ if num_breakpoint_threads + num_delay_breakpoint_threads > 0:
+ self.thread_breakpoint = self.add_breakpoint(self.thread_breakpoint_line, expected_bps)
+
+ # Verify breakpoints
+ self.expect("breakpoint list -f", "Breakpoint locations shown correctly", substrs = expected_bps)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # Check we are at line self.setup_breakpoint
+ self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ["stop reason = breakpoint 1."])
+
+ # Initialize the (single) watchpoint on the global variable (g_watchme)
+ if num_watchpoint_threads + num_delay_watchpoint_threads > 0:
+ self.runCmd("watchpoint set variable g_watchme")
+ for w in self.inferior_target.watchpoint_iter():
+ self.thread_watchpoint = w
+ self.assertTrue("g_watchme" in str(self.thread_watchpoint), "Watchpoint location not shown correctly")
+
+ # Get the process
+ self.inferior_process = self.inferior_target.GetProcess()
+
+ # We should be stopped at the setup site where we can set the number of
+ # threads doing each action (break/crash/signal/watch)
+ self.assertEqual(self.inferior_process.GetNumThreads(), 1, 'Expected to stop before any additional threads are spawned.')
+
+ self.runCmd("expr num_breakpoint_threads=%d" % num_breakpoint_threads)
+ self.runCmd("expr num_crash_threads=%d" % num_crash_threads)
+ self.runCmd("expr num_signal_threads=%d" % num_signal_threads)
+ self.runCmd("expr num_watchpoint_threads=%d" % num_watchpoint_threads)
+
+ self.runCmd("expr num_delay_breakpoint_threads=%d" % num_delay_breakpoint_threads)
+ self.runCmd("expr num_delay_crash_threads=%d" % num_delay_crash_threads)
+ self.runCmd("expr num_delay_signal_threads=%d" % num_delay_signal_threads)
+ self.runCmd("expr num_delay_watchpoint_threads=%d" % num_delay_watchpoint_threads)
+
+ # Continue the inferior so threads are spawned
+ self.runCmd("continue")
+
+ # Make sure we see all the threads. The inferior program's threads all synchronize with a pseudo-barrier; that is,
+ # the inferior program ensures all threads are started and running before any thread triggers its 'event'.
+ num_threads = self.inferior_process.GetNumThreads()
+ expected_num_threads = num_breakpoint_threads + num_delay_breakpoint_threads \
+ + num_signal_threads + num_delay_signal_threads \
+ + num_watchpoint_threads + num_delay_watchpoint_threads \
+ + num_crash_threads + num_delay_crash_threads + 1
+ self.assertEqual(num_threads, expected_num_threads,
+ 'Expected to see %d threads, but seeing %d. Details:\n%s' % (expected_num_threads,
+ num_threads,
+ "\n\t".join(self.describe_threads())))
+
+ self.signal_count = self.count_signaled_threads()
+ self.crash_count = len(lldbutil.get_crashed_threads(self, self.inferior_process))
+
+ # Run to completion (or crash)
+ while not self.inferior_done():
+ if self.TraceOn():
+ self.runCmd("thread backtrace all")
+ self.runCmd("continue")
+ self.signal_count += self.count_signaled_threads()
+ self.crash_count += len(lldbutil.get_crashed_threads(self, self.inferior_process))
+
+ if num_crash_threads > 0 or num_delay_crash_threads > 0:
+ # Expecting a crash
+ self.assertTrue(self.crash_count > 0,
+ "Expecting at least one thread to crash. Details: %s" % "\t\n".join(self.describe_threads()))
+
+ # Ensure the zombie process is reaped
+ self.runCmd("process kill")
+
+ elif num_crash_threads == 0 and num_delay_crash_threads == 0:
+ # There should be a single active thread (the main one) which hit the breakpoint after joining
+ self.assertEqual(1, self.finish_breakpoint.GetHitCount(), "Expected main thread (finish) breakpoint to be hit once")
+
+ num_threads = self.inferior_process.GetNumThreads()
+ self.assertEqual(1, num_threads, "Expecting 1 thread but seeing %d. Details:%s" % (num_threads,
+ "\n\t".join(self.describe_threads())))
+ self.runCmd("continue")
+
+ # The inferior process should have exited without crashing
+ self.assertEqual(0, self.crash_count, "Unexpected thread(s) in crashed state")
+ self.assertEqual(self.inferior_process.GetState(), lldb.eStateExited, PROCESS_EXITED)
+
+ # Verify the number of actions took place matches expected numbers
+ expected_breakpoint_threads = num_delay_breakpoint_threads + num_breakpoint_threads
+ breakpoint_hit_count = self.thread_breakpoint.GetHitCount() if expected_breakpoint_threads > 0 else 0
+ self.assertEqual(expected_breakpoint_threads, breakpoint_hit_count,
+ "Expected %d breakpoint hits, but got %d" % (expected_breakpoint_threads, breakpoint_hit_count))
+
+ expected_signal_threads = num_delay_signal_threads + num_signal_threads
+ self.assertEqual(expected_signal_threads, self.signal_count,
+ "Expected %d stops due to signal delivery, but got %d" % (expected_signal_threads, self.signal_count))
+
+ expected_watchpoint_threads = num_delay_watchpoint_threads + num_watchpoint_threads
+ watchpoint_hit_count = self.thread_watchpoint.GetHitCount() if expected_watchpoint_threads > 0 else 0
+ self.assertEqual(expected_watchpoint_threads, watchpoint_hit_count,
+ "Expected %d watchpoint hits, got %d" % (expected_watchpoint_threads, watchpoint_hit_count))
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/main.cpp
new file mode 100644
index 000000000000..ac2535cd2bff
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/main.cpp
@@ -0,0 +1,200 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// This test is intended to create a situation in which multiple events
+// (breakpoints, watchpoints, crashes, and signal generation/delivery) happen
+// from multiple threads. The test expects the debugger to set a breakpoint on
+// the main thread (before any worker threads are spawned) and modify variables
+// which control the number of threads that are spawned for each action.
+
+#include <atomic>
+#include <vector>
+using namespace std;
+
+#include <pthread.h>
+
+#include <signal.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+// Note that although hogging the CPU while waiting for a variable to change
+// would be terrible in production code, it's great for testing since it
+// avoids a lot of messy context switching to get multiple threads synchronized.
+#define do_nothing()
+
+#define pseudo_barrier_wait(bar) \
+ --bar; \
+ while (bar > 0) \
+ do_nothing();
+
+#define pseudo_barrier_init(bar, count) (bar = count)
+
+typedef std::vector<std::pair<unsigned, void*(*)(void*)> > action_counts;
+typedef std::vector<pthread_t> thread_vector;
+
+std::atomic_int g_barrier;
+int g_breakpoint = 0;
+int g_sigusr1_count = 0;
+std::atomic_int g_watchme;
+
+struct action_args {
+ int delay;
+};
+
+// Perform any extra actions required by thread 'input' arg
+void do_action_args(void *input) {
+ if (input) {
+ action_args *args = static_cast<action_args*>(input);
+ sleep(args->delay);
+ }
+}
+
+void *
+breakpoint_func (void *input)
+{
+ // Wait until all threads are running
+ pseudo_barrier_wait(g_barrier);
+ do_action_args(input);
+
+ // Do something
+ g_breakpoint++; // Set breakpoint here
+ return 0;
+}
+
+void *
+signal_func (void *input) {
+ // Wait until all threads are running
+ pseudo_barrier_wait(g_barrier);
+ do_action_args(input);
+
+ // Send a user-defined signal to the current process
+ //kill(getpid(), SIGUSR1);
+ // Send a user-defined signal to the current thread
+ pthread_kill(pthread_self(), SIGUSR1);
+
+ return 0;
+}
+
+void *
+watchpoint_func (void *input) {
+ pseudo_barrier_wait(g_barrier);
+ do_action_args(input);
+
+ g_watchme += 1; // watchpoint triggers here
+ return 0;
+}
+
+void *
+crash_func (void *input) {
+ pseudo_barrier_wait(g_barrier);
+ do_action_args(input);
+
+ int *a = 0;
+ *a = 5; // crash happens here
+ return 0;
+}
+
+void sigusr1_handler(int sig) {
+ if (sig == SIGUSR1)
+ g_sigusr1_count += 1; // Break here in signal handler
+}
+
+/// Register a simple function for to handle signal
+void register_signal_handler(int signal, void (*handler)(int))
+{
+ sigset_t empty_sigset;
+ sigemptyset(&empty_sigset);
+
+ struct sigaction action;
+ action.sa_sigaction = 0;
+ action.sa_mask = empty_sigset;
+ action.sa_flags = 0;
+ action.sa_handler = handler;
+ sigaction(SIGUSR1, &action, 0);
+}
+
+void start_threads(thread_vector& threads,
+ action_counts& actions,
+ void* args = 0) {
+ action_counts::iterator b = actions.begin(), e = actions.end();
+ for(action_counts::iterator i = b; i != e; ++i) {
+ for(unsigned count = 0; count < i->first; ++count) {
+ pthread_t t;
+ pthread_create(&t, 0, i->second, args);
+ threads.push_back(t);
+ }
+ }
+}
+
+int dotest()
+{
+ g_watchme = 0;
+
+ // Actions are triggered immediately after the thread is spawned
+ unsigned num_breakpoint_threads = 1;
+ unsigned num_watchpoint_threads = 0;
+ unsigned num_signal_threads = 1;
+ unsigned num_crash_threads = 0;
+
+ // Actions below are triggered after a 1-second delay
+ unsigned num_delay_breakpoint_threads = 0;
+ unsigned num_delay_watchpoint_threads = 0;
+ unsigned num_delay_signal_threads = 0;
+ unsigned num_delay_crash_threads = 0;
+
+ register_signal_handler(SIGUSR1, sigusr1_handler); // Break here and adjust num_[breakpoint|watchpoint|signal|crash]_threads
+
+ unsigned total_threads = num_breakpoint_threads \
+ + num_watchpoint_threads \
+ + num_signal_threads \
+ + num_crash_threads \
+ + num_delay_breakpoint_threads \
+ + num_delay_watchpoint_threads \
+ + num_delay_signal_threads \
+ + num_delay_crash_threads;
+
+ // Don't let either thread do anything until they're both ready.
+ pseudo_barrier_init(g_barrier, total_threads);
+
+ action_counts actions;
+ actions.push_back(std::make_pair(num_breakpoint_threads, breakpoint_func));
+ actions.push_back(std::make_pair(num_watchpoint_threads, watchpoint_func));
+ actions.push_back(std::make_pair(num_signal_threads, signal_func));
+ actions.push_back(std::make_pair(num_crash_threads, crash_func));
+
+ action_counts delay_actions;
+ delay_actions.push_back(std::make_pair(num_delay_breakpoint_threads, breakpoint_func));
+ delay_actions.push_back(std::make_pair(num_delay_watchpoint_threads, watchpoint_func));
+ delay_actions.push_back(std::make_pair(num_delay_signal_threads, signal_func));
+ delay_actions.push_back(std::make_pair(num_delay_crash_threads, crash_func));
+
+ // Create threads that handle instant actions
+ thread_vector threads;
+ start_threads(threads, actions);
+
+ // Create threads that handle delayed actions
+ action_args delay_arg;
+ delay_arg.delay = 1;
+ start_threads(threads, delay_actions, &delay_arg);
+
+ // Join all threads
+ typedef std::vector<pthread_t>::iterator thread_iterator;
+ for(thread_iterator t = threads.begin(); t != threads.end(); ++t)
+ pthread_join(*t, 0);
+
+ return 0;
+}
+
+int main ()
+{
+ dotest();
+ return 0; // Break here and verify one thread is active.
+}
+
+
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/Makefile b/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/Makefile
new file mode 100644
index 000000000000..26db4816b6ea
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/Makefile
@@ -0,0 +1,4 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/TestCrashDuringStep.py b/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/TestCrashDuringStep.py
new file mode 100644
index 000000000000..24b5bf0dad36
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/TestCrashDuringStep.py
@@ -0,0 +1,53 @@
+"""
+Test that step-inst over a crash behaves correctly.
+"""
+
+from __future__ import print_function
+
+
+
+import os
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class CreateDuringStepTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ TestBase.setUp(self)
+ self.breakpoint = line_number('main.cpp', '// Set breakpoint here')
+
+ @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAndroid("llvm.org/pr24497", archs=['arm', 'aarch64'])
+ @expectedFailureAll(archs=['mips', 'mipsel', 'mips64', 'mips64el']) # IO error due to breakpoint at invalid address
+ def test_step_inst_with(self):
+ """Test thread creation during step-inst handling."""
+ self.build(dictionary=self.getBuildFlags())
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target and target.IsValid(), "Target is valid")
+
+ self.bp_num = lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.breakpoint, num_expected_locations=1)
+
+ # Run the program.
+ process = target.LaunchSimple(None, None, self.get_process_working_directory())
+ self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID)
+
+ # The stop reason should be breakpoint.
+ self.assertEqual(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
+ self.assertEqual(lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint).IsValid(), 1,
+ STOPPED_DUE_TO_BREAKPOINT)
+
+ thread = process.GetThreadAtIndex(0)
+ self.assertTrue(thread and thread.IsValid(), "Thread is valid")
+
+ # Keep stepping until the inferior crashes
+ while process.GetState() == lldb.eStateStopped and not lldbutil.is_thread_crashed(self, thread):
+ thread.StepInstruction(False)
+
+ self.assertEqual(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
+ self.assertTrue(lldbutil.is_thread_crashed(self, thread), "Thread has crashed")
+ process.Kill()
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/main.cpp
new file mode 100644
index 000000000000..02f3ce338229
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/main.cpp
@@ -0,0 +1,16 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+void (*crash)() = nullptr;
+
+int main()
+{
+ crash(); // Set breakpoint here
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/Makefile b/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/Makefile
new file mode 100644
index 000000000000..67aa16625bff
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+ENABLE_THREADS := YES
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/TestCreateAfterAttach.py b/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/TestCreateAfterAttach.py
new file mode 100644
index 000000000000..977254343aa0
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/TestCreateAfterAttach.py
@@ -0,0 +1,122 @@
+"""
+Test thread creation after process attach.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class CreateAfterAttachTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipIfFreeBSD # Hangs. May be the same as Linux issue llvm.org/pr16229 but
+ # not yet investigated. Revisit once required functionality
+ # is implemented for FreeBSD.
+ @skipIfWindows # Occasionally hangs on Windows, may be same as other issues.
+ @skipIfiOSSimulator
+ def test_create_after_attach_with_popen(self):
+ """Test thread creation after process attach."""
+ self.build(dictionary=self.getBuildFlags(use_cpp11=False))
+ self.create_after_attach(use_fork=False)
+
+ @skipIfFreeBSD # Hangs. Revisit once required functionality is implemented
+ # for FreeBSD.
+ @skipIfRemote
+ @skipIfWindows # Windows doesn't have fork.
+ @expectedFlakeyLinux("llvm.org/pr16229") # 1/100 dosep, build 3546, clang-3.5 x84_64
+ @skipIfiOSSimulator
+ def test_create_after_attach_with_fork(self):
+ """Test thread creation after process attach."""
+ self.build(dictionary=self.getBuildFlags(use_cpp11=False))
+ self.create_after_attach(use_fork=True)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line numbers for our breakpoints.
+ self.break_1 = line_number('main.cpp', '// Set first breakpoint here')
+ self.break_2 = line_number('main.cpp', '// Set second breakpoint here')
+ self.break_3 = line_number('main.cpp', '// Set third breakpoint here')
+
+ def create_after_attach(self, use_fork):
+ """Test thread creation after process attach."""
+
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Spawn a new process
+ if use_fork:
+ pid = self.forkSubprocess(exe)
+ else:
+ popen = self.spawnSubprocess(exe)
+ pid = popen.pid
+ self.addTearDownHook(self.cleanupSubprocesses)
+
+ # Attach to the spawned process
+ self.runCmd("process attach -p " + str(pid))
+
+ target = self.dbg.GetSelectedTarget()
+
+ process = target.GetProcess()
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # This should create a breakpoint in the main thread.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_1, num_expected_locations=1)
+
+ # This should create a breakpoint in the second child thread.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_2, num_expected_locations=1)
+
+ # This should create a breakpoint in the first child thread.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_3, num_expected_locations=1)
+
+ # Note: With std::thread, we cannot rely on particular thread numbers. Using
+ # std::thread may cause the program to spin up a thread pool (and it does on
+ # Windows), so the thread numbers are non-deterministic.
+
+ # Run to the first breakpoint
+ self.runCmd("continue")
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ '* thread #',
+ 'main',
+ 'stop reason = breakpoint'])
+
+ # Change a variable to escape the loop
+ self.runCmd("expression main_thread_continue = 1")
+
+ # Run to the second breakpoint
+ self.runCmd("continue")
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ '* thread #',
+ 'thread_2_func',
+ 'stop reason = breakpoint'])
+
+ # Change a variable to escape the loop
+ self.runCmd("expression child_thread_continue = 1")
+
+ # Run to the third breakpoint
+ self.runCmd("continue")
+
+ # The stop reason of the thread should be breakpoint.
+ # Thread 3 may or may not have already exited.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ '* thread #',
+ 'thread_1_func',
+ 'stop reason = breakpoint'])
+
+ # Run to completion
+ self.runCmd("continue")
+
+ # At this point, the inferior process should have exited.
+ self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED)
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/main.cpp
new file mode 100644
index 000000000000..8434458f0648
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/main.cpp
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <chrono>
+#include <thread>
+
+using std::chrono::microseconds;
+
+#if defined(__linux__)
+#include <sys/prctl.h>
+#endif
+
+volatile int g_thread_2_continuing = 0;
+
+void *
+thread_1_func (void *input)
+{
+ // Waiting to be released by the debugger.
+ while (!g_thread_2_continuing) // Another thread will change this value
+ {
+ std::this_thread::sleep_for(microseconds(1));
+ }
+
+ // Return
+ return NULL; // Set third breakpoint here
+}
+
+void *
+thread_2_func (void *input)
+{
+ // Waiting to be released by the debugger.
+ int child_thread_continue = 0;
+ while (!child_thread_continue) // The debugger will change this value
+ {
+ std::this_thread::sleep_for(microseconds(1)); // Set second breakpoint here
+ }
+
+ // Release thread 1
+ g_thread_2_continuing = 1;
+
+ // Return
+ return NULL;
+}
+
+int main(int argc, char const *argv[])
+{
+#if defined(__linux__)
+ // Immediately enable any ptracer so that we can allow the stub attach
+ // operation to succeed. Some Linux kernels are locked down so that
+ // only an ancestor process can be a ptracer of a process. This disables that
+ // restriction. Without it, attach-related stub tests will fail.
+#if defined(PR_SET_PTRACER) && defined(PR_SET_PTRACER_ANY)
+ int prctl_result;
+
+ // For now we execute on best effort basis. If this fails for
+ // some reason, so be it.
+ prctl_result = prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0);
+ (void) prctl_result;
+#endif
+#endif
+
+ // Create a new thread
+ std::thread thread_1(thread_1_func, nullptr);
+
+ // Waiting to be attached by the debugger.
+ int main_thread_continue = 0;
+ while (!main_thread_continue) // The debugger will change this value
+ {
+ std::this_thread::sleep_for(microseconds(1)); // Set first breakpoint here
+ }
+
+ // Create another new thread
+ std::thread thread_2(thread_2_func, nullptr);
+
+ // Wait for the threads to finish.
+ thread_1.join();
+ thread_2.join();
+
+ printf("Exiting now\n");
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/Makefile b/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/Makefile
new file mode 100644
index 000000000000..67aa16625bff
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+ENABLE_THREADS := YES
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/TestCreateDuringStep.py b/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/TestCreateDuringStep.py
new file mode 100644
index 000000000000..046a86509c0f
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/TestCreateDuringStep.py
@@ -0,0 +1,127 @@
+"""
+Test number of threads.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class CreateDuringStepTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained
+ @expectedFailureFreeBSD("llvm.org/pr18190") # thread states not properly maintained
+ @expectedFailureLinux("llvm.org/pr15824") # thread states not properly maintained
+ @expectedFailureWindows("llvm.org/pr24668") # Breakpoints not resolved correctly
+ def test_step_inst(self):
+ """Test thread creation during step-inst handling."""
+ self.build(dictionary=self.getBuildFlags())
+ self.create_during_step_base("thread step-inst -m all-threads", 'stop reason = instruction step')
+
+ @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained
+ @expectedFailureFreeBSD("llvm.org/pr18190") # thread states not properly maintained
+ @expectedFailureLinux("llvm.org/pr15824") # thread states not properly maintained
+ @expectedFailureWindows("llvm.org/pr24668") # Breakpoints not resolved correctly
+ def test_step_over(self):
+ """Test thread creation during step-over handling."""
+ self.build(dictionary=self.getBuildFlags())
+ self.create_during_step_base("thread step-over -m all-threads", 'stop reason = step over')
+
+ @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained
+ @expectedFailureFreeBSD("llvm.org/pr18190") # thread states not properly maintained
+ @expectedFailureLinux("llvm.org/pr15824") # thread states not properly maintained
+ @expectedFailureWindows("llvm.org/pr24668") # Breakpoints not resolved correctly
+ def test_step_in(self):
+ """Test thread creation during step-in handling."""
+ self.build(dictionary=self.getBuildFlags())
+ self.create_during_step_base("thread step-in -m all-threads", 'stop reason = step in')
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line numbers to break and continue.
+ self.breakpoint = line_number('main.cpp', '// Set breakpoint here')
+ self.continuepoint = line_number('main.cpp', '// Continue from here')
+
+ def create_during_step_base(self, step_cmd, step_stop_reason):
+ """Test thread creation while using step-in."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # This should create a breakpoint in the stepping thread.
+ self.bp_num = lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.breakpoint, num_expected_locations=1)
+
+ # The breakpoint list should show 1 location.
+ self.expect("breakpoint list -f", "Breakpoint location shown correctly",
+ substrs = ["1: file = 'main.cpp', line = %d, locations = 1" % self.breakpoint])
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Get the target process
+ target = self.dbg.GetSelectedTarget()
+ process = target.GetProcess()
+
+ # Get the number of threads
+ num_threads = process.GetNumThreads()
+
+ # Make sure we see only two threads
+ self.assertTrue(num_threads == 2, 'Number of expected threads and actual threads do not match.')
+
+ # Get the thread objects
+ thread1 = process.GetThreadAtIndex(0)
+ thread2 = process.GetThreadAtIndex(1)
+
+ # Make sure both threads are stopped
+ self.assertTrue(thread1.IsStopped(), "Thread 1 didn't stop during breakpoint")
+ self.assertTrue(thread2.IsStopped(), "Thread 2 didn't stop during breakpoint")
+
+ # Find the thread that is stopped at the breakpoint
+ stepping_thread = None
+ for thread in process:
+ expected_bp_desc = "breakpoint %s." % self.bp_num
+ if expected_bp_desc in thread.GetStopDescription(100):
+ stepping_thread = thread
+ break
+ self.assertTrue(stepping_thread != None, "unable to find thread stopped at %s" % expected_bp_desc)
+ current_line = self.breakpoint
+ # Keep stepping until we've reached our designated continue point
+ while current_line != self.continuepoint:
+ if stepping_thread != process.GetSelectedThread():
+ process.SetSelectedThread(stepping_thread)
+
+ self.runCmd(step_cmd)
+
+ frame = stepping_thread.GetFrameAtIndex(0)
+ current_line = frame.GetLineEntry().GetLine()
+
+ # Make sure we're still where we thought we were
+ self.assertTrue(current_line >= self.breakpoint, "Stepped to unexpected line, " + str(current_line))
+ self.assertTrue(current_line <= self.continuepoint, "Stepped to unexpected line, " + str(current_line))
+
+ # Update the number of threads
+ num_threads = process.GetNumThreads()
+
+ # Check to see that we increased the number of threads as expected
+ self.assertTrue(num_threads == 3, 'Number of expected threads and actual threads do not match after thread exit.')
+
+ self.expect("thread list", 'Process state is stopped due to step',
+ substrs = ['stopped',
+ step_stop_reason])
+
+ # Run to completion
+ self.runCmd("process continue")
+
+ # At this point, the inferior process should have exited.
+ self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED)
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/main.cpp
new file mode 100644
index 000000000000..3a00248c022a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/main.cpp
@@ -0,0 +1,89 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// This test is intended to create a situation in which one thread will be
+// created while the debugger is stepping in another thread.
+
+#include <atomic>
+#include <thread>
+
+// Note that although hogging the CPU while waiting for a variable to change
+// would be terrible in production code, it's great for testing since it
+// avoids a lot of messy context switching to get multiple threads synchronized.
+#define do_nothing()
+
+#define pseudo_barrier_wait(bar) \
+ --bar; \
+ while (bar > 0) \
+ do_nothing();
+
+#define pseudo_barrier_init(bar, count) (bar = count)
+
+std::atomic_int g_barrier;
+
+volatile int g_thread_created = 0;
+volatile int g_test = 0;
+
+void *
+step_thread_func ()
+{
+ g_test = 0; // Set breakpoint here
+
+ while (!g_thread_created)
+ g_test++;
+
+ // One more time to provide a continue point
+ g_test++; // Continue from here
+
+ // Return
+ return NULL;
+}
+
+void *
+create_thread_func (void *input)
+{
+ std::thread *step_thread = (std::thread*)input;
+
+ // Wait until the main thread knows this thread is started.
+ pseudo_barrier_wait(g_barrier);
+
+ // Wait until the other thread is done.
+ step_thread->join();
+
+ // Return
+ return NULL;
+}
+
+int main ()
+{
+ // Use a simple count to simulate a barrier.
+ pseudo_barrier_init(g_barrier, 2);
+
+ // Create a thread to hit the breakpoint.
+ std::thread thread_1(step_thread_func);
+
+ // Wait until the step thread is stepping
+ while (g_test < 1)
+ do_nothing();
+
+ // Create a thread to exit while we're stepping.
+ std::thread thread_2(create_thread_func, &thread_1);
+
+ // Wait until that thread is started
+ pseudo_barrier_wait(g_barrier);
+
+ // Let the stepping thread know the other thread is there
+ g_thread_created = 1;
+
+ // Wait for the threads to finish.
+ thread_2.join();
+ thread_1.join();
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/Makefile b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/Makefile
new file mode 100644
index 000000000000..67aa16625bff
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+ENABLE_THREADS := YES
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/TestExitDuringBreak.py b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/TestExitDuringBreak.py
new file mode 100644
index 000000000000..f999ffe108f3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/TestExitDuringBreak.py
@@ -0,0 +1,81 @@
+"""
+Test number of threads.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class ExitDuringBreakpointTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number for our breakpoint.
+ self.breakpoint = line_number('main.cpp', '// Set breakpoint here')
+
+ @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained
+ @expectedFailureFreeBSD("llvm.org/pr18190") # thread states not properly maintained
+ @expectedFailureLinux("llvm.org/pr15824") # thread states not properly maintained
+ @expectedFailureWindows("llvm.org/pr24668") # Breakpoints not resolved correctly
+ def test(self):
+ """Test thread exit during breakpoint handling."""
+ self.build(dictionary=self.getBuildFlags())
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # This should create a breakpoint in the main thread.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.breakpoint, num_expected_locations=1)
+
+ # The breakpoint list should show 1 location.
+ self.expect("breakpoint list -f", "Breakpoint location shown correctly",
+ substrs = ["1: file = 'main.cpp', line = %d, locations = 1" % self.breakpoint])
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Get the target process
+ target = self.dbg.GetSelectedTarget()
+ process = target.GetProcess()
+
+ # The exit probably occurred during breakpoint handling, but it isn't
+ # guaranteed. The main thing we're testing here is that the debugger
+ # handles this cleanly is some way.
+
+ # Get the number of threads
+ num_threads = process.GetNumThreads()
+
+ # Make sure we see at least five threads
+ self.assertTrue(num_threads >= 5, 'Number of expected threads and actual threads do not match.')
+
+ # Get the thread objects
+ thread1 = process.GetThreadAtIndex(0)
+ thread2 = process.GetThreadAtIndex(1)
+ thread3 = process.GetThreadAtIndex(2)
+ thread4 = process.GetThreadAtIndex(3)
+ thread5 = process.GetThreadAtIndex(4)
+
+ # Make sure all threads are stopped
+ self.assertTrue(thread1.IsStopped(), "Thread 1 didn't stop during breakpoint")
+ self.assertTrue(thread2.IsStopped(), "Thread 2 didn't stop during breakpoint")
+ self.assertTrue(thread3.IsStopped(), "Thread 3 didn't stop during breakpoint")
+ self.assertTrue(thread4.IsStopped(), "Thread 4 didn't stop during breakpoint")
+ self.assertTrue(thread5.IsStopped(), "Thread 5 didn't stop during breakpoint")
+
+ # Run to completion
+ self.runCmd("continue")
+
+ # At this point, the inferior process should have exited.
+ self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED)
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/main.cpp
new file mode 100644
index 000000000000..3570637207d2
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/main.cpp
@@ -0,0 +1,130 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// This test is intended to create a situation in which one thread will exit
+// while a breakpoint is being handled in another thread. This may not always
+// happen because it's possible that the exiting thread will exit before the
+// breakpoint is hit. The test case should be flexible enough to treat that
+// as success.
+
+#include <atomic>
+#include <chrono>
+#include <thread>
+
+volatile int g_test = 0;
+
+// Note that although hogging the CPU while waiting for a variable to change
+// would be terrible in production code, it's great for testing since it
+// avoids a lot of messy context switching to get multiple threads synchronized.
+#define do_nothing()
+
+#define pseudo_barrier_wait(bar) \
+ --bar; \
+ while (bar > 0) \
+ do_nothing();
+
+#define pseudo_barrier_init(bar, count) (bar = count)
+
+// A barrier to synchronize all the threads except the one that will exit.
+std::atomic_int g_barrier1;
+
+// A barrier to synchronize all the threads including the one that will exit.
+std::atomic_int g_barrier2;
+
+// A barrier to keep the first group of threads from exiting until after the
+// breakpoint has been passed.
+std::atomic_int g_barrier3;
+
+void *
+break_thread_func ()
+{
+ // Wait until the entire first group of threads is running
+ pseudo_barrier_wait(g_barrier1);
+
+ // Wait for the exiting thread to start
+ pseudo_barrier_wait(g_barrier2);
+
+ // Do something
+ g_test++; // Set breakpoint here
+
+ // Synchronize after the breakpoint
+ pseudo_barrier_wait(g_barrier3);
+
+ // Return
+ return NULL;
+}
+
+void *
+wait_thread_func ()
+{
+ // Wait until the entire first group of threads is running
+ pseudo_barrier_wait(g_barrier1);
+
+ // Wait for the exiting thread to start
+ pseudo_barrier_wait(g_barrier2);
+
+ // Wait until the breakpoint has been passed
+ pseudo_barrier_wait(g_barrier3);
+
+ // Return
+ return NULL;
+}
+
+void *
+exit_thread_func ()
+{
+ // Sync up with the rest of the threads.
+ pseudo_barrier_wait(g_barrier2);
+
+ // Try to make sure this thread doesn't exit until the breakpoint is hit.
+ std::this_thread::sleep_for(std::chrono::microseconds(1));
+
+ // Return
+ return NULL;
+}
+
+int main ()
+{
+
+ // The first barrier waits for the non-exiting threads to start.
+ // This thread will also participate in that barrier.
+ // The idea here is to guarantee that the exiting thread will be
+ // last in the internal list maintained by the debugger.
+ pseudo_barrier_init(g_barrier1, 5);
+
+ // The second break synchronyizes thread exection with the breakpoint.
+ pseudo_barrier_init(g_barrier2, 5);
+
+ // The third barrier keeps the waiting threads around until the breakpoint
+ // has been passed.
+ pseudo_barrier_init(g_barrier3, 4);
+
+ // Create a thread to hit the breakpoint
+ std::thread thread_1(break_thread_func);
+
+ // Create more threads to slow the debugger down during processing.
+ std::thread thread_2(wait_thread_func);
+ std::thread thread_3(wait_thread_func);
+ std::thread thread_4(wait_thread_func);
+
+ // Wait for all these threads to get started.
+ pseudo_barrier_wait(g_barrier1);
+
+ // Create a thread to exit during the breakpoint
+ std::thread thread_5(exit_thread_func);
+
+ // Wait for the threads to finish
+ thread_5.join();
+ thread_4.join();
+ thread_3.join();
+ thread_2.join();
+ thread_1.join();
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/Makefile b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/Makefile
new file mode 100644
index 000000000000..d06a7d4685f3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+ENABLE_THREADS := YES
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py
new file mode 100644
index 000000000000..67d1c96fd342
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py
@@ -0,0 +1,144 @@
+"""
+Test number of threads.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class ExitDuringStepTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained
+ @expectedFailureFreeBSD("llvm.org/pr18190") # thread states not properly maintained
+ @expectedFailureLinux("llvm.org/pr15824") # thread states not properly maintained
+ @expectedFailureWindows("llvm.org/pr24681")
+ def test_thread_state_is_stopped(self):
+ """Test thread exit during step handling."""
+ self.build(dictionary=self.getBuildFlags())
+ self.exit_during_step_base("thread step-in -m all-threads", 'stop reason = step in', True)
+
+ @skipIfFreeBSD # llvm.org/pr21411: test is hanging
+ @expectedFailureWindows("llvm.org/pr24681")
+ def test(self):
+ """Test thread exit during step handling."""
+ self.build(dictionary=self.getBuildFlags())
+ self.exit_during_step_base("thread step-inst -m all-threads", 'stop reason = instruction step', False)
+
+ @skipIfFreeBSD # llvm.org/pr21411: test is hanging
+ @expectedFailureWindows("llvm.org/pr24681")
+ def test_step_over(self):
+ """Test thread exit during step-over handling."""
+ self.build(dictionary=self.getBuildFlags())
+ self.exit_during_step_base("thread step-over -m all-threads", 'stop reason = step over', False)
+
+ @skipIfFreeBSD # llvm.org/pr21411: test is hanging
+ @expectedFailureWindows("llvm.org/pr24681")
+ def test_step_in(self):
+ """Test thread exit during step-in handling."""
+ self.build(dictionary=self.getBuildFlags())
+ self.exit_during_step_base("thread step-in -m all-threads", 'stop reason = step in', False)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line numbers to break and continue.
+ self.breakpoint = line_number('main.cpp', '// Set breakpoint here')
+ self.continuepoint = line_number('main.cpp', '// Continue from here')
+
+ def exit_during_step_base(self, step_cmd, step_stop_reason, test_thread_state):
+ """Test thread exit during step handling."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # This should create a breakpoint in the main thread.
+ self.bp_num = lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.breakpoint, num_expected_locations=1)
+
+ # The breakpoint list should show 1 location.
+ self.expect("breakpoint list -f", "Breakpoint location shown correctly",
+ substrs = ["1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % self.breakpoint])
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Get the target process
+ target = self.dbg.GetSelectedTarget()
+ process = target.GetProcess()
+
+ # Get the number of threads
+ num_threads = process.GetNumThreads()
+
+ # Make sure we see all three threads
+ self.assertTrue(num_threads == 3, 'Number of expected threads and actual threads do not match.')
+
+ # Get the thread objects
+ thread1 = process.GetThreadAtIndex(0)
+ thread2 = process.GetThreadAtIndex(1)
+ thread3 = process.GetThreadAtIndex(2)
+
+ # Make sure all threads are stopped
+ if test_thread_state:
+ self.assertTrue(thread1.IsStopped(), "Thread 1 didn't stop during breakpoint")
+ self.assertTrue(thread2.IsStopped(), "Thread 2 didn't stop during breakpoint")
+ self.assertTrue(thread3.IsStopped(), "Thread 3 didn't stop during breakpoint")
+ return
+
+ # Find the thread that is stopped at the breakpoint
+ stepping_thread = None
+ for thread in process:
+ expected_bp_desc = "breakpoint %s." % self.bp_num
+ stop_desc = thread.GetStopDescription(100)
+ if stop_desc and (expected_bp_desc in stop_desc):
+ stepping_thread = thread
+ break
+ self.assertTrue(stepping_thread != None, "unable to find thread stopped at %s" % expected_bp_desc)
+
+ current_line = self.breakpoint
+ stepping_frame = stepping_thread.GetFrameAtIndex(0)
+ self.assertTrue(current_line == stepping_frame.GetLineEntry().GetLine(), "Starting line for stepping doesn't match breakpoint line.")
+
+ # Keep stepping until we've reached our designated continue point
+ while current_line != self.continuepoint:
+ # Since we're using the command interpreter to issue the thread command
+ # (on the selected thread) we need to ensure the selected thread is the
+ # stepping thread.
+ if stepping_thread != process.GetSelectedThread():
+ process.SetSelectedThread(stepping_thread)
+
+ self.runCmd(step_cmd)
+
+ frame = stepping_thread.GetFrameAtIndex(0)
+
+ current_line = frame.GetLineEntry().GetLine()
+
+ self.assertTrue(current_line >= self.breakpoint, "Stepped to unexpected line, " + str(current_line))
+ self.assertTrue(current_line <= self.continuepoint, "Stepped to unexpected line, " + str(current_line))
+
+ self.runCmd("thread list")
+
+ # Update the number of threads
+ num_threads = process.GetNumThreads()
+
+ # Check to see that we reduced the number of threads as expected
+ self.assertTrue(num_threads == 2, 'Number of expected threads and actual threads do not match after thread exit.')
+
+ self.expect("thread list", 'Process state is stopped due to step',
+ substrs = ['stopped',
+ step_stop_reason])
+
+ # Run to completion
+ self.runCmd("continue")
+
+ # At this point, the inferior process should have exited.
+ self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED)
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/main.cpp
new file mode 100644
index 000000000000..d1b364b8baa2
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/main.cpp
@@ -0,0 +1,87 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// This test is intended to create a situation in which one thread will exit
+// while the debugger is stepping in another thread.
+
+#include <thread>
+
+// Note that although hogging the CPU while waiting for a variable to change
+// would be terrible in production code, it's great for testing since it
+// avoids a lot of messy context switching to get multiple threads synchronized.
+#define do_nothing()
+
+#define pseudo_barrier_wait(bar) \
+ --bar; \
+ while (bar > 0) \
+ do_nothing();
+
+#define pseudo_barrier_init(bar, count) (bar = count)
+
+// A barrier to synchronize thread start.
+volatile int g_barrier;
+
+volatile int g_thread_exited = 0;
+
+volatile int g_test = 0;
+
+void *
+step_thread_func ()
+{
+ // Wait until both threads are started.
+ pseudo_barrier_wait(g_barrier);
+
+ g_test = 0; // Set breakpoint here
+
+ while (!g_thread_exited)
+ g_test++;
+
+ // One more time to provide a continue point
+ g_test++; // Continue from here
+
+ // Return
+ return NULL;
+}
+
+void *
+exit_thread_func ()
+{
+ // Wait until both threads are started.
+ pseudo_barrier_wait(g_barrier);
+
+ // Wait until the other thread is stepping.
+ while (g_test == 0)
+ do_nothing();
+
+ // Return
+ return NULL;
+}
+
+int main ()
+{
+ // Synchronize thread start so that doesn't happen during stepping.
+ pseudo_barrier_init(g_barrier, 2);
+
+ // Create a thread to hit the breakpoint.
+ std::thread thread_1(step_thread_func);
+
+ // Create a thread to exit while we're stepping.
+ std::thread thread_2(exit_thread_func);
+
+ // Wait for the exit thread to finish.
+ thread_2.join();
+
+ // Let the stepping thread know the other thread is gone.
+ g_thread_exited = 1;
+
+ // Wait for the stepping thread to finish.
+ thread_1.join();
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/jump/Makefile b/packages/Python/lldbsuite/test/functionalities/thread/jump/Makefile
new file mode 100644
index 000000000000..b726fc3695fd
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/jump/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+ENABLE_THREADS := YES
+CXX_SOURCES := main.cpp other.cpp
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/jump/TestThreadJump.py b/packages/Python/lldbsuite/test/functionalities/thread/jump/TestThreadJump.py
new file mode 100644
index 000000000000..be49a210f0f0
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/jump/TestThreadJump.py
@@ -0,0 +1,60 @@
+"""
+Test jumping to different places.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class ThreadJumpTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test(self):
+ """Test thread jump handling."""
+ self.build(dictionary=self.getBuildFlags())
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Find the line numbers for our breakpoints.
+ self.mark1 = line_number('main.cpp', '// 1st marker')
+ self.mark2 = line_number('main.cpp', '// 2nd marker')
+ self.mark3 = line_number('main.cpp', '// 3rd marker')
+ self.mark4 = line_number('main.cpp', '// 4th marker')
+ self.mark5 = line_number('other.cpp', '// other marker')
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.mark3, num_expected_locations=1)
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint 1.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT + " 1",
+ substrs = ['stopped',
+ '* thread #1',
+ 'stop reason = breakpoint 1'])
+
+ self.do_min_test(self.mark3, self.mark1, "i", "4"); # Try the int path, force it to return 'a'
+ self.do_min_test(self.mark3, self.mark2, "i", "5"); # Try the int path, force it to return 'b'
+ self.do_min_test(self.mark4, self.mark1, "j", "7"); # Try the double path, force it to return 'a'
+ self.do_min_test(self.mark4, self.mark2, "j", "8"); # Try the double path, force it to return 'b'
+
+ # Try jumping to another function in a different file.
+ self.runCmd("thread jump --file other.cpp --line %i --force" % self.mark5)
+ self.expect("process status",
+ substrs = ["at other.cpp:%i" % self.mark5])
+
+ # Try jumping to another function (without forcing)
+ self.expect("j main.cpp:%i" % self.mark1, COMMAND_FAILED_AS_EXPECTED, error = True,
+ substrs = ["error"])
+
+ def do_min_test(self, start, jump, var, value):
+ self.runCmd("j %i" % start) # jump to the start marker
+ self.runCmd("thread step-in") # step into the min fn
+ self.runCmd("j %i" % jump) # jump to the branch we're interested in
+ self.runCmd("thread step-out") # return out
+ self.runCmd("thread step-over") # assign to the global
+ self.expect("expr %s" % var, substrs = [value]) # check it
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/jump/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/jump/main.cpp
new file mode 100644
index 000000000000..3497155a98f2
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/jump/main.cpp
@@ -0,0 +1,35 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// This test verifies the correct handling of program counter jumps.
+
+int otherfn();
+
+template<typename T>
+T min(T a, T b)
+{
+ if (a < b)
+ {
+ return a; // 1st marker
+ } else {
+ return b; // 2nd marker
+ }
+}
+
+int main ()
+{
+ int i;
+ double j;
+ int min_i_a = 4, min_i_b = 5;
+ double min_j_a = 7.0, min_j_b = 8.0;
+ i = min(min_i_a, min_i_b); // 3rd marker
+ j = min(min_j_a, min_j_b); // 4th marker
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/jump/other.cpp b/packages/Python/lldbsuite/test/functionalities/thread/jump/other.cpp
new file mode 100644
index 000000000000..8108a52c163d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/jump/other.cpp
@@ -0,0 +1,13 @@
+//===-- other.cpp -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int otherfn()
+{
+ return 4; // other marker
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/main.cpp
new file mode 100644
index 000000000000..6a0ea4e0d119
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/main.cpp
@@ -0,0 +1,50 @@
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+
+std::mutex mutex;
+std::condition_variable cond;
+
+void *
+thread3(void *input)
+{
+ std::unique_lock<std::mutex> lock(mutex);
+ cond.notify_all(); // Set break point at this line.
+ return NULL;
+}
+
+void *
+thread2(void *input)
+{
+ std::unique_lock<std::mutex> lock(mutex);
+ cond.notify_all();
+ cond.wait(lock);
+ return NULL;
+}
+
+void *
+thread1(void *input)
+{
+ std::thread thread_2(thread2, nullptr);
+ thread_2.join();
+
+ return NULL;
+}
+
+int main()
+{
+ std::unique_lock<std::mutex> lock(mutex);
+
+ std::thread thread_1(thread1, nullptr);
+ cond.wait(lock);
+
+ std::thread thread_3(thread3, nullptr);
+ cond.wait(lock);
+
+ lock.unlock();
+
+ thread_1.join();
+ thread_3.join();
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/multi_break/Makefile b/packages/Python/lldbsuite/test/functionalities/thread/multi_break/Makefile
new file mode 100644
index 000000000000..67aa16625bff
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/multi_break/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+ENABLE_THREADS := YES
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/multi_break/TestMultipleBreakpoints.py b/packages/Python/lldbsuite/test/functionalities/thread/multi_break/TestMultipleBreakpoints.py
new file mode 100644
index 000000000000..9dd212412216
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/multi_break/TestMultipleBreakpoints.py
@@ -0,0 +1,77 @@
+"""
+Test number of threads.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class MultipleBreakpointTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number for our breakpoint.
+ self.breakpoint = line_number('main.cpp', '// Set breakpoint here')
+
+ @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained
+ @expectedFailureFreeBSD("llvm.org/pr18190") # thread states not properly maintained
+ @expectedFailureLinux("llvm.org/pr15824") # thread states not properly maintained
+ @expectedFailureWindows("llvm.org/pr24668") # Breakpoints not resolved correctly
+ def test(self):
+ """Test simultaneous breakpoints in multiple threads."""
+ self.build(dictionary=self.getBuildFlags())
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # This should create a breakpoint in the main thread.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.breakpoint, num_expected_locations=1)
+
+ # The breakpoint list should show 1 location.
+ self.expect("breakpoint list -f", "Breakpoint location shown correctly",
+ substrs = ["1: file = 'main.cpp', line = %d, locations = 1" % self.breakpoint])
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ # The breakpoint may be hit in either thread 2 or thread 3.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Get the target process
+ target = self.dbg.GetSelectedTarget()
+ process = target.GetProcess()
+
+ # Get the number of threads
+ num_threads = process.GetNumThreads()
+
+ # Make sure we see all three threads
+ self.assertTrue(num_threads == 3, 'Number of expected threads and actual threads do not match.')
+
+ # Get the thread objects
+ thread1 = process.GetThreadAtIndex(0)
+ thread2 = process.GetThreadAtIndex(1)
+ thread3 = process.GetThreadAtIndex(2)
+
+ # Make sure both threads are stopped
+ self.assertTrue(thread1.IsStopped(), "Primary thread didn't stop during breakpoint")
+ self.assertTrue(thread2.IsStopped(), "Secondary thread didn't stop during breakpoint")
+ self.assertTrue(thread3.IsStopped(), "Tertiary thread didn't stop during breakpoint")
+
+ # Delete the first breakpoint then continue
+ self.runCmd("breakpoint delete 1")
+
+ # Run to completion
+ self.runCmd("continue")
+
+ # At this point, the inferior process should have exited.
+ self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED)
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/multi_break/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/multi_break/main.cpp
new file mode 100644
index 000000000000..01f4b8f98ea7
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/multi_break/main.cpp
@@ -0,0 +1,61 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// This test is intended to create a situation in which a breakpoint will be
+// hit in two threads at nearly the same moment. The expected result is that
+// the breakpoint in the second thread will be hit while the breakpoint handler
+// in the first thread is trying to stop all threads.
+
+#include <atomic>
+#include <thread>
+
+// Note that although hogging the CPU while waiting for a variable to change
+// would be terrible in production code, it's great for testing since it
+// avoids a lot of messy context switching to get multiple threads synchronized.
+#define do_nothing()
+
+#define pseudo_barrier_wait(bar) \
+ --bar; \
+ while (bar > 0) \
+ do_nothing();
+
+#define pseudo_barrier_init(bar, count) (bar = count)
+
+std::atomic_int g_barrier;
+
+volatile int g_test = 0;
+
+void *
+thread_func ()
+{
+ // Wait until both threads are running
+ pseudo_barrier_wait(g_barrier);
+
+ // Do something
+ g_test++; // Set breakpoint here
+
+ // Return
+ return NULL;
+}
+
+int main ()
+{
+ // Don't let either thread do anything until they're both ready.
+ pseudo_barrier_init(g_barrier, 2);
+
+ // Create two threads
+ std::thread thread_1(thread_func);
+ std::thread thread_2(thread_func);
+
+ // Wait for the threads to finish
+ thread_1.join();
+ thread_2.join();
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/state/Makefile b/packages/Python/lldbsuite/test/functionalities/thread/state/Makefile
new file mode 100644
index 000000000000..26db4816b6ea
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/state/Makefile
@@ -0,0 +1,4 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/state/TestThreadStates.py b/packages/Python/lldbsuite/test/functionalities/thread/state/TestThreadStates.py
new file mode 100644
index 000000000000..623c659ffa5c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/state/TestThreadStates.py
@@ -0,0 +1,333 @@
+"""
+Test thread states.
+"""
+
+from __future__ import print_function
+
+
+
+import unittest2
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class ThreadStateTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureDarwin("rdar://15367566")
+ @expectedFailureFreeBSD('llvm.org/pr15824')
+ @expectedFailureLinux("llvm.org/pr15824") # thread states not properly maintained
+ @expectedFailureWindows("llvm.org/pr24668") # Breakpoints not resolved correctly
+ def test_state_after_breakpoint(self):
+ """Test thread state after breakpoint."""
+ self.build(dictionary=self.getBuildFlags(use_cpp11=False))
+ self.thread_state_after_breakpoint_test()
+
+ @skipIfDarwin # 'llvm.org/pr23669', cause Python crash randomly
+ @expectedFailureDarwin('llvm.org/pr23669')
+ @expectedFailureFreeBSD('llvm.org/pr15824')
+ @expectedFailureWindows("llvm.org/pr24660")
+ def test_state_after_continue(self):
+ """Test thread state after continue."""
+ self.build(dictionary=self.getBuildFlags(use_cpp11=False))
+ self.thread_state_after_continue_test()
+
+ @skipIfDarwin # 'llvm.org/pr23669', cause Python crash randomly
+ @expectedFailureDarwin('llvm.org/pr23669')
+ @expectedFailureWindows("llvm.org/pr24660")
+ @unittest2.expectedFailure("llvm.org/pr16712") # thread states not properly maintained
+ def test_state_after_expression(self):
+ """Test thread state after expression."""
+ self.build(dictionary=self.getBuildFlags(use_cpp11=False))
+ self.thread_state_after_expression_test()
+
+ @unittest2.expectedFailure("llvm.org/pr16712") # thread states not properly maintained
+ @expectedFailureWindows("llvm.org/pr24668") # Breakpoints not resolved correctly
+ def test_process_interrupt(self):
+ """Test process interrupt."""
+ self.build(dictionary=self.getBuildFlags(use_cpp11=False))
+ self.process_interrupt_test()
+
+ @unittest2.expectedFailure("llvm.org/pr15824") # thread states not properly maintained
+ @expectedFailureWindows("llvm.org/pr24668") # Breakpoints not resolved correctly
+ def test_process_state(self):
+ """Test thread states (comprehensive)."""
+ self.build(dictionary=self.getBuildFlags(use_cpp11=False))
+ self.thread_states_test()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line numbers for our breakpoints.
+ self.break_1 = line_number('main.cpp', '// Set first breakpoint here')
+ self.break_2 = line_number('main.cpp', '// Set second breakpoint here')
+
+ def thread_state_after_breakpoint_test(self):
+ """Test thread state after breakpoint."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # This should create a breakpoint in the main thread.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_1, num_expected_locations=1)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ '* thread #1',
+ 'stop reason = breakpoint'])
+
+ # Get the target process
+ target = self.dbg.GetSelectedTarget()
+ process = target.GetProcess()
+
+ # Get the number of threads
+ num_threads = process.GetNumThreads()
+
+ self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match.')
+
+ # Get the thread object
+ thread = process.GetThreadAtIndex(0)
+
+ # Make sure the thread is in the stopped state.
+ self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' during breakpoint 1.")
+ self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' during breakpoint 1.")
+
+ # Kill the process
+ self.runCmd("process kill")
+
+ def wait_for_running_event(self):
+ listener = self.dbg.GetListener()
+ if lldb.remote_platform:
+ lldbutil.expect_state_changes(self, listener, [lldb.eStateConnected])
+ lldbutil.expect_state_changes(self, listener, [lldb.eStateRunning])
+
+ def thread_state_after_continue_test(self):
+ """Test thread state after continue."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # This should create a breakpoint in the main thread.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_1, num_expected_locations=1)
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_2, num_expected_locations=1)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ '* thread #1',
+ 'stop reason = breakpoint'])
+
+ # Get the target process
+ target = self.dbg.GetSelectedTarget()
+ process = target.GetProcess()
+
+ # Get the number of threads
+ num_threads = process.GetNumThreads()
+
+ self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match.')
+
+ # Get the thread object
+ thread = process.GetThreadAtIndex(0)
+
+ # Continue, the inferior will go into an infinite loop waiting for 'g_test' to change.
+ self.dbg.SetAsync(True)
+ self.runCmd("continue")
+ self.wait_for_running_event()
+
+ # Check the thread state. It should be running.
+ self.assertFalse(thread.IsStopped(), "Thread state is \'stopped\' when it should be running.")
+ self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' when it should be running.")
+
+ # Go back to synchronous interactions
+ self.dbg.SetAsync(False)
+
+ # Kill the process
+ self.runCmd("process kill")
+
+ def thread_state_after_expression_test(self):
+ """Test thread state after expression."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # This should create a breakpoint in the main thread.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_1, num_expected_locations=1)
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_2, num_expected_locations=1)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ '* thread #1',
+ 'stop reason = breakpoint'])
+
+ # Get the target process
+ target = self.dbg.GetSelectedTarget()
+ process = target.GetProcess()
+
+ # Get the number of threads
+ num_threads = process.GetNumThreads()
+
+ self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match.')
+
+ # Get the thread object
+ thread = process.GetThreadAtIndex(0)
+
+ # Get the inferior out of its loop
+ self.runCmd("expression g_test = 1")
+
+ # Check the thread state
+ self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' after expression evaluation.")
+ self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' after expression evaluation.")
+
+ # Let the process run to completion
+ self.runCmd("process continue")
+
+
+ def process_interrupt_test(self):
+ """Test process interrupt and continue."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # This should create a breakpoint in the main thread.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_1, num_expected_locations=1)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ '* thread #1',
+ 'stop reason = breakpoint'])
+
+ # Get the target process
+ target = self.dbg.GetSelectedTarget()
+ process = target.GetProcess()
+
+ # Get the number of threads
+ num_threads = process.GetNumThreads()
+
+ self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match.')
+
+ # Continue, the inferior will go into an infinite loop waiting for 'g_test' to change.
+ self.dbg.SetAsync(True)
+ self.runCmd("continue")
+ self.wait_for_running_event()
+
+ # Go back to synchronous interactions
+ self.dbg.SetAsync(False)
+
+ # Stop the process
+ self.runCmd("process interrupt")
+
+ # The stop reason of the thread should be signal.
+ self.expect("process status", STOPPED_DUE_TO_SIGNAL,
+ substrs = ['stopped',
+ '* thread #1',
+ 'stop reason = signal'])
+
+ # Get the inferior out of its loop
+ self.runCmd("expression g_test = 1")
+
+ # Run to completion
+ self.runCmd("continue")
+
+ def thread_states_test(self):
+ """Test thread states (comprehensive)."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # This should create a breakpoint in the main thread.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_1, num_expected_locations=1)
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_2, num_expected_locations=1)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ '* thread #1',
+ 'stop reason = breakpoint'])
+
+ # Get the target process
+ target = self.dbg.GetSelectedTarget()
+ process = target.GetProcess()
+
+ # Get the number of threads
+ num_threads = process.GetNumThreads()
+
+ self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match.')
+
+ # Get the thread object
+ thread = process.GetThreadAtIndex(0)
+
+ # Make sure the thread is in the stopped state.
+ self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' during breakpoint 1.")
+ self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' during breakpoint 1.")
+
+ # Continue, the inferior will go into an infinite loop waiting for 'g_test' to change.
+ self.dbg.SetAsync(True)
+ self.runCmd("continue")
+ self.wait_for_running_event()
+
+ # Check the thread state. It should be running.
+ self.assertFalse(thread.IsStopped(), "Thread state is \'stopped\' when it should be running.")
+ self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' when it should be running.")
+
+ # Go back to synchronous interactions
+ self.dbg.SetAsync(False)
+
+ # Stop the process
+ self.runCmd("process interrupt")
+
+ # The stop reason of the thread should be signal.
+ self.expect("process status", STOPPED_DUE_TO_SIGNAL,
+ substrs = ['stopped',
+ '* thread #1',
+ 'stop reason = signal'])
+
+ # Check the thread state
+ self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' after process stop.")
+ self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' after process stop.")
+
+ # Get the inferior out of its loop
+ self.runCmd("expression g_test = 1")
+
+ # Check the thread state
+ self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' after expression evaluation.")
+ self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' after expression evaluation.")
+
+ # The stop reason of the thread should be signal.
+ self.expect("process status", STOPPED_DUE_TO_SIGNAL,
+ substrs = ['stopped',
+ '* thread #1',
+ 'stop reason = signal'])
+
+ # Run to breakpoint 2
+ self.runCmd("continue")
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ '* thread #1',
+ 'stop reason = breakpoint'])
+
+ # Make sure both threads are stopped
+ self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' during breakpoint 2.")
+ self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' during breakpoint 2.")
+
+ # Run to completion
+ self.runCmd("continue")
+
+ # At this point, the inferior process should have exited.
+ self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED)
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/state/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/state/main.cpp
new file mode 100644
index 000000000000..081203da8da9
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/state/main.cpp
@@ -0,0 +1,45 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// This test is intended to verify that thread states are properly maintained
+// when transitional actions are performed in the debugger. Most of the logic
+// is in the test script. This program merely provides places where the test
+// can create the intended states.
+
+#include <chrono>
+#include <thread>
+
+volatile int g_test = 0;
+
+int addSomething(int a)
+{
+ return a + g_test;
+}
+
+int doNothing()
+{
+ int temp = 0; // Set first breakpoint here
+
+ while (!g_test && temp < 5)
+ {
+ ++temp;
+ std::this_thread::sleep_for(std::chrono::seconds(2));
+ }
+
+ return temp; // Set second breakpoint here
+}
+
+int main ()
+{
+ int result = doNothing();
+
+ int i = addSomething(result);
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/step_out/Makefile b/packages/Python/lldbsuite/test/functionalities/thread/step_out/Makefile
new file mode 100644
index 000000000000..035413ff763d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/step_out/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+ENABLE_THREADS := YES
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py b/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py
new file mode 100644
index 000000000000..b2d966c4c0f3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py
@@ -0,0 +1,131 @@
+"""
+Test stepping out from a function in a multi-threaded program.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class ThreadStepOutTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipIfLinux # Test occasionally times out on the Linux build bot
+ @expectedFailureLinux("llvm.org/pr23477") # Test occasionally times out on the Linux build bot
+ @expectedFailureFreeBSD("llvm.org/pr18066") # inferior does not exit
+ @expectedFailureWindows # Test crashes
+ def test_step_single_thread(self):
+ """Test thread step out on one thread via command interpreter. """
+ self.build(dictionary=self.getBuildFlags())
+ self.step_out_test(self.step_out_single_thread_with_cmd)
+
+ @skipIfLinux # Test occasionally times out on the Linux build bot
+ @expectedFailureLinux("llvm.org/pr23477") # Test occasionally times out on the Linux build bot
+ @expectedFailureFreeBSD("llvm.org/pr19347") # 2nd thread stops at breakpoint
+ @expectedFailureWindows # Test crashes
+ def test_step_all_threads(self):
+ """Test thread step out on all threads via command interpreter. """
+ self.build(dictionary=self.getBuildFlags())
+ self.step_out_test(self.step_out_all_threads_with_cmd)
+
+ @skipIfLinux # Test occasionally times out on the Linux build bot
+ @expectedFailureLinux("llvm.org/pr23477") # Test occasionally times out on the Linux build bot
+ @expectedFailureFreeBSD("llvm.org/pr19347")
+ @expectedFailureWindows("llvm.org/pr24681")
+ def test_python(self):
+ """Test thread step out on one thread via Python API (dwarf)."""
+ self.build(dictionary=self.getBuildFlags())
+ self.step_out_test(self.step_out_with_python)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number for our breakpoint.
+ self.breakpoint = line_number('main.cpp', '// Set breakpoint here')
+ if "gcc" in self.getCompiler() or self.isIntelCompiler():
+ self.step_out_destination = line_number('main.cpp', '// Expect to stop here after step-out (icc and gcc)')
+ else:
+ self.step_out_destination = line_number('main.cpp', '// Expect to stop here after step-out (clang)')
+
+ def step_out_single_thread_with_cmd(self):
+ self.step_out_with_cmd("this-thread")
+ self.expect("thread backtrace all", "Thread location after step out is correct",
+ substrs = ["main.cpp:%d" % self.step_out_destination,
+ "main.cpp:%d" % self.breakpoint])
+
+ def step_out_all_threads_with_cmd(self):
+ self.step_out_with_cmd("all-threads")
+ self.expect("thread backtrace all", "Thread location after step out is correct",
+ substrs = ["main.cpp:%d" % self.step_out_destination])
+
+ def step_out_with_cmd(self, run_mode):
+ self.runCmd("thread select %d" % self.step_out_thread.GetIndexID())
+ self.runCmd("thread step-out -m %s" % run_mode)
+ self.expect("process status", "Expected stop reason to be step-out",
+ substrs = ["stop reason = step out"])
+
+ self.expect("thread list", "Selected thread did not change during step-out",
+ substrs = ["* thread #%d" % self.step_out_thread.GetIndexID()])
+
+ def step_out_with_python(self):
+ self.step_out_thread.StepOut()
+
+ reason = self.step_out_thread.GetStopReason()
+ self.assertEqual(lldb.eStopReasonPlanComplete, reason,
+ "Expected thread stop reason 'plancomplete', but got '%s'" % lldbutil.stop_reason_to_str(reason))
+
+ # Verify location after stepping out
+ frame = self.step_out_thread.GetFrameAtIndex(0)
+ desc = lldbutil.get_description(frame.GetLineEntry())
+ expect = "main.cpp:%d" % self.step_out_destination
+ self.assertTrue(expect in desc, "Expected %s but thread stopped at %s" % (expect, desc))
+
+ def step_out_test(self, step_out_func):
+ """Test single thread step out of a function."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # This should create a breakpoint in the main thread.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.breakpoint, num_expected_locations=1)
+
+ # The breakpoint list should show 1 location.
+ self.expect("breakpoint list -f", "Breakpoint location shown correctly",
+ substrs = ["1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % self.breakpoint])
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # Get the target process
+ self.inferior_target = self.dbg.GetSelectedTarget()
+ self.inferior_process = self.inferior_target.GetProcess()
+
+ # Get the number of threads, ensure we see all three.
+ num_threads = self.inferior_process.GetNumThreads()
+ self.assertEqual(num_threads, 3, 'Number of expected threads and actual threads do not match.')
+
+ (breakpoint_threads, other_threads) = ([], [])
+ lldbutil.sort_stopped_threads(self.inferior_process,
+ breakpoint_threads=breakpoint_threads,
+ other_threads=other_threads)
+
+ while len(breakpoint_threads) < 2:
+ self.runCmd("thread continue %s" % " ".join([str(x.GetIndexID()) for x in other_threads]))
+ lldbutil.sort_stopped_threads(self.inferior_process,
+ breakpoint_threads=breakpoint_threads,
+ other_threads=other_threads)
+
+ self.step_out_thread = breakpoint_threads[0]
+
+ # Step out of thread stopped at breakpoint
+ step_out_func()
+
+ # Run to completion
+ self.runCmd("continue")
+
+ # At this point, the inferior process should have exited.
+ self.assertTrue(self.inferior_process.GetState() == lldb.eStateExited, PROCESS_EXITED)
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/step_out/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/step_out/main.cpp
new file mode 100644
index 000000000000..b4c6216d6bfe
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/step_out/main.cpp
@@ -0,0 +1,63 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// This test is intended to create a situation in which two threads are stopped
+// at a breakpoint and the debugger issues a step-out command.
+
+#include <atomic>
+#include <thread>
+
+// Note that although hogging the CPU while waiting for a variable to change
+// would be terrible in production code, it's great for testing since it
+// avoids a lot of messy context switching to get multiple threads synchronized.
+#define do_nothing()
+
+#define pseudo_barrier_wait(bar) \
+ --bar; \
+ while (bar > 0) \
+ do_nothing();
+
+#define pseudo_barrier_init(bar, count) (bar = count)
+
+std::atomic_int g_barrier;
+
+volatile int g_test = 0;
+
+void step_out_of_here() {
+ g_test += 5; // Set breakpoint here
+}
+
+void *
+thread_func ()
+{
+ // Wait until both threads are running
+ pseudo_barrier_wait(g_barrier);
+
+ // Do something
+ step_out_of_here(); // Expect to stop here after step-out (clang)
+
+ // Return
+ return NULL; // Expect to stop here after step-out (icc and gcc)
+}
+
+int main ()
+{
+ // Don't let either thread do anything until they're both ready.
+ pseudo_barrier_init(g_barrier, 2);
+
+ // Create two threads
+ std::thread thread_1(thread_func);
+ std::thread thread_2(thread_func);
+
+ // Wait for the threads to finish
+ thread_1.join();
+ thread_2.join();
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/Makefile b/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/Makefile
new file mode 100644
index 000000000000..d06a7d4685f3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+ENABLE_THREADS := YES
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py b/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py
new file mode 100644
index 000000000000..f785401277a4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py
@@ -0,0 +1,116 @@
+"""
+Test number of threads.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class ThreadExitTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line numbers for our breakpoints.
+ self.break_1 = line_number('main.cpp', '// Set first breakpoint here')
+ self.break_2 = line_number('main.cpp', '// Set second breakpoint here')
+ self.break_3 = line_number('main.cpp', '// Set third breakpoint here')
+ self.break_4 = line_number('main.cpp', '// Set fourth breakpoint here')
+
+ @expectedFailureWindows("llvm.org/pr24681")
+ def test(self):
+ """Test thread exit handling."""
+ self.build(dictionary=self.getBuildFlags())
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # This should create a breakpoint with 1 location.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_1, num_expected_locations=1)
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_2, num_expected_locations=1)
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_3, num_expected_locations=1)
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_4, num_expected_locations=1)
+
+ # The breakpoint list should show 1 locations.
+ self.expect("breakpoint list -f", "Breakpoint location shown correctly",
+ substrs = ["1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % self.break_1,
+ "2: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % self.break_2,
+ "3: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % self.break_3,
+ "4: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % self.break_4])
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint 1.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT + " 1",
+ substrs = ['stopped',
+ '* thread #1',
+ 'stop reason = breakpoint 1',
+ 'thread #2'])
+
+ # Get the target process
+ target = self.dbg.GetSelectedTarget()
+ process = target.GetProcess()
+
+ # Get the number of threads
+ num_threads = process.GetNumThreads()
+
+ self.assertTrue(num_threads == 2, 'Number of expected threads and actual threads do not match at breakpoint 1.')
+
+ # Run to the second breakpoint
+ self.runCmd("continue")
+
+ # The stop reason of the thread should be breakpoint 1.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT + " 2",
+ substrs = ['stopped',
+ 'thread #1',
+ 'thread #2',
+ 'stop reason = breakpoint 2',
+ 'thread #3'])
+
+ # Update the number of threads
+ num_threads = process.GetNumThreads()
+
+ self.assertTrue(num_threads == 3, 'Number of expected threads and actual threads do not match at breakpoint 2.')
+
+ # Run to the third breakpoint
+ self.runCmd("continue")
+
+ # The stop reason of the thread should be breakpoint 3.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT + " 3",
+ substrs = ['stopped',
+ 'thread #1',
+ 'stop reason = breakpoint 3',
+ 'thread #3',
+ ])
+
+ # Update the number of threads
+ num_threads = process.GetNumThreads()
+
+ self.assertTrue(num_threads == 2, 'Number of expected threads and actual threads do not match at breakpoint 3.')
+
+ # Run to the fourth breakpoint
+ self.runCmd("continue")
+
+ # The stop reason of the thread should be breakpoint 4.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT + " 4",
+ substrs = ['stopped',
+ 'thread #1',
+ 'stop reason = breakpoint 4'])
+
+ # Update the number of threads
+ num_threads = process.GetNumThreads()
+
+ self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match at breakpoint 4.')
+
+ # Run to completion
+ self.runCmd("continue")
+
+ # At this point, the inferior process should have exited.
+ self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED)
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/main.cpp
new file mode 100644
index 000000000000..e498db7895d2
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/main.cpp
@@ -0,0 +1,85 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// This test verifies the correct handling of child thread exits.
+
+#include <atomic>
+#include <thread>
+
+// Note that although hogging the CPU while waiting for a variable to change
+// would be terrible in production code, it's great for testing since it
+// avoids a lot of messy context switching to get multiple threads synchronized.
+#define do_nothing()
+
+#define pseudo_barrier_wait(bar) \
+ --bar; \
+ while (bar > 0) \
+ do_nothing();
+
+#define pseudo_barrier_init(bar, count) (bar = count)
+
+std::atomic_int g_barrier1;
+std::atomic_int g_barrier2;
+std::atomic_int g_barrier3;
+
+void *
+thread1 ()
+{
+ // Synchronize with the main thread.
+ pseudo_barrier_wait(g_barrier1);
+
+ // Synchronize with the main thread and thread2.
+ pseudo_barrier_wait(g_barrier2);
+
+ // Return
+ return NULL; // Set second breakpoint here
+}
+
+void *
+thread2 ()
+{
+ // Synchronize with thread1 and the main thread.
+ pseudo_barrier_wait(g_barrier2);
+
+ // Synchronize with the main thread.
+ pseudo_barrier_wait(g_barrier3);
+
+ // Return
+ return NULL;
+}
+
+int main ()
+{
+ pseudo_barrier_init(g_barrier1, 2);
+ pseudo_barrier_init(g_barrier2, 3);
+ pseudo_barrier_init(g_barrier3, 2);
+
+ // Create a thread.
+ std::thread thread_1(thread1);
+
+ // Wait for thread1 to start.
+ pseudo_barrier_wait(g_barrier1);
+
+ // Create another thread.
+ std::thread thread_2(thread2); // Set first breakpoint here
+
+ // Wait for thread2 to start.
+ pseudo_barrier_wait(g_barrier2);
+
+ // Wait for the first thread to finish
+ thread_1.join();
+
+ // Synchronize with the remaining thread
+ pseudo_barrier_wait(g_barrier3); // Set third breakpoint here
+
+ // Wait for the second thread to finish
+ thread_2.join();
+
+ return 0; // Set fourth breakpoint here
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/Makefile b/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/Makefile
new file mode 100644
index 000000000000..035413ff763d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+ENABLE_THREADS := YES
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/TestThreadSpecificBreakpoint.py b/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/TestThreadSpecificBreakpoint.py
new file mode 100644
index 000000000000..3c69b6667f7d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/TestThreadSpecificBreakpoint.py
@@ -0,0 +1,63 @@
+"""
+Test that we obey thread conditioned breakpoints.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import re
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+class ThreadSpecificBreakTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @add_test_categories(['pyapi'])
+ @expectedFailureWindows # Thread specific breakpoints cause the inferior to crash
+ def test_python(self):
+ """Test that we obey thread conditioned breakpoints."""
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # This test works by setting a breakpoint in a function conditioned to stop only on
+ # the main thread, and then calling this function on a secondary thread, joining,
+ # and then calling again on the main thread. If the thread specific breakpoint works
+ # then it should not be hit on the secondary thread, only on the main thread.
+
+ main_source_spec = lldb.SBFileSpec ("main.cpp")
+
+ main_breakpoint = target.BreakpointCreateBySourceRegex("Set main breakpoint here", main_source_spec);
+ thread_breakpoint = target.BreakpointCreateBySourceRegex("Set thread-specific breakpoint here", main_source_spec)
+
+ self.assertTrue(main_breakpoint.IsValid(), "Failed to set main breakpoint.")
+ self.assertGreater(main_breakpoint.GetNumLocations(), 0, "main breakpoint has no locations associated with it.")
+ self.assertTrue(thread_breakpoint.IsValid(), "Failed to set thread breakpoint.")
+ self.assertGreater(thread_breakpoint.GetNumLocations(), 0, "thread breakpoint has no locations associated with it.")
+
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ stopped_threads = lldbutil.get_threads_stopped_at_breakpoint(process, main_breakpoint)
+ self.assertEqual(len(stopped_threads), 1, "main breakpoint stopped at unexpected number of threads")
+ main_thread = stopped_threads[0]
+ main_thread_id = main_thread.GetThreadID()
+
+ # Set the thread-specific breakpoint to only stop on the main thread. The run the function
+ # on another thread and join on it. If the thread-specific breakpoint works, the next
+ # stop should be on the main thread.
+ thread_breakpoint.SetThreadID(main_thread_id)
+
+ process.Continue()
+ next_stop_state = process.GetState()
+ self.assertEqual(next_stop_state, lldb.eStateStopped, "We should have stopped at the thread breakpoint.")
+ stopped_threads = lldbutil.get_threads_stopped_at_breakpoint(process, thread_breakpoint)
+ self.assertEqual(len(stopped_threads), 1, "thread breakpoint stopped at unexpected number of threads")
+ self.assertEqual(stopped_threads[0].GetThreadID(), main_thread_id, "thread breakpoint stopped at the wrong thread")
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/main.cpp
new file mode 100644
index 000000000000..7721b5d84322
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/main.cpp
@@ -0,0 +1,20 @@
+#include <chrono>
+#include <thread>
+
+void
+thread_function ()
+{
+ // Set thread-specific breakpoint here.
+ std::this_thread::sleep_for(std::chrono::microseconds(100));
+}
+
+int
+main ()
+{
+ // Set main breakpoint here.
+ std::thread t(thread_function);
+ t.join();
+
+ thread_function();
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/Makefile b/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/Makefile
new file mode 100644
index 000000000000..035413ff763d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+ENABLE_THREADS := YES
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/TestThreadSpecificBpPlusCondition.py b/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/TestThreadSpecificBpPlusCondition.py
new file mode 100644
index 000000000000..b4a0b7a5dd4e
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/TestThreadSpecificBpPlusCondition.py
@@ -0,0 +1,65 @@
+"""
+Test that we obey thread conditioned breakpoints and expression
+conditioned breakpoints simultaneously
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import re
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+class ThreadSpecificBreakPlusConditionTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipIfFreeBSD # test frequently times out or hangs
+ @expectedFailureFreeBSD('llvm.org/pr18522') # hits break in another thread in testrun
+ @add_test_categories(['pyapi'])
+ @expectedFailureWindows # Thread specific breakpoints cause the inferior to crash.
+ @expectedFlakeyLinux # this test fails 6/100 dosep runs
+ def test_python(self):
+ """Test that we obey thread conditioned breakpoints."""
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ main_source_spec = lldb.SBFileSpec ("main.cpp")
+
+ # Set a breakpoint in the thread body, and make it active for only the first thread.
+ break_thread_body = target.BreakpointCreateBySourceRegex ("Break here in thread body.", main_source_spec)
+ self.assertTrue (break_thread_body.IsValid() and break_thread_body.GetNumLocations() > 0, "Failed to set thread body breakpoint.")
+
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ threads = lldbutil.get_threads_stopped_at_breakpoint (process, break_thread_body)
+
+ victim_thread = threads[0]
+
+ # Pick one of the threads, and change the breakpoint so it ONLY stops for this thread,
+ # but add a condition that it won't stop for this thread's my_value. The other threads
+ # pass the condition, so they should stop, but if the thread-specification is working
+ # they should not stop. So nobody should hit the breakpoint anymore, and we should
+ # just exit cleanly.
+
+ frame = victim_thread.GetFrameAtIndex(0)
+ value = frame.FindVariable("my_value").GetValueAsSigned(0)
+ self.assertTrue (value > 0 and value < 11, "Got a reasonable value for my_value.")
+
+ cond_string = "my_value != %d"%(value)
+
+ break_thread_body.SetThreadID(victim_thread.GetThreadID())
+ break_thread_body.SetCondition (cond_string)
+
+ process.Continue()
+
+ next_stop_state = process.GetState()
+ self.assertTrue (next_stop_state == lldb.eStateExited, "We should have not hit the breakpoint again.")
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/main.cpp
new file mode 100644
index 000000000000..af8ab84157fd
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/main.cpp
@@ -0,0 +1,39 @@
+#include <chrono>
+#include <thread>
+#include <vector>
+
+void *
+thread_function (void *thread_marker)
+{
+ int keep_going = 1;
+ int my_value = *((int *)thread_marker);
+ int counter = 0;
+
+ while (counter < 20)
+ {
+ counter++; // Break here in thread body.
+ std::this_thread::sleep_for(std::chrono::microseconds(10));
+ }
+ return NULL;
+}
+
+
+int
+main ()
+{
+ std::vector<std::thread> threads;
+
+ int thread_value = 0;
+ int i;
+
+ for (i = 0; i < 10; i++)
+ {
+ thread_value += 1;
+ threads.push_back(std::thread(thread_function, &thread_value));
+ }
+
+ for (i = 0; i < 10; i++)
+ threads[i].join();
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/tty/TestTerminal.py b/packages/Python/lldbsuite/test/functionalities/tty/TestTerminal.py
new file mode 100644
index 000000000000..5697c2c37283
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/tty/TestTerminal.py
@@ -0,0 +1,40 @@
+"""
+Test lldb command aliases.
+"""
+
+from __future__ import print_function
+
+
+
+import unittest2
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class LaunchInTerminalTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ # Darwin is the only platform that I know of that supports optionally launching
+ # a program in a separate terminal window. It would be great if other platforms
+ # added support for this.
+ @skipUnlessDarwin
+ @expectedFailureDarwin("llvm.org/pr25484")
+ # If the test is being run under sudo, the spawned terminal won't retain that elevated
+ # privilege so it can't open the socket to talk back to the test case
+ @unittest2.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0, "test cannot be run as root")
+ # Do we need to disable this test if the testsuite is being run on a remote system?
+ # This env var is only defined when the shell is running in a local mac terminal window
+ @unittest2.skipUnless('TERM_PROGRAM' in os.environ, "test must be run on local system")
+ @no_debug_info_test
+ def test_launch_in_terminal (self):
+ exe = "/bin/ls"
+ target = self.dbg.CreateTarget(exe)
+ launch_info = lldb.SBLaunchInfo(["-lAF", "/tmp/"])
+ launch_info.SetLaunchFlags(lldb.eLaunchFlagLaunchInTTY | lldb.eLaunchFlagCloseTTYOnExit)
+ error = lldb.SBError()
+ process = target.Launch (launch_info, error)
+ self.assertTrue(error.Success(), "Make sure launch happened successfully in a terminal window")
+ # Running in synchronous mode our process should have run and already exited by the time target.Launch() returns
+ self.assertTrue(process.GetState() == lldb.eStateExited)
diff --git a/packages/Python/lldbsuite/test/functionalities/type_completion/Makefile b/packages/Python/lldbsuite/test/functionalities/type_completion/Makefile
new file mode 100644
index 000000000000..b69775dc199a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/type_completion/Makefile
@@ -0,0 +1,12 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+# clang-3.5+ outputs FullDebugInfo by default for Darwin/FreeBSD
+# targets. Other targets do not, which causes this test to fail.
+# This flag enables FullDebugInfo for all targets.
+ifneq (,$(findstring clang,$(CC)))
+ CFLAGS_EXTRAS += -fno-limit-debug-info
+endif
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/type_completion/TestTypeCompletion.py b/packages/Python/lldbsuite/test/functionalities/type_completion/TestTypeCompletion.py
new file mode 100644
index 000000000000..5a238b7d3542
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/type_completion/TestTypeCompletion.py
@@ -0,0 +1,108 @@
+"""
+Check that types only get completed when necessary.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class TypeCompletionTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureIcc # often fails with 'NameAndAddress should be valid'
+ # Fails with gcc 4.8.1 with llvm.org/pr15301 LLDB prints incorrect sizes of STL containers
+ def test_with_run_command(self):
+ """Check that types only get completed when necessary."""
+ self.build()
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_source_regexp (self, "// Set break point at this line.")
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # 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 category enable -l c++', check=False)
+
+ self.runCmd('type category disable -l c++', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ p_vector = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('p')
+ p_type = p_vector.GetType()
+ self.assertFalse(p_type.IsTypeComplete(), 'vector<T> complete but it should not be')
+
+ self.runCmd("continue")
+
+ p_vector = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('p')
+ p_type = p_vector.GetType()
+ self.assertFalse(p_type.IsTypeComplete(), 'vector<T> complete but it should not be')
+
+ self.runCmd("continue")
+
+ self.runCmd("frame variable p --show-types")
+
+ p_vector = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('p')
+ p_type = p_vector.GetType()
+ self.assertTrue(p_type.IsTypeComplete(), 'vector<T> should now be complete')
+ name_address_type = p_type.GetTemplateArgumentType(0)
+ self.assertTrue(name_address_type.IsValid(), 'NameAndAddress should be valid')
+ self.assertFalse(name_address_type.IsTypeComplete(), 'NameAndAddress complete but it should not be')
+
+ self.runCmd("continue")
+
+ self.runCmd("frame variable guy --show-types")
+
+ p_vector = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('p')
+ p_type = p_vector.GetType()
+ self.assertTrue(p_type.IsTypeComplete(), 'vector<T> should now be complete')
+ name_address_type = p_type.GetTemplateArgumentType(0)
+ self.assertTrue(name_address_type.IsValid(), 'NameAndAddress should be valid')
+ self.assertTrue(name_address_type.IsTypeComplete(), 'NameAndAddress should now be complete')
+ field0 = name_address_type.GetFieldAtIndex(0)
+ self.assertTrue(field0.IsValid(), 'NameAndAddress::m_name should be valid')
+ string = field0.GetType().GetPointeeType()
+ self.assertTrue(string.IsValid(), 'CustomString should be valid')
+ self.assertFalse(string.IsTypeComplete(), 'CustomString complete but it should not be')
+
+ self.runCmd("continue")
+
+ p_vector = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('p')
+ p_type = p_vector.GetType()
+ self.assertTrue(p_type.IsTypeComplete(), 'vector<T> should now be complete')
+ name_address_type = p_type.GetTemplateArgumentType(0)
+ self.assertTrue(name_address_type.IsValid(), 'NameAndAddress should be valid')
+ self.assertTrue(name_address_type.IsTypeComplete(), 'NameAndAddress should now be complete')
+ field0 = name_address_type.GetFieldAtIndex(0)
+ self.assertTrue(field0.IsValid(), 'NameAndAddress::m_name should be valid')
+ string = field0.GetType().GetPointeeType()
+ self.assertTrue(string.IsValid(), 'CustomString should be valid')
+ self.assertFalse(string.IsTypeComplete(), 'CustomString complete but it should not be')
+
+ self.runCmd('type category enable -l c++', check=False)
+ self.runCmd('frame variable guy --show-types --ptr-depth=1')
+
+ p_vector = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('p')
+ p_type = p_vector.GetType()
+ self.assertTrue(p_type.IsTypeComplete(), 'vector<T> should now be complete')
+ name_address_type = p_type.GetTemplateArgumentType(0)
+ self.assertTrue(name_address_type.IsValid(), 'NameAndAddress should be valid')
+ self.assertTrue(name_address_type.IsTypeComplete(), 'NameAndAddress should now be complete')
+ field0 = name_address_type.GetFieldAtIndex(0)
+ self.assertTrue(field0.IsValid(), 'NameAndAddress::m_name should be valid')
+ string = field0.GetType().GetPointeeType()
+ self.assertTrue(string.IsValid(), 'CustomString should be valid')
+ self.assertTrue(string.IsTypeComplete(), 'CustomString should now be complete')
diff --git a/packages/Python/lldbsuite/test/functionalities/type_completion/main.cpp b/packages/Python/lldbsuite/test/functionalities/type_completion/main.cpp
new file mode 100644
index 000000000000..80329737928e
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/type_completion/main.cpp
@@ -0,0 +1,81 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <string.h>
+#include <vector>
+#include <iostream>
+
+class CustomString
+{
+public:
+ CustomString (const char* buffer) :
+ m_buffer(nullptr)
+ {
+ if (buffer)
+ {
+ auto l = strlen(buffer);
+ m_buffer = new char[1 + l];
+ strcpy(m_buffer, buffer);
+ }
+ }
+
+ ~CustomString ()
+ {
+ delete[] m_buffer;
+ }
+
+ const char*
+ GetBuffer ()
+ {
+ return m_buffer;
+ }
+
+private:
+ char *m_buffer;
+};
+
+class NameAndAddress
+ {
+ public:
+ CustomString& GetName() { return *m_name; }
+ CustomString& GetAddress() { return *m_address; }
+ NameAndAddress(const char* N, const char* A) : m_name(new CustomString(N)), m_address(new CustomString(A))
+ {
+ }
+ ~NameAndAddress()
+ {
+ }
+
+ private:
+ CustomString* m_name;
+ CustomString* m_address;
+};
+
+typedef std::vector<NameAndAddress> People;
+
+int main (int argc, const char * argv[])
+{
+ People p;
+ p.push_back(NameAndAddress("Enrico","123 Main Street"));
+ p.push_back(NameAndAddress("Foo","10710 Johnson Avenue")); // Set break point at this line.
+ p.push_back(NameAndAddress("Arpia","6956 Florey Street"));
+ p.push_back(NameAndAddress("Apple","1 Infinite Loop")); // Set break point at this line.
+ p.push_back(NameAndAddress("Richard","9500 Gilman Drive"));
+ p.push_back(NameAndAddress("Bar","3213 Windsor Rd"));
+
+ for (int j = 0; j<p.size(); j++)
+ {
+ NameAndAddress guy = p[j];
+ std::cout << "Person " << j << " is named " << guy.GetName().GetBuffer() << " and lives at " << guy.GetAddress().GetBuffer() << std::endl; // Set break point at this line.
+ }
+
+ return 0;
+
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/type_lookup/Makefile b/packages/Python/lldbsuite/test/functionalities/type_lookup/Makefile
new file mode 100644
index 000000000000..31e57fe28a58
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/type_lookup/Makefile
@@ -0,0 +1,9 @@
+LEVEL = ../../make
+
+OBJC_SOURCES := main.m
+
+CFLAGS_EXTRAS += -w
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation
diff --git a/packages/Python/lldbsuite/test/functionalities/type_lookup/TestTypeLookup.py b/packages/Python/lldbsuite/test/functionalities/type_lookup/TestTypeLookup.py
new file mode 100644
index 000000000000..ca0b1f1d1e53
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/type_lookup/TestTypeLookup.py
@@ -0,0 +1,43 @@
+"""
+Test type lookup command.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import datetime
+import lldbsuite.test.lldbutil as lldbutil
+
+class TypeLookupTestCase(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.m', '// break here')
+
+ @skipUnlessDarwin
+ def test_type_lookup(self):
+ """Test type lookup command."""
+ self.build()
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ self.expect('type lookup NoSuchType', substrs=['@interface'], matching=False)
+ self.expect('type lookup NSURL', substrs=['NSURL'])
+ self.expect('type lookup NSArray', substrs=['NSArray'])
+ self.expect('type lookup NSObject', substrs=['NSObject', 'isa'])
diff --git a/packages/Python/lldbsuite/test/functionalities/type_lookup/main.m b/packages/Python/lldbsuite/test/functionalities/type_lookup/main.m
new file mode 100644
index 000000000000..058a0c00e92c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/type_lookup/main.m
@@ -0,0 +1,16 @@
+//===-- main.m ------------------------------------------------*- ObjC -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#import <Foundation/Foundation.h>
+
+int main (int argc, const char * argv[])
+{
+ return 0; // break here
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/unwind/noreturn/Makefile b/packages/Python/lldbsuite/test/functionalities/unwind/noreturn/Makefile
new file mode 100644
index 000000000000..ede25f029bcd
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/unwind/noreturn/Makefile
@@ -0,0 +1,7 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+CFLAGS ?= -g -Os
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/unwind/noreturn/TestNoreturnUnwind.py b/packages/Python/lldbsuite/test/functionalities/unwind/noreturn/TestNoreturnUnwind.py
new file mode 100644
index 000000000000..a419500f7a17
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/unwind/noreturn/TestNoreturnUnwind.py
@@ -0,0 +1,76 @@
+"""
+Test that we can backtrace correctly with 'noreturn' functions on the stack
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class NoreturnUnwind(TestBase):
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailurei386 #xfail to get buildbot green, failing config: i386 binary running on ubuntu 14.04 x86_64
+ @skipIfWindows # clang-cl does not support gcc style attributes.
+ def test (self):
+ """Test that we can backtrace correctly with 'noreturn' functions on the stack"""
+ self.build()
+ self.setTearDownCleanup()
+
+ exe = os.path.join(os.getcwd(), "a.out")
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ if not process:
+ self.fail("SBTarget.Launch() failed")
+
+ if process.GetState() != lldb.eStateStopped:
+ self.fail("Process should be in the 'stopped' state, "
+ "instead the actual state is: '%s'" %
+ lldbutil.state_type_to_str(process.GetState()))
+
+ thread = process.GetThreadAtIndex(0)
+ abort_frame_number = 0
+ for f in thread.frames:
+ # Some C libraries mangle the abort symbol into __GI_abort.
+ if f.GetFunctionName() in ["abort", "__GI_abort"]:
+ break
+ abort_frame_number = abort_frame_number + 1
+
+ if self.TraceOn():
+ print("Backtrace once we're stopped:")
+ for f in thread.frames:
+ print(" %d %s" % (f.GetFrameID(), f.GetFunctionName()))
+
+ # I'm going to assume that abort() ends up calling/invoking another
+ # function before halting the process. In which case if abort_frame_number
+ # equals 0, we didn't find abort() in the backtrace.
+ if abort_frame_number == len(thread.frames):
+ self.fail("Unable to find abort() in backtrace.")
+
+ func_c_frame_number = abort_frame_number + 1
+ if thread.GetFrameAtIndex (func_c_frame_number).GetFunctionName() != "func_c":
+ self.fail("Did not find func_c() above abort().")
+
+ # This depends on whether we see the func_b inlined function in the backtrace
+ # or not. I'm not interested in testing that aspect of the backtrace here
+ # right now.
+
+ if thread.GetFrameAtIndex (func_c_frame_number + 1).GetFunctionName() == "func_b":
+ func_a_frame_number = func_c_frame_number + 2
+ else:
+ func_a_frame_number = func_c_frame_number + 1
+
+ if thread.GetFrameAtIndex (func_a_frame_number).GetFunctionName() != "func_a":
+ self.fail("Did not find func_a() above func_c().")
+
+ main_frame_number = func_a_frame_number + 1
+
+ if thread.GetFrameAtIndex (main_frame_number).GetFunctionName() != "main":
+ self.fail("Did not find main() above func_a().")
diff --git a/packages/Python/lldbsuite/test/functionalities/unwind/noreturn/main.c b/packages/Python/lldbsuite/test/functionalities/unwind/noreturn/main.c
new file mode 100644
index 000000000000..7190e38f5d8c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/unwind/noreturn/main.c
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static void func_a (void) __attribute__((noinline));
+static void func_b (void) __attribute__((noreturn));
+static void func_c (void) __attribute__((noinline));
+
+static void
+func_c (void)
+{
+ abort ();
+}
+
+static void
+func_b (void)
+{
+ func_c ();
+ while (1)
+ ;
+}
+
+static void
+func_a (void)
+{
+ func_b ();
+}
+
+int
+main (int argc, char *argv[])
+{
+ sleep (2);
+
+ func_a ();
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/unwind/sigtramp/Makefile b/packages/Python/lldbsuite/test/functionalities/unwind/sigtramp/Makefile
new file mode 100644
index 000000000000..b09a579159d4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/unwind/sigtramp/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/unwind/sigtramp/TestSigtrampUnwind.py b/packages/Python/lldbsuite/test/functionalities/unwind/sigtramp/TestSigtrampUnwind.py
new file mode 100644
index 000000000000..ddfb1122b6f1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/unwind/sigtramp/TestSigtrampUnwind.py
@@ -0,0 +1,81 @@
+"""
+Test that we can backtrace correctly with 'sigtramp' functions on the stack
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class SigtrampUnwind(TestBase):
+ mydir = TestBase.compute_mydir(__file__)
+
+ # On different platforms the "_sigtramp" and "__kill" frames are likely to be different.
+ # This test could probably be adapted to run on linux/*bsd easily enough.
+ @skipUnlessDarwin
+ def test (self):
+ """Test that we can backtrace correctly with _sigtramp on the stack"""
+ self.build()
+ self.setTearDownCleanup()
+
+ exe = os.path.join(os.getcwd(), "a.out")
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.c", line_number('main.c', '// Set breakpoint here'), num_expected_locations=1)
+
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ if not process:
+ self.fail("SBTarget.Launch() failed")
+
+ if process.GetState() != lldb.eStateStopped:
+ self.fail("Process should be in the 'stopped' state, "
+ "instead the actual state is: '%s'" %
+ lldbutil.state_type_to_str(process.GetState()))
+
+ self.expect("pro handle -n false -p true -s false SIGUSR1", "Have lldb pass SIGUSR1 signals",
+ substrs = ["SIGUSR1", "true", "false", "false"])
+
+ lldbutil.run_break_set_by_symbol (self, "handler", num_expected_locations=1, module_name="a.out")
+
+ self.runCmd("continue")
+
+ thread = process.GetThreadAtIndex(0)
+
+ found_handler = False
+ found_sigtramp = False
+ found_kill = False
+ found_main = False
+
+ for f in thread.frames:
+ if f.GetFunctionName() == "handler":
+ found_handler = True
+ if f.GetFunctionName() == "_sigtramp":
+ found_sigtramp = True
+ if f.GetFunctionName() == "__kill":
+ found_kill = True
+ if f.GetFunctionName() == "main":
+ found_main = True
+
+ if self.TraceOn():
+ print("Backtrace once we're stopped:")
+ for f in thread.frames:
+ print(" %d %s" % (f.GetFrameID(), f.GetFunctionName()))
+
+ if found_handler == False:
+ self.fail("Unable to find handler() in backtrace.")
+
+ if found_sigtramp == False:
+ self.fail("Unable to find _sigtramp() in backtrace.")
+
+ if found_kill == False:
+ self.fail("Unable to find kill() in backtrace.")
+
+ if found_main == False:
+ self.fail("Unable to find main() in backtrace.")
diff --git a/packages/Python/lldbsuite/test/functionalities/unwind/sigtramp/main.c b/packages/Python/lldbsuite/test/functionalities/unwind/sigtramp/main.c
new file mode 100644
index 000000000000..aaa03e7aa843
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/unwind/sigtramp/main.c
@@ -0,0 +1,27 @@
+#include <stdlib.h>
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+
+void handler (int in)
+{
+ puts ("in handler routine");
+ while (1)
+ ;
+}
+
+void
+foo ()
+{
+ puts ("in foo ()");
+ kill (getpid(), SIGUSR1);
+}
+int main ()
+{
+ puts ("in main"); // Set breakpoint here
+ signal (SIGUSR1, handler);
+ puts ("signal handler set up");
+ foo();
+ puts ("exiting");
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/unwind/standard/Makefile b/packages/Python/lldbsuite/test/functionalities/unwind/standard/Makefile
new file mode 100644
index 000000000000..146da30b12cb
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/unwind/standard/Makefile
@@ -0,0 +1,3 @@
+LEVEL = ../../../make
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/unwind/standard/TestStandardUnwind.py b/packages/Python/lldbsuite/test/functionalities/unwind/standard/TestStandardUnwind.py
new file mode 100644
index 000000000000..3f88e7b6e1aa
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/unwind/standard/TestStandardUnwind.py
@@ -0,0 +1,145 @@
+"""
+Test that we can backtrace correctly from standard functions.
+
+This test suit is a collection of automatically generated tests from the source files in the
+directory. Please DON'T add individual test cases to this file.
+
+To add a new test case to this test suit please create a simple C/C++ application and put the
+source file into the directory of the test cases. The test suit will automatically pick the
+file up and generate a test case from it in run time (with name test_standard_unwind_<file_name>
+after escaping some special characters).
+"""
+
+from __future__ import print_function
+
+
+
+import unittest2
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+test_source_dirs = ["."]
+
+class StandardUnwindTest(TestBase):
+ mydir = TestBase.compute_mydir(__file__)
+
+ def standard_unwind_tests (self):
+ # The following variables have to be defined for each architecture and OS we testing for:
+ # base_function_names: List of function names where we accept that the stack unwinding is
+ # correct if they are on the stack. It should include the bottom most
+ # function on the stack and a list of functions where we know we can't
+ # unwind for any reason (list of expected failure functions)
+ # no_step_function_names: The list of functions where we don't want to step through
+ # instruction by instruction for any reason. (A valid reason is if
+ # it is impossible to step through a function instruction by
+ # instruction because it is special for some reason.) For these
+ # functions we will immediately do a step-out when we hit them.
+
+ triple = self.dbg.GetSelectedPlatform().GetTriple()
+ if re.match("arm-.*-.*-android", triple):
+ base_function_names = [
+ "_start", # Base function on the stack
+ "__memcpy_base", # Function reached by a fall through from the previous function
+ "__memcpy_base_aligned", # Function reached by a fall through from the previous function
+ ]
+ no_step_function_names = [
+ "__sync_fetch_and_add_4", # Calls into a special SO where we can't set a breakpoint
+ "pthread_mutex_lock", # Uses ldrex and strex what interferes with the software single stepping
+ "pthread_mutex_unlock", # Uses ldrex and strex what interferes with the software single stepping
+ "pthread_once", # Uses ldrex and strex what interferes with the software single stepping
+ ]
+ elif re.match("aarch64-.*-.*-android", triple):
+ base_function_names = [
+ "do_arm64_start", # Base function on the stack
+ ]
+ no_step_function_names = [
+ None,
+ "__cxa_guard_acquire", # Uses ldxr and stxr what interferes with the software single stepping
+ "__cxa_guard_release", # Uses ldxr and stxr what interferes with the software single stepping
+ "pthread_mutex_lock", # Uses ldxr and stxr what interferes with the software single stepping
+ "pthread_mutex_unlock", # Uses ldxr and stxr what interferes with the software single stepping
+ "pthread_once", # Uses ldxr and stxr what interferes with the software single stepping
+ ]
+ else:
+ self.skipTest("No expectations for the current architecture")
+
+ exe = os.path.join(os.getcwd(), "a.out")
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ target.BreakpointCreateByName("main")
+
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+ self.assertTrue(process is not None, "SBTarget.Launch() failed")
+ self.assertEqual(process.GetState(), lldb.eStateStopped, "The process didn't hit main")
+
+ index = 0
+ while process.GetState() == lldb.eStateStopped:
+ index += 1
+ if process.GetNumThreads() > 1:
+ # In case of a multi threaded inferior if one of the thread is stopped in a blocking
+ # syscall and we try to step it then SBThread::StepInstruction() will block forever
+ self.skipTest("Multi threaded inferiors are not supported by this test")
+
+ thread = process.GetThreadAtIndex(0)
+
+ if self.TraceOn():
+ print("INDEX: %u" % index)
+ for f in thread.frames:
+ print(f)
+
+ if thread.GetFrameAtIndex(0).GetFunctionName() is not None:
+ found_main = False
+ for f in thread.frames:
+ if f.GetFunctionName() in base_function_names:
+ found_main = True
+ break
+ self.assertTrue(found_main, "Main function isn't found on the backtrace")
+
+ if thread.GetFrameAtIndex(0).GetFunctionName() in no_step_function_names:
+ thread.StepOut()
+ else:
+ thread.StepInstruction(False)
+
+# Collect source files in the specified directories
+test_source_files = set([])
+for d in test_source_dirs:
+ if os.path.isabs(d):
+ dirname = d
+ else:
+ dirname = os.path.join(os.path.dirname(__file__), d)
+
+ for root, _, files in os.walk(dirname):
+ test_source_files = test_source_files | set(os.path.abspath(os.path.join(root, f)) for f in files)
+
+# Generate test cases based on the collected source files
+for f in test_source_files:
+ if f.endswith(".cpp") or f.endswith(".c"):
+ @add_test_categories(["dwarf"])
+ @unittest2.skipIf(TestBase.skipLongRunningTest(), "Skip this long running test")
+ def test_function_dwarf(self, f=f):
+ if f.endswith(".cpp"):
+ d = {'CXX_SOURCES': f}
+ elif f.endswith(".c"):
+ d = {'C_SOURCES': f}
+
+ # If we can't compile the inferior just skip the test instead of failing it.
+ # It makes the test suit more robust when testing on several different architecture
+ # avoid the hassle of skipping tests manually.
+ try:
+ self.buildDwarf(dictionary=d)
+ self.setTearDownCleanup(d)
+ except:
+ if self.TraceOn():
+ print(sys.exc_info()[0])
+ self.skipTest("Inferior not supported")
+ self.standard_unwind_tests()
+
+ test_name = "test_unwind_" + str(f)
+ for c in ".=()/\\":
+ test_name = test_name.replace(c, '_')
+
+ test_function_dwarf.__name__ = test_name
+ setattr(StandardUnwindTest, test_function_dwarf.__name__, test_function_dwarf)
diff --git a/packages/Python/lldbsuite/test/functionalities/unwind/standard/hand_written/divmod.cpp b/packages/Python/lldbsuite/test/functionalities/unwind/standard/hand_written/divmod.cpp
new file mode 100644
index 000000000000..75df6ba89372
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/unwind/standard/hand_written/divmod.cpp
@@ -0,0 +1,15 @@
+//===-- divmod.cpp ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int
+main(int argc, char const *argv[])
+{
+ signed long long a = 123456789, b = 12, c = a / b, d = a % b;
+ unsigned long long e = 123456789, f = 12, g = e / f, h = e % f;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/unwind/standard/hand_written/fprintf.cpp b/packages/Python/lldbsuite/test/functionalities/unwind/standard/hand_written/fprintf.cpp
new file mode 100644
index 000000000000..188738cb9bab
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/unwind/standard/hand_written/fprintf.cpp
@@ -0,0 +1,16 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <cstdio>
+
+int
+main(int argc, char const *argv[])
+{
+ fprintf(stderr, "%d %p %s\n", argc, argv, argv[0]);
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/unwind/standard/hand_written/new_delete.cpp b/packages/Python/lldbsuite/test/functionalities/unwind/standard/hand_written/new_delete.cpp
new file mode 100644
index 000000000000..d240b89e50ab
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/unwind/standard/hand_written/new_delete.cpp
@@ -0,0 +1,15 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int
+main(int argc, char const *argv[])
+{
+ int* p = new int;
+ delete p;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/value_md5_crash/Makefile b/packages/Python/lldbsuite/test/functionalities/value_md5_crash/Makefile
new file mode 100644
index 000000000000..8a7102e347af
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/value_md5_crash/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/value_md5_crash/TestValueMD5Crash.py b/packages/Python/lldbsuite/test/functionalities/value_md5_crash/TestValueMD5Crash.py
new file mode 100644
index 000000000000..763ecc94c2eb
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/value_md5_crash/TestValueMD5Crash.py
@@ -0,0 +1,52 @@
+"""
+Verify that the hash computing logic for ValueObject's values can't crash us.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class ValueMD5CrashTestCase(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', '// break here')
+
+ @expectedFailureWindows("llvm.org/pr24663")
+ def test_with_run_command(self):
+ """Verify that the hash computing logic for ValueObject's values can't crash us."""
+ 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, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ value = self.frame().FindVariable("a")
+ value.SetPreferDynamicValue(lldb.eDynamicCanRunTarget)
+
+ v = value.GetValue()
+ type_name = value.GetTypeName()
+ self.assertTrue(type_name == "B *", "a is a B*")
+
+ self.runCmd("next")
+ self.runCmd("process kill")
+
+ # now the process is dead, and value needs updating
+ v = value.GetValue()
+
+ # if we are here, instead of crashed, the test succeeded
diff --git a/packages/Python/lldbsuite/test/functionalities/value_md5_crash/main.cpp b/packages/Python/lldbsuite/test/functionalities/value_md5_crash/main.cpp
new file mode 100644
index 000000000000..ba596b8653cf
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/value_md5_crash/main.cpp
@@ -0,0 +1,29 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+class A {
+public:
+ virtual int foo() { return 1; }
+ virtual ~A () = default;
+ A() = default;
+};
+
+class B : public A {
+public:
+ virtual int foo() { return 2; }
+ virtual ~B () = default;
+ B() = default;
+};
+
+int main() {
+ A* a = new B();
+ a->foo(); // break here
+ return 0; // break here
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/Makefile b/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/Makefile
new file mode 100644
index 000000000000..8817fff55e8c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+ENABLE_THREADS := YES
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/TestWatchLocation.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/TestWatchLocation.py
new file mode 100644
index 000000000000..f0a0b5ab99d0
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/TestWatchLocation.py
@@ -0,0 +1,98 @@
+"""
+Test lldb watchpoint that uses '-s size' to watch a pointed location with size.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import re
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class HelloWatchLocationTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Our simple source filename.
+ self.source = 'main.cpp'
+ # Find the line number to break inside main().
+ self.line = line_number(self.source, '// Set break point at this line.')
+ # This is for verifying that watch location works.
+ self.violating_func = "do_bad_thing_with_location";
+ # Build dictionary to have unique executable names for each test method.
+ self.exe_name = self.testMethodName
+ self.d = {'CXX_SOURCES': self.source, 'EXE': self.exe_name}
+
+ @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ @expectedFailureAll(archs=['mips', 'mipsel', 'mips64', 'mips64el']) # Most of the MIPS boards provide only one H/W watchpoints, and S/W watchpoints are not supported yet
+ def test_hello_watchlocation(self):
+ """Test watching a location with '-s size' option."""
+ self.build(dictionary=self.d)
+ self.setTearDownCleanup(dictionary=self.d)
+ exe = os.path.join(os.getcwd(), self.exe_name)
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
+ lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1, loc_exact=False)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # We should be stopped again due to the breakpoint.
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Now let's set a write-type watchpoint pointed to by 'g_char_ptr'.
+ # The main.cpp, by design, misbehaves by not following the agreed upon
+ # protocol of using a mutex while accessing the global pool and by not
+ # incrmenting the global pool by 2.
+ self.expect("watchpoint set expression -w write -s 1 -- g_char_ptr", WATCHPOINT_CREATED,
+ substrs = ['Watchpoint created', 'size = 1', 'type = w'])
+ # Get a hold of the watchpoint id just created, it is used later on to
+ # match the watchpoint id which is expected to be fired.
+ match = re.match("Watchpoint created: Watchpoint (.*):", self.res.GetOutput().splitlines()[0])
+ if match:
+ expected_wp_id = int(match.group(1), 0)
+ else:
+ self.fail("Grokking watchpoint id faailed!")
+
+ self.runCmd("expr unsigned val = *g_char_ptr; val")
+ self.expect(self.res.GetOutput().splitlines()[0], exe=False,
+ endstr = ' = 0')
+
+ self.runCmd("watchpoint set expression -w write -s 4 -- &threads[0]")
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should be 0 initially.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 0'])
+
+ self.runCmd("process continue")
+
+ # We should be stopped again due to the watchpoint (write type), but
+ # only once. The stop reason of the thread should be watchpoint.
+ self.expect("thread list", STOPPED_DUE_TO_WATCHPOINT,
+ substrs = ['stopped',
+ 'stop reason = watchpoint %d' % expected_wp_id])
+
+ # Switch to the thread stopped due to watchpoint and issue some commands.
+ self.switch_to_thread_with_stop_reason(lldb.eStopReasonWatchpoint)
+ self.runCmd("thread backtrace")
+ self.expect("frame info",
+ substrs = [self.violating_func])
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should now be 1.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 1'])
+
+ self.runCmd("thread backtrace all")
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/main.cpp b/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/main.cpp
new file mode 100644
index 000000000000..59b0afc6d5f7
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/main.cpp
@@ -0,0 +1,106 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <chrono>
+#include <condition_variable>
+#include <cstdio>
+#include <random>
+#include <thread>
+
+std::default_random_engine g_random_engine{std::random_device{}()};
+std::uniform_int_distribution<> g_distribution{0, 3000000};
+std::condition_variable g_condition_variable;
+std::mutex g_mutex;
+int g_count;
+
+char *g_char_ptr = nullptr;
+
+void
+barrier_wait()
+{
+ std::unique_lock<std::mutex> lock{g_mutex};
+ if (--g_count > 0)
+ g_condition_variable.wait(lock);
+ else
+ g_condition_variable.notify_all();
+}
+
+void
+do_bad_thing_with_location(char *char_ptr, char new_val)
+{
+ unsigned what = new_val;
+ printf("new value written to location(%p) = %u\n", char_ptr, what);
+ *char_ptr = new_val;
+}
+
+uint32_t
+access_pool (bool flag = false)
+{
+ static std::mutex g_access_mutex;
+ if (!flag)
+ g_access_mutex.lock();
+
+ char old_val = *g_char_ptr;
+ if (flag)
+ do_bad_thing_with_location(g_char_ptr, old_val + 1);
+
+ if (!flag)
+ g_access_mutex.unlock();
+ return *g_char_ptr;
+}
+
+void
+thread_func (uint32_t thread_index)
+{
+ printf ("%s (thread index = %u) startng...\n", __FUNCTION__, thread_index);
+
+ barrier_wait();
+
+ uint32_t count = 0;
+ uint32_t val;
+ while (count++ < 15)
+ {
+ // random micro second sleep from zero to 3 seconds
+ int usec = g_distribution(g_random_engine);
+ printf ("%s (thread = %u) doing a usleep (%d)...\n", __FUNCTION__, thread_index, usec);
+ std::this_thread::sleep_for(std::chrono::microseconds{usec});
+
+ if (count < 7)
+ val = access_pool ();
+ else
+ val = access_pool (true);
+
+ printf ("%s (thread = %u) after usleep access_pool returns %d (count=%d)...\n", __FUNCTION__, thread_index, val, count);
+ }
+ printf ("%s (thread index = %u) exiting...\n", __FUNCTION__, thread_index);
+}
+
+
+int main (int argc, char const *argv[])
+{
+ g_count = 4;
+ std::thread threads[3];
+
+ g_char_ptr = new char{};
+
+ // Create 3 threads
+ for (auto &thread : threads)
+ thread = std::thread{thread_func, std::distance(threads, &thread)};
+
+ printf ("Before turning all three threads loose...\n"); // Set break point at this line.
+ barrier_wait();
+
+ // Join all of our threads
+ for (auto &thread : threads)
+ thread.join();
+
+ delete g_char_ptr;
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchpoint/Makefile b/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchpoint/Makefile
new file mode 100644
index 000000000000..b09a579159d4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchpoint/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchpoint/TestMyFirstWatchpoint.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchpoint/TestMyFirstWatchpoint.py
new file mode 100644
index 000000000000..57467c38d5f8
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchpoint/TestMyFirstWatchpoint.py
@@ -0,0 +1,84 @@
+"""
+Test my first lldb watchpoint.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class HelloWatchpointTestCase(TestBase):
+
+ def getCategories (self):
+ return ['basic_process']
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Our simple source filename.
+ self.source = 'main.c'
+ # Find the line number to break inside main().
+ self.line = line_number(self.source, '// Set break point at this line.')
+ # And the watchpoint variable declaration line number.
+ self.decl = line_number(self.source, '// Watchpoint variable declaration.')
+ self.exe_name = 'a.out'
+ self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
+
+ @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureWindows("llvm.org/pr24446")
+ def test_hello_watchpoint_using_watchpoint_set(self):
+ """Test a simple sequence of watchpoint creation and watchpoint hit."""
+ self.build(dictionary=self.d)
+ self.setTearDownCleanup(dictionary=self.d)
+
+ exe = os.path.join(os.getcwd(), self.exe_name)
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
+ lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # We should be stopped again due to the breakpoint.
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Now let's set a write-type watchpoint for 'global'.
+ # There should be only one watchpoint hit (see main.c).
+ self.expect("watchpoint set variable -w write global", WATCHPOINT_CREATED,
+ substrs = ['Watchpoint created', 'size = 4', 'type = w',
+ '%s:%d' % (self.source, self.decl)])
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should be 0 initially.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 0'])
+
+ self.runCmd("process continue")
+
+ # We should be stopped again due to the watchpoint (write type), but
+ # only once. The stop reason of the thread should be watchpoint.
+ self.expect("thread list", STOPPED_DUE_TO_WATCHPOINT,
+ substrs = ['stopped',
+ 'stop reason = watchpoint'])
+
+ self.runCmd("process continue")
+
+ # Don't expect the read of 'global' to trigger a stop exception.
+ process = self.dbg.GetSelectedTarget().GetProcess()
+ if process.GetState() == lldb.eStateStopped:
+ self.assertFalse(lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint))
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should now be 1.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 1'])
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchpoint/main.c b/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchpoint/main.c
new file mode 100644
index 000000000000..11a738a0de43
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchpoint/main.c
@@ -0,0 +1,30 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+#include <stdint.h>
+
+int32_t global = 10; // Watchpoint variable declaration.
+char gchar1 = 'a';
+char gchar2 = 'b';
+
+int main(int argc, char** argv) {
+ int local = 0;
+ printf("&global=%p\n", &global);
+ printf("about to write to 'global'...\n"); // Set break point at this line.
+ // When stopped, watch 'global' for write.
+ global = 20;
+ gchar1 += 1;
+ gchar2 += 1;
+ local += argc;
+ ++local;
+ printf("local: %d\n", local);
+ printf("global=%d\n", global);
+ printf("gchar1='%c'\n", gchar1);
+ printf("gchar2='%c'\n", gchar2);
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/Makefile b/packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/Makefile
new file mode 100644
index 000000000000..8817fff55e8c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+ENABLE_THREADS := YES
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/TestWatchpointMultipleThreads.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/TestWatchpointMultipleThreads.py
new file mode 100644
index 000000000000..2318214a0d5c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/TestWatchpointMultipleThreads.py
@@ -0,0 +1,137 @@
+"""
+Test that lldb watchpoint works for multiple threads.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import re
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class WatchpointForMultipleThreadsTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ def test_watchpoint_multiple_threads(self):
+ """Test that lldb watchpoint works for multiple threads."""
+ self.build()
+ self.setTearDownCleanup()
+ self.hello_multiple_threads()
+
+ @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ def test_watchpoint_multiple_threads_wp_set_and_then_delete(self):
+ """Test that lldb watchpoint works for multiple threads, and after the watchpoint is deleted, the watchpoint event should no longer fires."""
+ self.build()
+ self.setTearDownCleanup()
+ self.hello_multiple_threads_wp_set_and_then_delete()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Our simple source filename.
+ self.source = 'main.cpp'
+ # Find the line number to break inside main().
+ self.first_stop = line_number(self.source, '// Set break point at this line')
+
+ def hello_multiple_threads(self):
+ """Test that lldb watchpoint works for multiple threads."""
+ self.runCmd("file %s" % os.path.join(os.getcwd(), 'a.out'), CURRENT_EXECUTABLE_SET)
+
+ # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
+ lldbutil.run_break_set_by_file_and_line (self, None, self.first_stop, num_expected_locations=1)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # We should be stopped again due to the breakpoint.
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Now let's set a write-type watchpoint for variable 'g_val'.
+ # The main.cpp, by design, misbehaves by not following the agreed upon
+ # protocol of using a mutex while accessing the global pool and by not
+ # writing to the variable.
+ self.expect("watchpoint set variable -w write g_val", WATCHPOINT_CREATED,
+ substrs = ['Watchpoint created', 'size = 4', 'type = w'])
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should be 0 initially.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 0'])
+
+ while True:
+ self.runCmd("process continue")
+
+ self.runCmd("thread list")
+ if "stop reason = watchpoint" in self.res.GetOutput():
+ # Good, we verified that the watchpoint works!
+ self.runCmd("thread backtrace all")
+ break
+ else:
+ self.fail("The stop reason should be either break or watchpoint")
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should now be 1.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 1'])
+
+ def hello_multiple_threads_wp_set_and_then_delete(self):
+ """Test that lldb watchpoint works for multiple threads, and after the watchpoint is deleted, the watchpoint event should no longer fires."""
+ self.runCmd("file %s" % os.path.join(os.getcwd(), 'a.out'), CURRENT_EXECUTABLE_SET)
+
+ # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
+ lldbutil.run_break_set_by_file_and_line (self, None, self.first_stop, num_expected_locations=1)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # We should be stopped again due to the breakpoint.
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Now let's set a write-type watchpoint for variable 'g_val'.
+ # The main.cpp, by design, misbehaves by not following the agreed upon
+ # protocol of using a mutex while accessing the global pool and by not
+ # writing to the variable.
+ self.expect("watchpoint set variable -w write g_val", WATCHPOINT_CREATED,
+ substrs = ['Watchpoint created', 'size = 4', 'type = w'])
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should be 0 initially.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 0'])
+
+ watchpoint_stops = 0
+ while True:
+ self.runCmd("process continue")
+ self.runCmd("process status")
+ if re.search("Process .* exited", self.res.GetOutput()):
+ # Great, we are done with this test!
+ break
+
+ self.runCmd("thread list")
+ if "stop reason = watchpoint" in self.res.GetOutput():
+ self.runCmd("thread backtrace all")
+ watchpoint_stops += 1
+ if watchpoint_stops > 1:
+ self.fail("Watchpoint hits not supposed to exceed 1 by design!")
+ # Good, we verified that the watchpoint works! Now delete the watchpoint.
+ if self.TraceOn():
+ print("watchpoint_stops=%d at the moment we delete the watchpoint" % watchpoint_stops)
+ self.runCmd("watchpoint delete 1")
+ self.expect("watchpoint list -v",
+ substrs = ['No watchpoints currently set.'])
+ continue
+ else:
+ self.fail("The stop reason should be either break or watchpoint")
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/main.cpp b/packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/main.cpp
new file mode 100644
index 000000000000..8a31041f8fca
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/main.cpp
@@ -0,0 +1,83 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <chrono>
+#include <cstdio>
+#include <mutex>
+#include <random>
+#include <thread>
+
+std::default_random_engine g_random_engine{std::random_device{}()};
+std::uniform_int_distribution<> g_distribution{0, 3000000};
+
+uint32_t g_val = 0;
+
+
+uint32_t
+access_pool (bool flag = false)
+{
+ static std::mutex g_access_mutex;
+ if (!flag)
+ g_access_mutex.lock();
+
+ uint32_t old_val = g_val;
+ if (flag)
+ {
+ printf("changing g_val to %d...\n", old_val + 1);
+ g_val = old_val + 1;
+ }
+
+ if (!flag)
+ g_access_mutex.unlock();
+ return g_val;
+}
+
+void
+thread_func (uint32_t thread_index)
+{
+ // Break here in order to allow the thread
+ // to inherit the global watchpoint state.
+ printf ("%s (thread index = %u) startng...\n", __FUNCTION__, thread_index);
+
+ uint32_t count = 0;
+ uint32_t val;
+ while (count++ < 15)
+ {
+ // random micro second sleep from zero to 3 seconds
+ int usec = g_distribution(g_random_engine);
+ printf ("%s (thread = %u) doing a usleep (%d)...\n", __FUNCTION__, thread_index, usec);
+ std::this_thread::sleep_for(std::chrono::microseconds{usec});
+
+ if (count < 7)
+ val = access_pool ();
+ else
+ val = access_pool (true);
+
+ printf ("%s (thread = %u) after usleep access_pool returns %d (count=%d)...\n", __FUNCTION__, thread_index, val, count);
+ }
+ printf ("%s (thread index = %u) exiting...\n", __FUNCTION__, thread_index);
+}
+
+
+int main (int argc, char const *argv[])
+{
+ std::thread threads[3];
+
+ printf ("Before turning all three threads loose...\n"); // Set break point at this line,
+ // in order to set our watchpoint.
+ // Create 3 threads
+ for (auto &thread : threads)
+ thread = std::thread{thread_func, std::distance(threads, &thread)};
+
+ // Join all of our threads
+ for (auto &thread : threads)
+ thread.join();
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/Makefile b/packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/Makefile
new file mode 100644
index 000000000000..b09a579159d4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/TestStepOverWatchpoint.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/TestStepOverWatchpoint.py
new file mode 100644
index 000000000000..dd18a6482066
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/TestStepOverWatchpoint.py
@@ -0,0 +1,113 @@
+"""Test stepping over watchpoints."""
+
+from __future__ import print_function
+
+
+
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+
+class TestStepOverWatchpoint(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def getCategories(self):
+ return ['basic_process']
+
+ @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureWindows("llvm.org/pr24446")
+ def test(self):
+ """Test stepping over watchpoints."""
+ self.build()
+ exe = os.path.join(os.getcwd(), 'a.out')
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(self.target, VALID_TARGET)
+
+ lldbutil.run_break_set_by_symbol(self, 'main')
+
+ process = target.LaunchSimple(None, None,
+ self.get_process_working_directory())
+ self.assertTrue(process.IsValid(), PROCESS_IS_VALID)
+ self.assertTrue(process.GetState() == lldb.eStateStopped,
+ PROCESS_STOPPED)
+
+ thread = lldbutil.get_stopped_thread(process,
+ lldb.eStopReasonBreakpoint)
+ self.assertTrue(thread.IsValid(), "Failed to get thread.")
+
+ frame = thread.GetFrameAtIndex(0)
+ self.assertTrue(frame.IsValid(), "Failed to get frame.")
+
+ read_value = frame.FindValue('g_watch_me_read',
+ lldb.eValueTypeVariableGlobal)
+ self.assertTrue(read_value.IsValid(), "Failed to find read value.")
+
+ error = lldb.SBError()
+
+ # resolve_location=True, read=True, write=False
+ read_watchpoint = read_value.Watch(True, True, False, error)
+ self.assertTrue(error.Success(),
+ "Error while setting watchpoint: %s" %
+ error.GetCString())
+ self.assertTrue(read_watchpoint, "Failed to set read watchpoint.")
+
+ thread.StepOver()
+ self.assertTrue(thread.GetStopReason() == lldb.eStopReasonWatchpoint,
+ STOPPED_DUE_TO_WATCHPOINT)
+ self.assertTrue(thread.GetStopDescription(20) == 'watchpoint 1')
+
+ process.Continue()
+ self.assertTrue(process.GetState() == lldb.eStateStopped,
+ PROCESS_STOPPED)
+ self.assertTrue(thread.GetStopDescription(20) == 'step over')
+
+ self.step_inst_for_watchpoint(1)
+
+ write_value = frame.FindValue('g_watch_me_write',
+ lldb.eValueTypeVariableGlobal)
+ self.assertTrue(write_value, "Failed to find write value.")
+
+ # Most of the MIPS boards provide only one H/W watchpoints, and S/W watchpoints are not supported yet
+ arch = self.getArchitecture()
+ if arch in ['mips', 'mipsel', 'mips64', 'mips64el']:
+ self.runCmd("watchpoint delete 1")
+
+ # resolve_location=True, read=False, write=True
+ write_watchpoint = write_value.Watch(True, False, True, error)
+ self.assertTrue(read_watchpoint, "Failed to set write watchpoint.")
+ self.assertTrue(error.Success(),
+ "Error while setting watchpoint: %s" %
+ error.GetCString())
+
+ thread.StepOver()
+ self.assertTrue(thread.GetStopReason() == lldb.eStopReasonWatchpoint,
+ STOPPED_DUE_TO_WATCHPOINT)
+ self.assertTrue(thread.GetStopDescription(20) == 'watchpoint 2')
+
+ process.Continue()
+ self.assertTrue(process.GetState() == lldb.eStateStopped,
+ PROCESS_STOPPED)
+ self.assertTrue(thread.GetStopDescription(20) == 'step over')
+
+ self.step_inst_for_watchpoint(2)
+
+ def step_inst_for_watchpoint(self, wp_id):
+ watchpoint_hit = False
+ current_line = self.frame().GetLineEntry().GetLine()
+ while self.frame().GetLineEntry().GetLine() == current_line:
+ self.thread().StepInstruction(False) # step_over=False
+ stop_reason = self.thread().GetStopReason()
+ if stop_reason == lldb.eStopReasonWatchpoint:
+ self.assertFalse(watchpoint_hit, "Watchpoint already hit.")
+ expected_stop_desc = "watchpoint %d" % wp_id
+ actual_stop_desc = self.thread().GetStopDescription(20)
+ self.assertTrue(actual_stop_desc == expected_stop_desc,
+ "Watchpoint ID didn't match.")
+ watchpoint_hit = True
+ else:
+ self.assertTrue(stop_reason == lldb.eStopReasonPlanComplete,
+ STOPPED_DUE_TO_STEP_IN)
+ self.assertTrue(watchpoint_hit, "Watchpoint never hit.")
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/main.c b/packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/main.c
new file mode 100644
index 000000000000..2d87d9a2f73f
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/main.c
@@ -0,0 +1,19 @@
+char g_watch_me_read;
+char g_watch_me_write;
+char g_temp;
+
+void watch_read() {
+ g_temp = g_watch_me_read;
+}
+
+void watch_write() {
+ g_watch_me_write = g_temp;
+}
+
+int main() {
+ watch_read();
+ g_temp = g_watch_me_read;
+ watch_write();
+ g_watch_me_write = g_temp;
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/variable_out_of_scope/Makefile b/packages/Python/lldbsuite/test/functionalities/watchpoint/variable_out_of_scope/Makefile
new file mode 100644
index 000000000000..b09a579159d4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/variable_out_of_scope/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/variable_out_of_scope/TestWatchedVarHitWhenInScope.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/variable_out_of_scope/TestWatchedVarHitWhenInScope.py
new file mode 100644
index 000000000000..21f1fb68426b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/variable_out_of_scope/TestWatchedVarHitWhenInScope.py
@@ -0,0 +1,83 @@
+"""
+Test that a variable watchpoint should only hit when in scope.
+"""
+
+from __future__ import print_function
+
+
+
+import unittest2
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class WatchedVariableHitWhenInScopeTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ #
+ # This test depends on not tracking watchpoint expression hits if we have
+ # left the watchpoint scope. We will provide such an ability at some point
+ # but the way this was done was incorrect, and it is unclear that for the
+ # most part that's not what folks mostly want, so we have to provide a
+ # clearer API to express this.
+ #
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Our simple source filename.
+ self.source = 'main.c'
+ self.exe_name = self.testMethodName
+ self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
+
+ @unittest2.expectedFailure("rdar://problem/18685649")
+ def test_watched_var_should_only_hit_when_in_scope(self):
+ """Test that a variable watchpoint should only hit when in scope."""
+ self.build(dictionary=self.d)
+ self.setTearDownCleanup(dictionary=self.d)
+
+ exe = os.path.join(os.getcwd(), self.exe_name)
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Add a breakpoint to set a watchpoint when stopped in main.
+ lldbutil.run_break_set_by_symbol (self, "main", num_expected_locations=-1)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # We should be stopped again due to the breakpoint.
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Now let's set a watchpoint for 'c.a'.
+ # There should be only one watchpoint hit (see main.c).
+ self.expect("watchpoint set variable c.a", WATCHPOINT_CREATED,
+ substrs = ['Watchpoint created', 'size = 4', 'type = w'])
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should be 0 initially.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 0'])
+
+ self.runCmd("process continue")
+
+ # We should be stopped again due to the watchpoint (write type), but
+ # only once. The stop reason of the thread should be watchpoint.
+ self.expect("thread list", STOPPED_DUE_TO_WATCHPOINT,
+ substrs = ['stopped',
+ 'stop reason = watchpoint'])
+
+ self.runCmd("process continue")
+ # Don't expect the read of 'global' to trigger a stop exception.
+ # The process status should be 'exited'.
+ self.expect("process status",
+ substrs = ['exited'])
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should now be 1.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 1'])
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/variable_out_of_scope/main.c b/packages/Python/lldbsuite/test/functionalities/watchpoint/variable_out_of_scope/main.c
new file mode 100644
index 000000000000..1bf7a00ac837
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/variable_out_of_scope/main.c
@@ -0,0 +1,15 @@
+typedef struct
+{
+ int a;
+ float b;
+} mystruct;
+
+int main()
+{
+ mystruct c;
+
+ c.a = 5;
+ c.b = 3.6;
+
+ return 0;
+} \ No newline at end of file
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/Makefile b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/Makefile
new file mode 100644
index 000000000000..b09a579159d4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/TestWatchpointCommands.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/TestWatchpointCommands.py
new file mode 100644
index 000000000000..339de45a085a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/TestWatchpointCommands.py
@@ -0,0 +1,313 @@
+"""
+Test watchpoint list, enable, disable, and delete commands.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class WatchpointCommandsTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Our simple source filename.
+ self.source = 'main.c'
+ # Find the line number to break inside main().
+ self.line = line_number(self.source, '// Set break point at this line.')
+ self.line2 = line_number(self.source, '// Set 2nd break point for disable_then_enable test case.')
+ # And the watchpoint variable declaration line number.
+ self.decl = line_number(self.source, '// Watchpoint variable declaration.')
+ # Build dictionary to have unique executable names for each test method.
+ self.exe_name = self.testMethodName
+ self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
+
+ @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ def test_rw_watchpoint(self):
+ """Test read_write watchpoint and expect to stop two times."""
+ self.build(dictionary=self.d)
+ self.setTearDownCleanup(dictionary=self.d)
+
+ exe = os.path.join(os.getcwd(), self.exe_name)
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
+ lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # We should be stopped again due to the breakpoint.
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Now let's set a read_write-type watchpoint for 'global'.
+ # There should be two watchpoint hits (see main.c).
+ self.expect("watchpoint set variable -w read_write global", WATCHPOINT_CREATED,
+ substrs = ['Watchpoint created', 'size = 4', 'type = rw',
+ '%s:%d' % (self.source, self.decl)])
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should be 0 initially.
+ self.expect("watchpoint list -v",
+ substrs = ['Number of supported hardware watchpoints:',
+ 'hit_count = 0'])
+
+ self.runCmd("process continue")
+
+ # We should be stopped again due to the watchpoint (read_write type).
+ # The stop reason of the thread should be watchpoint.
+ self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT,
+ substrs = ['stop reason = watchpoint'])
+
+ self.runCmd("process continue")
+
+ # We should be stopped again due to the watchpoint (read_write type).
+ # The stop reason of the thread should be watchpoint.
+ self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT,
+ substrs = ['stop reason = watchpoint'])
+
+ self.runCmd("process continue")
+
+ # There should be no more watchpoint hit and the process status should
+ # be 'exited'.
+ self.expect("process status",
+ substrs = ['exited'])
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should now be 2.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 2'])
+
+ @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ def test_rw_watchpoint_delete(self):
+ """Test delete watchpoint and expect not to stop for watchpoint."""
+ self.build(dictionary=self.d)
+ self.setTearDownCleanup(dictionary=self.d)
+
+ exe = os.path.join(os.getcwd(), self.exe_name)
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
+ lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # We should be stopped again due to the breakpoint.
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Now let's set a read_write-type watchpoint for 'global'.
+ # There should be two watchpoint hits (see main.c).
+ self.expect("watchpoint set variable -w read_write global", WATCHPOINT_CREATED,
+ substrs = ['Watchpoint created', 'size = 4', 'type = rw',
+ '%s:%d' % (self.source, self.decl)])
+
+ # Delete the watchpoint immediately, but set auto-confirm to true first.
+ self.runCmd("settings set auto-confirm true")
+ self.expect("watchpoint delete",
+ substrs = ['All watchpoints removed.'])
+ # Restore the original setting of auto-confirm.
+ self.runCmd("settings clear auto-confirm")
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ self.runCmd("watchpoint list -v")
+
+ self.runCmd("process continue")
+
+ # There should be no more watchpoint hit and the process status should
+ # be 'exited'.
+ self.expect("process status",
+ substrs = ['exited'])
+
+ @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ def test_rw_watchpoint_set_ignore_count(self):
+ """Test watchpoint ignore count and expect to not to stop at all."""
+ self.build(dictionary=self.d)
+ self.setTearDownCleanup(dictionary=self.d)
+
+ exe = os.path.join(os.getcwd(), self.exe_name)
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
+ lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # We should be stopped again due to the breakpoint.
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Now let's set a read_write-type watchpoint for 'global'.
+ # There should be two watchpoint hits (see main.c).
+ self.expect("watchpoint set variable -w read_write global", WATCHPOINT_CREATED,
+ substrs = ['Watchpoint created', 'size = 4', 'type = rw',
+ '%s:%d' % (self.source, self.decl)])
+
+ # Set the ignore count of the watchpoint immediately.
+ self.expect("watchpoint ignore -i 2",
+ substrs = ['All watchpoints ignored.'])
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # Expect to find an ignore_count of 2.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 0', 'ignore_count = 2'])
+
+ self.runCmd("process continue")
+
+ # There should be no more watchpoint hit and the process status should
+ # be 'exited'.
+ self.expect("process status",
+ substrs = ['exited'])
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # Expect to find a hit_count of 2 as well.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 2', 'ignore_count = 2'])
+
+ @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ def test_rw_disable_after_first_stop(self):
+ """Test read_write watchpoint but disable it after the first stop."""
+ self.build(dictionary=self.d)
+ self.setTearDownCleanup(dictionary=self.d)
+
+ exe = os.path.join(os.getcwd(), self.exe_name)
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
+ lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # We should be stopped again due to the breakpoint.
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Now let's set a read_write-type watchpoint for 'global'.
+ # There should be two watchpoint hits (see main.c).
+ self.expect("watchpoint set variable -w read_write global", WATCHPOINT_CREATED,
+ substrs = ['Watchpoint created', 'size = 4', 'type = rw',
+ '%s:%d' % (self.source, self.decl)])
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should be 0 initially.
+ self.expect("watchpoint list -v",
+ substrs = ['state = enabled', 'hit_count = 0'])
+
+ self.runCmd("process continue")
+
+ # We should be stopped again due to the watchpoint (read_write type).
+ # The stop reason of the thread should be watchpoint.
+ self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT,
+ substrs = ['stop reason = watchpoint'])
+
+ # Before continuing, we'll disable the watchpoint, which means we won't
+ # stop again after this.
+ self.runCmd("watchpoint disable")
+
+ self.expect("watchpoint list -v",
+ substrs = ['state = disabled', 'hit_count = 1'])
+
+ self.runCmd("process continue")
+
+ # There should be no more watchpoint hit and the process status should
+ # be 'exited'.
+ self.expect("process status",
+ substrs = ['exited'])
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should be 1.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 1'])
+
+ @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ def test_rw_disable_then_enable(self):
+ """Test read_write watchpoint, disable initially, then enable it."""
+ self.build(dictionary=self.d)
+ self.setTearDownCleanup(dictionary=self.d)
+
+ exe = os.path.join(os.getcwd(), self.exe_name)
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
+ lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1)
+ lldbutil.run_break_set_by_file_and_line (self, None, self.line2, num_expected_locations=1)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # We should be stopped again due to the breakpoint.
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Now let's set a read_write-type watchpoint for 'global'.
+ # There should be two watchpoint hits (see main.c).
+ self.expect("watchpoint set variable -w read_write global", WATCHPOINT_CREATED,
+ substrs = ['Watchpoint created', 'size = 4', 'type = rw',
+ '%s:%d' % (self.source, self.decl)])
+
+ # Immediately, we disable the watchpoint. We won't be stopping due to a
+ # watchpoint after this.
+ self.runCmd("watchpoint disable")
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should be 0 initially.
+ self.expect("watchpoint list -v",
+ substrs = ['state = disabled', 'hit_count = 0'])
+
+ self.runCmd("process continue")
+
+ # We should be stopped again due to the breakpoint.
+ self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stop reason = breakpoint'])
+
+ # Before continuing, we'll enable the watchpoint, which means we will
+ # stop again after this.
+ self.runCmd("watchpoint enable")
+
+ self.expect("watchpoint list -v",
+ substrs = ['state = enabled', 'hit_count = 0'])
+
+ self.runCmd("process continue")
+
+ # We should be stopped again due to the watchpoint (read_write type).
+ # The stop reason of the thread should be watchpoint.
+ self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT,
+ substrs = ['stop reason = watchpoint'])
+
+ self.runCmd("process continue")
+
+ # There should be no more watchpoint hit and the process status should
+ # be 'exited'.
+ self.expect("process status",
+ substrs = ['exited'])
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should be 1.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 1'])
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/Makefile b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/Makefile
new file mode 100644
index 000000000000..ee6b9cc62b40
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py
new file mode 100644
index 000000000000..f2bf90866330
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py
@@ -0,0 +1,139 @@
+"""
+Test 'watchpoint command'.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class WatchpointLLDBCommandTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Our simple source filename.
+ self.source = 'main.cpp'
+ # Find the line number to break inside main().
+ self.line = line_number(self.source, '// Set break point at this line.')
+ # And the watchpoint variable declaration line number.
+ self.decl = line_number(self.source, '// Watchpoint variable declaration.')
+ # Build dictionary to have unique executable names for each test method.
+ self.exe_name = 'a%d.out' % self.test_number
+ self.d = {'CXX_SOURCES': self.source, 'EXE': self.exe_name}
+
+ @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ def test_watchpoint_command(self):
+ """Test 'watchpoint command'."""
+ self.build(dictionary=self.d)
+ self.setTearDownCleanup(dictionary=self.d)
+
+ exe = os.path.join(os.getcwd(), self.exe_name)
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
+ lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # We should be stopped again due to the breakpoint.
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Now let's set a write-type watchpoint for 'global'.
+ self.expect("watchpoint set variable -w write global", WATCHPOINT_CREATED,
+ substrs = ['Watchpoint created', 'size = 4', 'type = w',
+ '%s:%d' % (self.source, self.decl)])
+
+ self.runCmd('watchpoint command add 1 -o "expr -- cookie = 777"')
+
+ # List the watchpoint command we just added.
+ self.expect("watchpoint command list 1",
+ substrs = ['expr -- cookie = 777'])
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should be 0 initially.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 0'])
+
+ self.runCmd("process continue")
+
+ # We should be stopped again due to the watchpoint (write type).
+ # The stop reason of the thread should be watchpoint.
+ self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT,
+ substrs = ['stop reason = watchpoint'])
+
+ # Check that the watchpoint snapshoting mechanism is working.
+ self.expect("watchpoint list -v",
+ substrs = ['old value:', ' = 0',
+ 'new value:', ' = 1'])
+
+ # The watchpoint command "forced" our global variable 'cookie' to become 777.
+ self.expect("frame variable --show-globals cookie",
+ substrs = ['(int32_t)', 'cookie = 777'])
+
+ @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ def test_watchpoint_command_can_disable_a_watchpoint(self):
+ """Test that 'watchpoint command' action can disable a watchpoint after it is triggered."""
+ self.build(dictionary=self.d)
+ self.setTearDownCleanup(dictionary=self.d)
+
+ exe = os.path.join(os.getcwd(), self.exe_name)
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
+ lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # We should be stopped again due to the breakpoint.
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Now let's set a write-type watchpoint for 'global'.
+ self.expect("watchpoint set variable -w write global", WATCHPOINT_CREATED,
+ substrs = ['Watchpoint created', 'size = 4', 'type = w',
+ '%s:%d' % (self.source, self.decl)])
+
+ self.runCmd('watchpoint command add 1 -o "watchpoint disable 1"')
+
+ # List the watchpoint command we just added.
+ self.expect("watchpoint command list 1",
+ substrs = ['watchpoint disable 1'])
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should be 0 initially.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 0'])
+
+ self.runCmd("process continue")
+
+ # We should be stopped again due to the watchpoint (write type).
+ # The stop reason of the thread should be watchpoint.
+ self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT,
+ substrs = ['stop reason = watchpoint'])
+
+ # Check that the watchpoint has been disabled.
+ self.expect("watchpoint list -v",
+ substrs = ['disabled'])
+
+ self.runCmd("process continue")
+
+ # There should be no more watchpoint hit and the process status should
+ # be 'exited'.
+ self.expect("process status",
+ substrs = ['exited'])
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py
new file mode 100644
index 000000000000..a476aebb8db9
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py
@@ -0,0 +1,87 @@
+"""
+Test 'watchpoint command'.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class WatchpointPythonCommandTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Our simple source filename.
+ self.source = 'main.cpp'
+ # Find the line number to break inside main().
+ self.line = line_number(self.source, '// Set break point at this line.')
+ # And the watchpoint variable declaration line number.
+ self.decl = line_number(self.source, '// Watchpoint variable declaration.')
+ # Build dictionary to have unique executable names for each test method.
+ self.exe_name = self.testMethodName
+ self.d = {'CXX_SOURCES': self.source, 'EXE': self.exe_name}
+
+ @skipIfFreeBSD # timing out on buildbot
+ @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ def test_watchpoint_command(self):
+ """Test 'watchpoint command'."""
+ self.build(dictionary=self.d)
+ self.setTearDownCleanup(dictionary=self.d)
+
+ exe = os.path.join(os.getcwd(), self.exe_name)
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
+ lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1)
+# self.expect("breakpoint set -l %d" % self.line, BREAKPOINT_CREATED,
+# startstr = "Breakpoint created: 1: file ='%s', line = %d, locations = 1" %
+# (self.source, self.line))#
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # We should be stopped again due to the breakpoint.
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Now let's set a write-type watchpoint for 'global'.
+ self.expect("watchpoint set variable -w write global", WATCHPOINT_CREATED,
+ substrs = ['Watchpoint created', 'size = 4', 'type = w',
+ '%s:%d' % (self.source, self.decl)])
+
+ self.runCmd('watchpoint command add -s python 1 -o \'frame.EvaluateExpression("cookie = 777")\'')
+
+ # List the watchpoint command we just added.
+ self.expect("watchpoint command list 1",
+ substrs = ['frame.EvaluateExpression', 'cookie = 777'])
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should be 0 initially.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 0'])
+
+ self.runCmd("process continue")
+
+ # We should be stopped again due to the watchpoint (write type).
+ # The stop reason of the thread should be watchpoint.
+ self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT,
+ substrs = ['stop reason = watchpoint'])
+
+ # Check that the watchpoint snapshoting mechanism is working.
+ self.expect("watchpoint list -v",
+ substrs = ['old value:', ' = 0',
+ 'new value:', ' = 1'])
+
+ # The watchpoint command "forced" our global variable 'cookie' to become 777.
+ self.expect("frame variable --show-globals cookie",
+ substrs = ['(int32_t)', 'cookie = 777'])
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/main.cpp b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/main.cpp
new file mode 100644
index 000000000000..6cb80c62217e
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/main.cpp
@@ -0,0 +1,28 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+#include <stdint.h>
+
+int32_t global = 0; // Watchpoint variable declaration.
+int32_t cookie = 0;
+
+static void modify(int32_t &var) {
+ ++var;
+}
+
+int main(int argc, char** argv) {
+ int local = 0;
+ printf("&global=%p\n", &global);
+ printf("about to write to 'global'...\n"); // Set break point at this line.
+ for (int i = 0; i < 10; ++i)
+ modify(global);
+
+ printf("global=%d\n", global);
+ printf("cookie=%d\n", cookie);
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/condition/Makefile b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/condition/Makefile
new file mode 100644
index 000000000000..ee6b9cc62b40
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/condition/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/condition/TestWatchpointConditionCmd.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/condition/TestWatchpointConditionCmd.py
new file mode 100644
index 000000000000..355204a4ce1e
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/condition/TestWatchpointConditionCmd.py
@@ -0,0 +1,78 @@
+"""
+Test watchpoint modify command to set condition on a watchpoint.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class WatchpointConditionCmdTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Our simple source filename.
+ self.source = 'main.cpp'
+ # Find the line number to break inside main().
+ self.line = line_number(self.source, '// Set break point at this line.')
+ # And the watchpoint variable declaration line number.
+ self.decl = line_number(self.source, '// Watchpoint variable declaration.')
+ # Build dictionary to have unique executable names for each test method.
+ self.exe_name = self.testMethodName
+ self.d = {'CXX_SOURCES': self.source, 'EXE': self.exe_name}
+
+ @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ def test_watchpoint_cond(self):
+ """Test watchpoint condition."""
+ self.build(dictionary=self.d)
+ self.setTearDownCleanup(dictionary=self.d)
+
+ exe = os.path.join(os.getcwd(), self.exe_name)
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
+ lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # We should be stopped again due to the breakpoint.
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Now let's set a write-type watchpoint for 'global'.
+ # With a condition of 'global==5'.
+ self.expect("watchpoint set variable -w write global", WATCHPOINT_CREATED,
+ substrs = ['Watchpoint created', 'size = 4', 'type = w',
+ '%s:%d' % (self.source, self.decl)])
+
+ self.runCmd("watchpoint modify -c 'global==5'")
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should be 0 initially.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 0', 'global==5'])
+
+ self.runCmd("process continue")
+
+ # We should be stopped again due to the watchpoint (write type).
+ # The stop reason of the thread should be watchpoint.
+ self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT,
+ substrs = ['stop reason = watchpoint'])
+ self.expect("frame variable --show-globals global",
+ substrs = ['(int32_t)', 'global = 5'])
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should now be 2.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 5'])
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/condition/main.cpp b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/condition/main.cpp
new file mode 100644
index 000000000000..f4c3527f8af2
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/condition/main.cpp
@@ -0,0 +1,28 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+#include <stdint.h>
+
+int32_t global = 0; // Watchpoint variable declaration.
+
+static void modify(int32_t &var) {
+ ++var;
+}
+
+int main(int argc, char** argv) {
+ int local = 0;
+ printf("&global=%p\n", &global);
+ printf("about to write to 'global'...\n"); // Set break point at this line.
+ // When stopped, watch 'global',
+ // for the condition "global == 5".
+ for (int i = 0; i < 10; ++i)
+ modify(global);
+
+ printf("global=%d\n", global);
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/main.c b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/main.c
new file mode 100644
index 000000000000..b20eaf494fbf
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/main.c
@@ -0,0 +1,24 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+#include <stdint.h>
+
+int32_t global = 10; // Watchpoint variable declaration.
+
+int main(int argc, char** argv) {
+ int local = 0;
+ printf("&global=%p\n", &global);
+ printf("about to write to 'global'...\n"); // Set break point at this line.
+ // When stopped, watch 'global'.
+ global = 20;
+ local += argc;
+ ++local; // Set 2nd break point for disable_then_enable test case.
+ printf("local: %d\n", local);
+ printf("global=%d\n", global);
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_events/Makefile b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_events/Makefile
new file mode 100644
index 000000000000..b09a579159d4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_events/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_events/TestWatchpointEvents.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_events/TestWatchpointEvents.py
new file mode 100644
index 000000000000..e4d6e019c20e
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_events/TestWatchpointEvents.py
@@ -0,0 +1,89 @@
+"""Test that adding, deleting and modifying watchpoints sends the appropriate events."""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+class TestWatchpointEvents (TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line numbers that we will step to in main:
+ self.main_source = "main.c"
+
+ @add_test_categories(['pyapi'])
+ @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ def test_with_python_api(self):
+ """Test that adding, deleting and modifying watchpoints sends the appropriate events."""
+ self.build()
+
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ self.main_source_spec = lldb.SBFileSpec (self.main_source)
+
+ break_in_main = target.BreakpointCreateBySourceRegex ('// Put a breakpoint here.', self.main_source_spec)
+ self.assertTrue(break_in_main, VALID_BREAKPOINT)
+
+ # Now launch the process, and do not stop at entry point.
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # The stop reason of the thread should be breakpoint.
+ threads = lldbutil.get_threads_stopped_at_breakpoint (process, break_in_main)
+
+ if len(threads) != 1:
+ self.fail ("Failed to stop at first breakpoint in main.")
+
+ thread = threads[0]
+ frame = thread.GetFrameAtIndex(0)
+ local_var = frame.FindVariable ("local_var")
+ self.assertTrue (local_var.IsValid())
+
+ self.listener = lldb.SBListener("com.lldb.testsuite_listener")
+ self.target_bcast = target.GetBroadcaster()
+ self.target_bcast.AddListener (self.listener, lldb.SBTarget.eBroadcastBitWatchpointChanged)
+ self.listener.StartListeningForEvents (self.target_bcast, lldb.SBTarget.eBroadcastBitWatchpointChanged)
+
+ error = lldb.SBError()
+ local_watch = local_var.Watch(True, True, True, error)
+ if not error.Success():
+ self.fail ("Failed to make watchpoint for local_var: %s"%(error.GetCString()))
+
+ self.GetWatchpointEvent (lldb.eWatchpointEventTypeAdded)
+ # Now change some of the features of this watchpoint and make sure we get events:
+ local_watch.SetEnabled(False)
+ self.GetWatchpointEvent (lldb.eWatchpointEventTypeDisabled)
+
+ local_watch.SetIgnoreCount(10)
+ self.GetWatchpointEvent (lldb.eWatchpointEventTypeIgnoreChanged)
+
+ local_watch.SetCondition ("1 == 2")
+ self.GetWatchpointEvent (lldb.eWatchpointEventTypeConditionChanged)
+
+ def GetWatchpointEvent (self, event_type):
+ # We added a watchpoint so we should get a watchpoint added event.
+ event = lldb.SBEvent()
+ success = self.listener.WaitForEvent (1, event)
+ self.assertTrue(success == True, "Successfully got watchpoint event")
+ self.assertTrue (lldb.SBWatchpoint.EventIsWatchpointEvent(event), "Event is a watchpoint event.")
+ found_type = lldb.SBWatchpoint.GetWatchpointEventTypeFromEvent (event)
+ self.assertTrue (found_type == event_type, "Event is not correct type, expected: %d, found: %d"%(event_type, found_type))
+ # There shouldn't be another event waiting around:
+ found_event = self.listener.PeekAtNextEventForBroadcasterWithType (self.target_bcast, lldb.SBTarget.eBroadcastBitBreakpointChanged, event)
+ if found_event:
+ print("Found an event I didn't expect: ", event)
+
+ self.assertTrue (not found_event, "Only one event per change.")
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_events/main.c b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_events/main.c
new file mode 100644
index 000000000000..4b917536a161
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_events/main.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+int
+main (int argc, char **argv)
+{
+ int local_var = 10;
+ printf ("local_var is: %d.\n", local_var++); // Put a breakpoint here.
+ return local_var;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/Makefile b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/Makefile
new file mode 100644
index 000000000000..b09a579159d4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/TestValueOfVectorVariable.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/TestValueOfVectorVariable.py
new file mode 100644
index 000000000000..73752d2d18d5
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/TestValueOfVectorVariable.py
@@ -0,0 +1,47 @@
+"""
+Test displayed value of a vector variable while doing watchpoint operations
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class TestValueOfVectorVariableTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ def test_value_of_vector_variable_using_watchpoint_set(self):
+ """Test verify displayed value of vector variable."""
+ self.build(dictionary=self.d)
+ self.setTearDownCleanup(dictionary=self.d)
+ self.value_of_vector_variable_with_watchpoint_set()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Our simple source filename.
+ self.source = 'main.c'
+ self.exe_name = 'a.out'
+ self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
+
+ def value_of_vector_variable_with_watchpoint_set(self):
+ """Test verify displayed value of vector variable"""
+ exe = os.path.join(os.getcwd(), 'a.out')
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Set break to get a frame
+ self.runCmd("b main")
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # Value of a vector variable should be displayed correctly
+ self.expect("watchpoint set variable global_vector", WATCHPOINT_CREATED,
+ substrs = ['new value: (1, 2, 3, 4)'])
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/main.c b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/main.c
new file mode 100644
index 000000000000..98f8c477eb31
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/main.c
@@ -0,0 +1,16 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+typedef char v4i8 __attribute__ ((vector_size(4)));
+v4i8 global_vector = {1, 2, 3, 4};
+
+int
+main ()
+{
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/Makefile b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/Makefile
new file mode 100644
index 000000000000..8817fff55e8c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+ENABLE_THREADS := YES
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/TestWatchLocationWithWatchSet.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/TestWatchLocationWithWatchSet.py
new file mode 100644
index 000000000000..6bdac7024847
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/TestWatchLocationWithWatchSet.py
@@ -0,0 +1,89 @@
+"""
+Test lldb watchpoint that uses 'watchpoint set -w write -s size' to watch a pointed location with size.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class WatchLocationUsingWatchpointSetTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Our simple source filename.
+ self.source = 'main.cpp'
+ # Find the line number to break inside main().
+ self.line = line_number(self.source, '// Set break point at this line.')
+ # This is for verifying that watch location works.
+ self.violating_func = "do_bad_thing_with_location";
+ # Build dictionary to have unique executable names for each test method.
+
+ @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ def test_watchlocation_using_watchpoint_set(self):
+ """Test watching a location with 'watchpoint set expression -w write -s size' option."""
+ self.build()
+ self.setTearDownCleanup()
+
+ exe = os.path.join(os.getcwd(), 'a.out')
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
+ lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # We should be stopped again due to the breakpoint.
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Now let's set a write-type watchpoint pointed to by 'g_char_ptr' and
+ # with offset as 7.
+ # The main.cpp, by design, misbehaves by not following the agreed upon
+ # protocol of only accessing the allowable index range of [0, 6].
+ self.expect("watchpoint set expression -w write -s 1 -- g_char_ptr + 7", WATCHPOINT_CREATED,
+ substrs = ['Watchpoint created', 'size = 1', 'type = w'])
+ self.runCmd("expr unsigned val = g_char_ptr[7]; val")
+ self.expect(self.res.GetOutput().splitlines()[0], exe=False,
+ endstr = ' = 0')
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should be 0 initially.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 0'])
+
+ self.runCmd("process continue")
+
+ # We should be stopped again due to the watchpoint (write type), but
+ # only once. The stop reason of the thread should be watchpoint.
+ self.expect("thread list", STOPPED_DUE_TO_WATCHPOINT,
+ substrs = ['stopped',
+ 'stop reason = watchpoint',
+ self.violating_func])
+
+ # Switch to the thread stopped due to watchpoint and issue some commands.
+ self.switch_to_thread_with_stop_reason(lldb.eStopReasonWatchpoint)
+ self.runCmd("thread backtrace")
+ self.runCmd("expr unsigned val = g_char_ptr[7]; val")
+ self.expect(self.res.GetOutput().splitlines()[0], exe=False,
+ endstr = ' = 99')
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should now be the same as the number of threads that
+ # stopped on a watchpoint.
+ threads = lldbutil.get_stopped_threads(self.process(), lldb.eStopReasonWatchpoint)
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = %d' % len(threads)])
+
+ self.runCmd("thread backtrace all")
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py
new file mode 100644
index 000000000000..27c759e6fb64
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py
@@ -0,0 +1,67 @@
+"""
+Test error cases for the 'watchpoint set' command to make sure it errors out when necessary.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class WatchpointSetErrorTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Our simple source filename.
+ self.source = 'main.cpp'
+ # Find the line number to break inside main().
+ self.line = line_number(self.source, '// Set break point at this line.')
+ # Build dictionary to have unique executable names for each test method.
+
+ def test_error_cases_with_watchpoint_set(self):
+ """Test error cases with the 'watchpoint set' command."""
+ self.build()
+ self.setTearDownCleanup()
+
+ exe = os.path.join(os.getcwd(), 'a.out')
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
+ lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # We should be stopped again due to the breakpoint.
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Try some error conditions:
+
+ # 'watchpoint set' is now a multiword command.
+ self.expect("watchpoint set",
+ substrs = ['The following subcommands are supported:',
+ 'expression',
+ 'variable'])
+ self.runCmd("watchpoint set variable -w read_write", check=False)
+
+ # 'watchpoint set expression' with '-w' or '-s' specified now needs
+ # an option terminator and a raw expression after that.
+ self.expect("watchpoint set expression -w write --", error=True,
+ startstr = 'error: ')
+
+ # It's an error if the expression did not evaluate to an address.
+ self.expect("watchpoint set expression MyAggregateDataType", error=True,
+ startstr = 'error: expression did not evaluate to an address')
+
+ # Wrong size parameter is an error.
+ self.expect("watchpoint set variable -s -128", error=True,
+ substrs = ['invalid enumeration value'])
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/main.cpp b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/main.cpp
new file mode 100644
index 000000000000..796c0ef359df
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/main.cpp
@@ -0,0 +1,121 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <chrono>
+#include <condition_variable>
+#include <cstdio>
+#include <random>
+#include <thread>
+
+std::default_random_engine g_random_engine{std::random_device{}()};
+std::uniform_int_distribution<> g_distribution{0, 3000000};
+std::condition_variable g_condition_variable;
+std::mutex g_mutex;
+int g_count;
+
+char *g_char_ptr = nullptr;
+
+void
+barrier_wait()
+{
+ std::unique_lock<std::mutex> lock{g_mutex};
+ if (--g_count > 0)
+ g_condition_variable.wait(lock);
+ else
+ g_condition_variable.notify_all();
+}
+
+void
+do_bad_thing_with_location(unsigned index, char *char_ptr, char new_val)
+{
+ unsigned what = new_val;
+ printf("new value written to array(%p) and index(%u) = %u\n", char_ptr, index, what);
+ char_ptr[index] = new_val;
+}
+
+uint32_t
+access_pool (bool flag = false)
+{
+ static std::mutex g_access_mutex;
+ static unsigned idx = 0; // Well-behaving thread only writes into indexs from 0..6.
+ if (!flag)
+ g_access_mutex.lock();
+
+ // idx valid range is [0, 6].
+ if (idx > 6)
+ idx = 0;
+
+ if (flag)
+ {
+ // Write into a forbidden area.
+ do_bad_thing_with_location(7, g_char_ptr, 99);
+ }
+
+ unsigned index = idx++;
+
+ if (!flag)
+ g_access_mutex.unlock();
+ return g_char_ptr[index];
+}
+
+void
+thread_func (uint32_t thread_index)
+{
+ printf ("%s (thread index = %u) startng...\n", __FUNCTION__, thread_index);
+
+ barrier_wait();
+
+ uint32_t count = 0;
+ uint32_t val;
+ while (count++ < 15)
+ {
+ // random micro second sleep from zero to 3 seconds
+ int usec = g_distribution(g_random_engine);
+ printf ("%s (thread = %u) doing a usleep (%d)...\n", __FUNCTION__, thread_index, usec);
+ std::this_thread::sleep_for(std::chrono::microseconds{usec});
+
+ if (count < 7)
+ val = access_pool ();
+ else
+ val = access_pool (true);
+
+ printf ("%s (thread = %u) after usleep access_pool returns %d (count=%d)...\n", __FUNCTION__, thread_index, val, count);
+ }
+ printf ("%s (thread index = %u) exiting...\n", __FUNCTION__, thread_index);
+}
+
+
+int main (int argc, char const *argv[])
+{
+ g_count = 4;
+ std::thread threads[3];
+
+ g_char_ptr = new char[10]{};
+
+ // Create 3 threads
+ for (auto &thread : threads)
+ thread = std::thread{thread_func, std::distance(threads, &thread)};
+
+ struct {
+ int a;
+ int b;
+ int c;
+ } MyAggregateDataType;
+
+ printf ("Before turning all three threads loose...\n"); // Set break point at this line.
+ barrier_wait();
+
+ // Join all of our threads
+ for (auto &thread : threads)
+ thread.join();
+
+ delete[] g_char_ptr;
+
+ return 0;
+}