diff options
author | 2020-08-03 14:33:06 +0000 | |
---|---|---|
committer | 2020-08-03 14:33:06 +0000 | |
commit | 061da546b983eb767bad15e67af1174fb0bcf31c (patch) | |
tree | 83c78b820819d70aa40c36d90447978b300078c5 /gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api | |
parent | Import LLVM 10.0.0 release including clang, lld and lldb. (diff) | |
download | wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.tar.xz wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.zip |
Import LLVM 10.0.0 release including clang, lld and lldb.
ok hackroom
tested by plenty
Diffstat (limited to 'gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api')
174 files changed, 11109 insertions, 0 deletions
diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/.categories b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/.categories new file mode 100644 index 00000000000..db8069c3b9f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/.categories @@ -0,0 +1 @@ +pyapi diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/breakpoint/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/breakpoint/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/breakpoint/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/breakpoint/TestBreakpointAPI.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/breakpoint/TestBreakpointAPI.py new file mode 100644 index 00000000000..dd578469634 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/breakpoint/TestBreakpointAPI.py @@ -0,0 +1,71 @@ +""" +Test SBBreakpoint APIs. +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class BreakpointAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + @add_test_categories(['pyapi']) + def test_breakpoint_is_valid(self): + """Make sure that if an SBBreakpoint gets deleted its IsValid returns false.""" + self.build() + exe = self.getBuildArtifact("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 'AFunction'. + breakpoint = target.BreakpointCreateByName('AFunction', 'a.out') + #print("breakpoint:", breakpoint) + self.assertTrue(breakpoint and + breakpoint.GetNumLocations() == 1, + VALID_BREAKPOINT) + + # Now delete it: + did_delete = target.BreakpointDelete(breakpoint.GetID()) + self.assertTrue( + did_delete, + "Did delete the breakpoint we just created.") + + # Make sure we can't find it: + del_bkpt = target.FindBreakpointByID(breakpoint.GetID()) + self.assertTrue(not del_bkpt, "We did delete the breakpoint.") + + # Finally make sure the original breakpoint is no longer valid. + self.assertTrue( + not breakpoint, + "Breakpoint we deleted is no longer valid.") + + @add_test_categories(['pyapi']) + def test_target_delete(self): + """Make sure that if an SBTarget gets deleted the associated + Breakpoint's IsValid returns false.""" + + self.build() + exe = self.getBuildArtifact("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 'AFunction'. + breakpoint = target.BreakpointCreateByName('AFunction', 'a.out') + #print("breakpoint:", breakpoint) + self.assertTrue(breakpoint and + breakpoint.GetNumLocations() == 1, + VALID_BREAKPOINT) + location = breakpoint.GetLocationAtIndex(0) + self.assertTrue(location.IsValid()) + + self.assertTrue(self.dbg.DeleteTarget(target)) + self.assertFalse(breakpoint.IsValid()) + self.assertFalse(location.IsValid()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/breakpoint/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/breakpoint/main.c new file mode 100644 index 00000000000..2677594e622 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/breakpoint/main.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +void +AFunction() +{ + printf ("I am a function.\n"); +} + +int +main () +{ + AFunction(); + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/class_members/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/class_members/Makefile new file mode 100644 index 00000000000..6f34ff7dd84 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/class_members/Makefile @@ -0,0 +1,3 @@ +OBJCXX_SOURCES := main.mm + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/class_members/TestSBTypeClassMembers.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/class_members/TestSBTypeClassMembers.py new file mode 100644 index 00000000000..884043ac2ec --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/class_members/TestSBTypeClassMembers.py @@ -0,0 +1,117 @@ +""" +Test SBType APIs to fetch member function types. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class SBTypeMemberFunctionsTest(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # We'll use the test method name as the exe_name. + self.exe_name = self.testMethodName + # Find the line number to break at. + self.source = 'main.mm' + self.line = line_number(self.source, '// set breakpoint here') + + @skipUnlessDarwin + @add_test_categories(['pyapi']) + def test(self): + """Test SBType APIs to fetch member function types.""" + d = {'EXE': self.exe_name} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + exe = self.getBuildArtifact(self.exe_name) + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Create the breakpoint inside function 'main'. + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + 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) + + # Get Frame #0. + self.assertTrue(process.GetState() == lldb.eStateStopped) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint condition") + frame0 = thread.GetFrameAtIndex(0) + + variable = frame0.FindVariable("d") + Derived = variable.GetType() + Base = Derived.GetDirectBaseClassAtIndex(0).GetType() + + self.assertEquals(2, + Derived.GetNumberOfMemberFunctions(), + "Derived declares two methods") + self.assertEquals("int", Derived.GetMemberFunctionAtIndex(0).GetType( + ).GetFunctionReturnType().GetName(), + "Derived::dImpl returns int") + + self.assertEquals(4, + Base.GetNumberOfMemberFunctions(), + "Base declares three methods") + self.assertEquals(3, Base.GetMemberFunctionAtIndex(3).GetType( + ).GetFunctionArgumentTypes().GetSize(), + "Base::sfunc takes three arguments") + self.assertEquals("sfunc", Base.GetMemberFunctionAtIndex( + 3).GetName(), "Base::sfunc not found") + self.assertEquals(lldb.eMemberFunctionKindStaticMethod, + Base.GetMemberFunctionAtIndex(3).GetKind(), + "Base::sfunc is a static") + self.assertEquals(0, Base.GetMemberFunctionAtIndex(2).GetType( + ).GetFunctionArgumentTypes().GetSize(), + "Base::dat takes no arguments") + self.assertEquals("char", + Base.GetMemberFunctionAtIndex(1).GetType().GetFunctionArgumentTypes( + ).GetTypeAtIndex(1).GetName(), + "Base::bar takes a second 'char' argument") + self.assertEquals("bar", + Base.GetMemberFunctionAtIndex(1).GetName(), "Base::bar not found") + + variable = frame0.FindVariable("thingy") + Thingy = variable.GetType() + + self.assertEquals( + 2, Thingy.GetNumberOfMemberFunctions(), + "Thingy declares two methods") + + self.assertEquals("id", Thingy.GetMemberFunctionAtIndex( + 0).GetReturnType().GetName(), "Thingy::init returns an id") + self.assertEquals(2, + Thingy.GetMemberFunctionAtIndex(1).GetNumberOfArguments(), + "Thingy::foo takes two arguments") + self.assertEquals("int", + Thingy.GetMemberFunctionAtIndex(1).GetArgumentTypeAtIndex( + 0).GetName(), "Thingy::foo takes an int") + + self.assertEquals("Derived::dImpl()", Derived.GetMemberFunctionAtIndex(0).GetDemangledName()) + self.assertEquals("Derived::baz(float)", Derived.GetMemberFunctionAtIndex(1).GetDemangledName()) + self.assertEquals("Base::foo(int, int)", Base.GetMemberFunctionAtIndex(0).GetDemangledName()) + self.assertEquals("Base::bar(int, char)", Base.GetMemberFunctionAtIndex(1).GetDemangledName()) + self.assertEquals("Base::dat()", Base.GetMemberFunctionAtIndex(2).GetDemangledName()) + self.assertEquals("Base::sfunc(char, int, float)", Base.GetMemberFunctionAtIndex(3).GetDemangledName()) + + self.assertEquals("_ZN7Derived5dImplEv", Derived.GetMemberFunctionAtIndex(0).GetMangledName()) + self.assertEquals("_ZN7Derived3bazEf", Derived.GetMemberFunctionAtIndex(1).GetMangledName()) + self.assertEquals("_ZN4Base3fooEii", Base.GetMemberFunctionAtIndex(0).GetMangledName()) + self.assertEquals("_ZN4Base3barEic", Base.GetMemberFunctionAtIndex(1).GetMangledName()) + self.assertEquals("_ZN4Base3datEv", Base.GetMemberFunctionAtIndex(2).GetMangledName()) + self.assertEquals("_ZN4Base5sfuncEcif", Base.GetMemberFunctionAtIndex(3).GetMangledName()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/class_members/main.mm b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/class_members/main.mm new file mode 100644 index 00000000000..48a2c59ad4a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/class_members/main.mm @@ -0,0 +1,46 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#import <Foundation/Foundation.h> + +class Base { +public: + int foo(int x, int y) { return 1; } + char bar(int x, char y) { return 2; } + void dat() {} + static int sfunc(char, int, float) { return 3; } +}; + +class Derived: public Base { +protected: + int dImpl() { return 1; } +public: + float baz(float b) { return b + 1.0; } +}; + +@interface Thingy: NSObject { +} +- (id)init; +- (id)fooWithBar: (int)bar andBaz:(id)baz; +@end + +@implementation Thingy { +} +- (id)init { + return (self = [super init]); +} +- (id)fooWithBar: (int)bar andBaz:(id)baz { + return nil; +} +@end + +int main() { + Derived d; + Thingy *thingy = [[Thingy alloc] init]; + return 0; // set breakpoint here +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/debugger/TestDebuggerAPI.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/debugger/TestDebuggerAPI.py new file mode 100644 index 00000000000..32202acbe07 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/debugger/TestDebuggerAPI.py @@ -0,0 +1,45 @@ +""" +Test Debugger APIs. +""" + +import lldb + +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class DebuggerAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + @add_test_categories(['pyapi']) + def test_debugger_api_boundary_condition(self): + """Exercise SBDebugger APIs with boundary conditions.""" + self.dbg.HandleCommand(None) + self.dbg.SetDefaultArchitecture(None) + self.dbg.GetScriptingLanguage(None) + self.dbg.CreateTarget(None) + self.dbg.CreateTarget(None, None, None, True, lldb.SBError()) + self.dbg.CreateTargetWithFileAndTargetTriple(None, None) + self.dbg.CreateTargetWithFileAndArch(None, None) + self.dbg.FindTargetWithFileAndArch(None, None) + self.dbg.SetInternalVariable(None, None, None) + self.dbg.GetInternalVariableValue(None, None) + # FIXME (filcab): We must first allow for the swig bindings to know if + # a Python callback is set. (Check python-typemaps.swig) + # self.dbg.SetLoggingCallback(None) + self.dbg.SetPrompt(None) + self.dbg.SetCurrentPlatform(None) + self.dbg.SetCurrentPlatformSDKRoot(None) + + fresh_dbg = lldb.SBDebugger() + self.assertEquals(len(fresh_dbg), 0) + + @add_test_categories(['pyapi']) + def test_debugger_delete_invalid_target(self): + """SBDebugger.DeleteTarget() should not crash LLDB given and invalid target.""" + target = lldb.SBTarget() + self.assertFalse(target.IsValid()) + self.dbg.DeleteTarget(target) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py new file mode 100644 index 00000000000..e00206587ed --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py @@ -0,0 +1,398 @@ +""" +Test lldb Python API object's default constructor and make sure it is invalid +after initial construction. + +There are also some cases of boundary condition testings sprinkled throughout +the tests where None is passed to SB API which expects (const char *) in the +C++ API counterpart. Passing None should not crash lldb! + +There are three exceptions to the above general rules, though; API objects +SBCommadnReturnObject, SBStream, and SBSymbolContextList, are all valid objects +after default construction. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class APIDefaultConstructorTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + @add_test_categories(['pyapi']) + def test_SBAddress(self): + obj = lldb.SBAddress() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_address + sb_address.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBBlock(self): + obj = lldb.SBBlock() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_block + sb_block.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBBreakpoint(self): + obj = lldb.SBBreakpoint() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_breakpoint + sb_breakpoint.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBBreakpointLocation(self): + obj = lldb.SBBreakpointLocation() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_breakpointlocation + sb_breakpointlocation.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBBreakpointName(self): + obj = lldb.SBBreakpointName() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_breakpointname + sb_breakpointname.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBBroadcaster(self): + obj = lldb.SBBroadcaster() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_broadcaster + sb_broadcaster.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBCommandReturnObject(self): + """SBCommandReturnObject object is valid after default construction.""" + obj = lldb.SBCommandReturnObject() + if self.TraceOn(): + print(obj) + self.assertTrue(obj) + + @add_test_categories(['pyapi']) + def test_SBCommunication(self): + obj = lldb.SBCommunication() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_communication + sb_communication.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBCompileUnit(self): + obj = lldb.SBCompileUnit() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_compileunit + sb_compileunit.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBDebugger(self): + obj = lldb.SBDebugger() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_debugger + sb_debugger.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + # darwin: This test passes with swig 3.0.2, fails w/3.0.5 other tests fail + # with 2.0.12 http://llvm.org/pr23488 + def test_SBError(self): + obj = lldb.SBError() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_error + sb_error.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBEvent(self): + obj = lldb.SBEvent() + # This is just to test that typemap, as defined in lldb.swig, works. + obj2 = lldb.SBEvent(0, "abc") + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_event + sb_event.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBFileSpec(self): + obj = lldb.SBFileSpec() + # This is just to test that FileSpec(None) does not crash. + obj2 = lldb.SBFileSpec(None, True) + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_filespec + sb_filespec.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBFrame(self): + obj = lldb.SBFrame() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_frame + sb_frame.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBFunction(self): + obj = lldb.SBFunction() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_function + sb_function.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBFile(self): + sbf = lldb.SBFile() + self.assertFalse(sbf.IsValid()) + self.assertFalse(bool(sbf)) + e, n = sbf.Write(b'foo') + self.assertTrue(e.Fail()) + self.assertEqual(n, 0) + buffer = bytearray(100) + e, n = sbf.Read(buffer) + self.assertEqual(n, 0) + self.assertTrue(e.Fail()) + + @add_test_categories(['pyapi']) + def test_SBInstruction(self): + obj = lldb.SBInstruction() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_instruction + sb_instruction.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBInstructionList(self): + obj = lldb.SBInstructionList() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_instructionlist + sb_instructionlist.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBLineEntry(self): + obj = lldb.SBLineEntry() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_lineentry + sb_lineentry.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBListener(self): + obj = lldb.SBListener() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_listener + sb_listener.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + # Py3 asserts due to a bug in SWIG. Trying to upstream a patch to fix + # this in 3.0.8 + @skipIf(py_version=['>=', (3, 0)], swig_version=['<', (3, 0, 8)]) + def test_SBModule(self): + obj = lldb.SBModule() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_module + sb_module.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBProcess(self): + obj = lldb.SBProcess() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_process + sb_process.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBProcessInfo(self): + obj = lldb.SBProcessInfo() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_process_info + sb_process_info.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBSection(self): + obj = lldb.SBSection() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_section + sb_section.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBStream(self): + """SBStream object is valid after default construction.""" + obj = lldb.SBStream() + if self.TraceOn(): + print(obj) + self.assertTrue(obj) + + @add_test_categories(['pyapi']) + def test_SBStringList(self): + obj = lldb.SBStringList() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_stringlist + sb_stringlist.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBSymbol(self): + obj = lldb.SBSymbol() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_symbol + sb_symbol.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBSymbolContext(self): + obj = lldb.SBSymbolContext() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_symbolcontext + sb_symbolcontext.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBSymbolContextList(self): + """SBSymbolContextList object is valid after default construction.""" + obj = lldb.SBSymbolContextList() + if self.TraceOn(): + print(obj) + self.assertTrue(obj) + + @add_test_categories(['pyapi']) + def test_SBTarget(self): + obj = lldb.SBTarget() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_target + sb_target.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBThread(self): + obj = lldb.SBThread() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_thread + sb_thread.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBType(self): + try: + obj = lldb.SBType() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # If we reach here, the test fails. + self.fail("lldb.SBType() should fail, not succeed!") + except: + # Exception is expected. + return + + # Unreachable code because lldb.SBType() should fail. + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_type + sb_type.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBTypeList(self): + """SBTypeList object is valid after default construction.""" + obj = lldb.SBTypeList() + if self.TraceOn(): + print(obj) + self.assertTrue(obj) + + @add_test_categories(['pyapi']) + def test_SBValue(self): + obj = lldb.SBValue() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_value + sb_value.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBValueList(self): + obj = lldb.SBValueList() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_valuelist + sb_valuelist.fuzz_obj(obj) + + @add_test_categories(['pyapi']) + def test_SBWatchpoint(self): + obj = lldb.SBWatchpoint() + if self.TraceOn(): + print(obj) + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_watchpoint + sb_watchpoint.fuzz_obj(obj) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_address.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_address.py new file mode 100644 index 00000000000..8f9665d3a73 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_address.py @@ -0,0 +1,23 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + + +def fuzz_obj(obj): + obj.GetFileAddress() + obj.GetLoadAddress(lldb.SBTarget()) + obj.SetLoadAddress(0xffff, lldb.SBTarget()) + obj.OffsetAddress(sys.maxsize) + obj.GetDescription(lldb.SBStream()) + obj.GetSection() + obj.GetSymbolContext(lldb.eSymbolContextEverything) + obj.GetModule() + obj.GetCompileUnit() + obj.GetFunction() + obj.GetBlock() + obj.GetSymbol() + obj.GetLineEntry() + obj.Clear() diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_block.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_block.py new file mode 100644 index 00000000000..299ca08910c --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_block.py @@ -0,0 +1,17 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.IsInlined() + obj.GetInlinedName() + obj.GetInlinedCallSiteFile() + obj.GetInlinedCallSiteLine() + obj.GetInlinedCallSiteColumn() + obj.GetParent() + obj.GetSibling() + obj.GetFirstChild() + obj.GetDescription(lldb.SBStream()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_breakpoint.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_breakpoint.py new file mode 100644 index 00000000000..3bdf5879d30 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_breakpoint.py @@ -0,0 +1,37 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + + +def fuzz_obj(obj): + obj.GetID() + obj.ClearAllBreakpointSites() + obj.FindLocationByAddress(sys.maxsize) + obj.FindLocationIDByAddress(sys.maxsize) + obj.FindLocationByID(0) + obj.GetLocationAtIndex(0) + obj.SetEnabled(True) + obj.IsEnabled() + obj.GetHitCount() + obj.SetIgnoreCount(1) + obj.GetIgnoreCount() + obj.SetCondition("i >= 10") + obj.GetCondition() + obj.SetThreadID(0) + obj.GetThreadID() + obj.SetThreadIndex(0) + obj.GetThreadIndex() + obj.SetThreadName("worker thread") + obj.GetThreadName() + obj.SetQueueName("my queue") + obj.GetQueueName() + obj.SetScriptCallbackFunction(None) + obj.SetScriptCallbackBody(None) + obj.GetNumResolvedLocations() + obj.GetNumLocations() + obj.GetDescription(lldb.SBStream()) + for bp_loc in obj: + s = str(bp_loc) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_breakpointlocation.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_breakpointlocation.py new file mode 100644 index 00000000000..5ac1c065efe --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_breakpointlocation.py @@ -0,0 +1,28 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.GetAddress() + obj.GetLoadAddress() + obj.SetEnabled(True) + obj.IsEnabled() + obj.SetCondition("i >= 10") + obj.GetCondition() + obj.SetThreadID(0) + obj.GetThreadID() + obj.SetThreadIndex(0) + obj.GetThreadIndex() + obj.SetThreadName("worker thread") + obj.GetThreadName() + obj.SetQueueName("my queue") + obj.GetQueueName() + obj.IsResolved() + obj.GetDescription(lldb.SBStream(), lldb.eDescriptionLevelVerbose) + breakpoint = obj.GetBreakpoint() + # Do fuzz testing on the breakpoint obj, it should not crash lldb. + import sb_breakpoint + sb_breakpoint.fuzz_obj(breakpoint) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_breakpointname.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_breakpointname.py new file mode 100644 index 00000000000..b32ed0d11aa --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_breakpointname.py @@ -0,0 +1,41 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.IsValid() + obj.GetName() + obj.SetEnabled(True) + obj.IsEnabled() + obj.SetOneShot(True) + obj.IsOneShot() + obj.SetIgnoreCount(1) + obj.GetIgnoreCount() + obj.SetCondition("1 == 2") + obj.GetCondition() + obj.SetAutoContinue(False) + obj.GetAutoContinue() + obj.SetThreadID(0x1234) + obj.GetThreadID() + obj.SetThreadIndex(10) + obj.GetThreadIndex() + obj.SetThreadName("AThread") + obj.GetThreadName() + obj.SetQueueName("AQueue") + obj.GetQueueName() + obj.SetScriptCallbackFunction("AFunction") + commands = lldb.SBStringList() + obj.SetCommandLineCommands(commands) + obj.GetCommandLineCommands(commands) + obj.SetScriptCallbackBody("Insert Python Code here") + obj.GetAllowList() + obj.SetAllowList(False) + obj.GetAllowDelete() + obj.SetAllowDelete(False) + obj.GetAllowDisable() + obj.SetAllowDisable(False) + stream = lldb.SBStream() + obj.GetDescription(stream) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_broadcaster.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_broadcaster.py new file mode 100644 index 00000000000..59491a762db --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_broadcaster.py @@ -0,0 +1,20 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.BroadcastEventByType(lldb.eBreakpointEventTypeInvalidType, True) + obj.BroadcastEvent(lldb.SBEvent(), False) + listener = lldb.SBListener("fuzz_testing") + obj.AddInitialEventsToListener(listener, 0xffffffff) + obj.AddInitialEventsToListener(listener, 0) + obj.AddListener(listener, 0xffffffff) + obj.AddListener(listener, 0) + obj.GetName() + obj.EventTypeHasListeners(0) + obj.RemoveListener(listener, 0xffffffff) + obj.RemoveListener(listener, 0) + obj.Clear() diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_communication.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_communication.py new file mode 100644 index 00000000000..1f5aefbc0d5 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_communication.py @@ -0,0 +1,28 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + broadcaster = obj.GetBroadcaster() + # Do fuzz testing on the broadcaster obj, it should not crash lldb. + import sb_broadcaster + sb_broadcaster.fuzz_obj(broadcaster) + obj.AdoptFileDesriptor(0, False) + obj.AdoptFileDesriptor(1, False) + obj.AdoptFileDesriptor(2, False) + obj.Connect("file:/tmp/myfile") + obj.Connect(None) + obj.Disconnect() + obj.IsConnected() + obj.GetCloseOnEOF() + obj.SetCloseOnEOF(True) + obj.SetCloseOnEOF(False) + #obj.Write(None, sys.maxint, None) + #obj.Read(None, sys.maxint, 0xffffffff, None) + obj.ReadThreadStart() + obj.ReadThreadStop() + obj.ReadThreadIsRunning() + obj.SetReadThreadBytesReceivedCallback(None, None) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_compileunit.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_compileunit.py new file mode 100644 index 00000000000..4caef33a75f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_compileunit.py @@ -0,0 +1,16 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.GetFileSpec() + obj.GetNumLineEntries() + obj.GetLineEntryAtIndex(0xffffffff) + obj.FindLineEntryIndex(0, 0xffffffff, None) + obj.GetDescription(lldb.SBStream()) + len(obj) + for line_entry in obj: + s = str(line_entry) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_debugger.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_debugger.py new file mode 100644 index 00000000000..e6267c8475e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_debugger.py @@ -0,0 +1,63 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.SetAsync(True) + obj.SetAsync(False) + obj.GetAsync() + obj.SkipLLDBInitFiles(True) + obj.SetInputFileHandle(None, True) + obj.SetOutputFileHandle(None, True) + obj.SetErrorFileHandle(None, True) + obj.GetInputFileHandle() + obj.GetOutputFileHandle() + obj.GetErrorFileHandle() + obj.GetCommandInterpreter() + obj.HandleCommand("nothing here") + listener = obj.GetListener() + try: + obj.HandleProcessEvent(lldb.SBProcess(), lldb.SBEvent(), None, None) + except Exception: + pass + obj.CreateTargetWithFileAndTargetTriple("a.out", "A-B-C") + obj.CreateTargetWithFileAndArch("b.out", "arm") + obj.CreateTarget("c.out") + obj.DeleteTarget(lldb.SBTarget()) + obj.GetTargetAtIndex(0xffffffff) + obj.FindTargetWithProcessID(0) + obj.FindTargetWithFileAndArch("a.out", "arm") + obj.GetNumTargets() + obj.GetSelectedTarget() + obj.GetNumPlatforms() + obj.GetPlatformAtIndex(0xffffffff) + obj.GetNumAvailablePlatforms() + obj.GetAvailablePlatformInfoAtIndex(0xffffffff) + obj.GetSourceManager() + obj.SetSelectedTarget(lldb.SBTarget()) + obj.SetCurrentPlatformSDKRoot("tmp/sdk-root") + try: + obj.DispatchInput(None) + except Exception: + pass + obj.DispatchInputInterrupt() + obj.DispatchInputEndOfFile() + obj.GetInstanceName() + obj.GetDescription(lldb.SBStream()) + obj.GetTerminalWidth() + obj.SetTerminalWidth(0xffffffff) + obj.GetID() + obj.GetPrompt() + obj.SetPrompt("Hi, Mom!") + obj.GetScriptLanguage() + obj.SetScriptLanguage(lldb.eScriptLanguageNone) + obj.SetScriptLanguage(lldb.eScriptLanguagePython) + obj.GetCloseInputOnEOF() + obj.SetCloseInputOnEOF(True) + obj.SetCloseInputOnEOF(False) + obj.Clear() + for target in obj: + s = str(target) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_error.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_error.py new file mode 100644 index 00000000000..7d14c3e5844 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_error.py @@ -0,0 +1,25 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.GetCString() + obj.Fail() + obj.Success() + obj.GetError() + obj.GetType() + obj.SetError(5, lldb.eErrorTypeGeneric) + obj.SetErrorToErrno() + obj.SetErrorToGenericError() + obj.SetErrorString("xyz") + obj.SetErrorString(None) + obj.SetErrorStringWithFormat("%s!", "error") + obj.SetErrorStringWithFormat(None) + obj.SetErrorStringWithFormat("error") + obj.SetErrorStringWithFormat("%s %s", "warning", "danger") + obj.SetErrorStringWithFormat("%s %s %s", "danger", "will", "robinson") + obj.GetDescription(lldb.SBStream()) + obj.Clear() diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_event.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_event.py new file mode 100644 index 00000000000..aaf71d03051 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_event.py @@ -0,0 +1,17 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.GetDataFlavor() + obj.GetType() + broadcaster = obj.GetBroadcaster() + # Do fuzz testing on the broadcaster obj, it should not crash lldb. + import sb_broadcaster + sb_broadcaster.fuzz_obj(broadcaster) + obj.BroadcasterMatchesRef(broadcaster) + obj.GetDescription(lldb.SBStream()) + obj.Clear() diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_filespec.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_filespec.py new file mode 100644 index 00000000000..4ab5c49c37e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_filespec.py @@ -0,0 +1,14 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.Exists() + obj.ResolveExecutableLocation() + obj.GetFilename() + obj.GetDirectory() + obj.GetPath(None, 0) + obj.GetDescription(lldb.SBStream()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_frame.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_frame.py new file mode 100644 index 00000000000..b81f1af7b0e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_frame.py @@ -0,0 +1,40 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.GetFrameID() + obj.GetPC() + obj.SetPC(0xffffffff) + obj.GetSP() + obj.GetFP() + obj.GetPCAddress() + obj.GetSymbolContext(0) + obj.GetModule() + obj.GetCompileUnit() + obj.GetFunction() + obj.GetSymbol() + obj.GetBlock() + obj.GetFunctionName() + obj.IsInlined() + obj.EvaluateExpression("x + y") + obj.EvaluateExpression("x + y", lldb.eDynamicCanRunTarget) + obj.GetFrameBlock() + obj.GetLineEntry() + obj.GetThread() + obj.Disassemble() + obj.GetVariables(True, True, True, True) + obj.GetVariables(True, True, True, False, lldb.eDynamicCanRunTarget) + obj.GetRegisters() + obj.FindVariable("my_var") + obj.FindVariable("my_var", lldb.eDynamicCanRunTarget) + obj.FindValue("your_var", lldb.eValueTypeVariableGlobal) + obj.FindValue( + "your_var", + lldb.eValueTypeVariableStatic, + lldb.eDynamicCanRunTarget) + obj.GetDescription(lldb.SBStream()) + obj.Clear() diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_function.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_function.py new file mode 100644 index 00000000000..764fb373b62 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_function.py @@ -0,0 +1,19 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.GetName() + obj.GetMangledName() + obj.GetInstructions(lldb.SBTarget()) + sa = obj.GetStartAddress() + ea = obj.GetEndAddress() + # Do fuzz testing on the address obj, it should not crash lldb. + import sb_address + sb_address.fuzz_obj(sa) + sb_address.fuzz_obj(ea) + obj.GetPrologueByteSize + obj.GetDescription(lldb.SBStream()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_instruction.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_instruction.py new file mode 100644 index 00000000000..fbfb2313688 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_instruction.py @@ -0,0 +1,19 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.GetAddress() + obj.GetByteSize() + obj.DoesBranch() + try: + obj.Print(None) + except Exception: + pass + obj.GetDescription(lldb.SBStream()) + obj.EmulateWithFrame(lldb.SBFrame(), 0) + obj.DumpEmulation("armv7") + obj.TestEmulation(lldb.SBStream(), "my-file") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_instructionlist.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_instructionlist.py new file mode 100644 index 00000000000..9e7ebf927f4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_instructionlist.py @@ -0,0 +1,20 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.GetSize() + obj.GetInstructionAtIndex(0xffffffff) + obj.AppendInstruction(lldb.SBInstruction()) + try: + obj.Print(None) + except Exception: + pass + obj.GetDescription(lldb.SBStream()) + obj.DumpEmulationForAllInstructions("armv7") + obj.Clear() + for inst in obj: + s = str(inst) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_lineentry.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_lineentry.py new file mode 100644 index 00000000000..53761a0c1fa --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_lineentry.py @@ -0,0 +1,14 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.GetStartAddress() + obj.GetEndAddress() + obj.GetFileSpec() + obj.GetLine() + obj.GetColumn() + obj.GetDescription(lldb.SBStream()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_listener.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_listener.py new file mode 100644 index 00000000000..b40cfd4d1c2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_listener.py @@ -0,0 +1,23 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.AddEvent(lldb.SBEvent()) + obj.StartListeningForEvents(lldb.SBBroadcaster(), 0xffffffff) + obj.StopListeningForEvents(lldb.SBBroadcaster(), 0xffffffff) + event = lldb.SBEvent() + broadcaster = lldb.SBBroadcaster() + obj.WaitForEvent(5, event) + obj.WaitForEventForBroadcaster(5, broadcaster, event) + obj.WaitForEventForBroadcasterWithType(5, broadcaster, 0xffffffff, event) + obj.PeekAtNextEvent(event) + obj.PeekAtNextEventForBroadcaster(broadcaster, event) + obj.PeekAtNextEventForBroadcasterWithType(broadcaster, 0xffffffff, event) + obj.GetNextEvent(event) + obj.GetNextEventForBroadcaster(broadcaster, event) + obj.GetNextEventForBroadcasterWithType(broadcaster, 0xffffffff, event) + obj.HandleBroadcastEvent(event) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_module.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_module.py new file mode 100644 index 00000000000..175550a5a0f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_module.py @@ -0,0 +1,30 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + + +def fuzz_obj(obj): + obj.GetFileSpec() + obj.GetPlatformFileSpec() + obj.SetPlatformFileSpec(lldb.SBFileSpec()) + obj.GetUUIDString() + obj.ResolveFileAddress(sys.maxsize) + obj.ResolveSymbolContextForAddress(lldb.SBAddress(), 0) + obj.GetDescription(lldb.SBStream()) + obj.GetNumSymbols() + obj.GetSymbolAtIndex(sys.maxsize) + sc_list = obj.FindFunctions("my_func") + sc_list = obj.FindFunctions("my_func", lldb.eFunctionNameTypeAny) + obj.FindGlobalVariables(lldb.SBTarget(), "my_global_var", 1) + for section in obj.section_iter(): + s = str(section) + for symbol in obj.symbol_in_section_iter(lldb.SBSection()): + s = str(symbol) + for symbol in obj: + s = str(symbol) + obj.GetAddressByteSize() + obj.GetByteOrder() + obj.GetTriple() diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_process.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_process.py new file mode 100644 index 00000000000..93e43d4433f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_process.py @@ -0,0 +1,53 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.GetTarget() + obj.GetByteOrder() + obj.PutSTDIN("my data") + obj.GetSTDOUT(6) + obj.GetSTDERR(6) + event = lldb.SBEvent() + try: + obj.ReportEventState(event, None) + except Exception: + pass + obj.AppendEventStateReport(event, lldb.SBCommandReturnObject()) + error = lldb.SBError() + obj.RemoteAttachToProcessWithID(123, error) + obj.RemoteLaunch(None, None, None, None, None, None, 0, False, error) + obj.GetNumThreads() + obj.GetThreadAtIndex(0) + obj.GetThreadByID(0) + obj.GetSelectedThread() + obj.SetSelectedThread(lldb.SBThread()) + obj.SetSelectedThreadByID(0) + obj.GetState() + obj.GetExitStatus() + obj.GetExitDescription() + obj.GetProcessID() + obj.GetAddressByteSize() + obj.Destroy() + obj.Continue() + obj.Stop() + obj.Kill() + obj.Detach() + obj.Signal(7) + obj.ReadMemory(0x0000ffff, 10, error) + obj.WriteMemory(0x0000ffff, "hi data", error) + obj.ReadCStringFromMemory(0x0, 128, error) + obj.ReadUnsignedFromMemory(0xff, 4, error) + obj.ReadPointerFromMemory(0xff, error) + obj.GetBroadcaster() + obj.GetDescription(lldb.SBStream()) + obj.LoadImage(lldb.SBFileSpec(), error) + obj.UnloadImage(0) + obj.Clear() + obj.GetNumSupportedHardwareWatchpoints(error) + for thread in obj: + s = str(thread) + len(obj) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_process_info.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_process_info.py new file mode 100644 index 00000000000..0c4562f9be9 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_process_info.py @@ -0,0 +1,21 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.IsValid() + obj.GetName() + obj.GetExecutableFile() + obj.GetProcessID() + obj.GetUserID() + obj.GetGroupID() + obj.UserIDIsValid() + obj.GroupIDIsValid() + obj.GetEffectiveUserID() + obj.GetEffectiveGroupID() + obj.EffectiveUserIDIsValid() + obj.EffectiveGroupIDIsValid() + obj.GetParentProcessID() diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_section.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_section.py new file mode 100644 index 00000000000..d6118186b4b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_section.py @@ -0,0 +1,23 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.IsValid() + obj.GetName() + obj.FindSubSection("hello_section_name") + obj.GetNumSubSections() + obj.GetSubSectionAtIndex(600) + obj.GetFileAddress() + obj.GetByteSize() + obj.GetFileOffset() + obj.GetFileByteSize() + obj.GetSectionData(1000, 100) + obj.GetSectionType() + obj.GetDescription(lldb.SBStream()) + for subsec in obj: + s = str(subsec) + len(obj) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_stringlist.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_stringlist.py new file mode 100644 index 00000000000..015de7aa7ac --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_stringlist.py @@ -0,0 +1,17 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.AppendString("another string") + obj.AppendString(None) + obj.AppendList(None, 0) + obj.AppendList(lldb.SBStringList()) + obj.GetSize() + obj.GetStringAtIndex(0xffffffff) + obj.Clear() + for n in obj: + s = str(n) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_symbol.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_symbol.py new file mode 100644 index 00000000000..ce942a9daa4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_symbol.py @@ -0,0 +1,16 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.GetName() + obj.GetMangledName() + obj.GetInstructions(lldb.SBTarget()) + obj.GetStartAddress() + obj.GetEndAddress() + obj.GetPrologueByteSize() + obj.GetType() + obj.GetDescription(lldb.SBStream()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_symbolcontext.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_symbolcontext.py new file mode 100644 index 00000000000..e46e4714be0 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_symbolcontext.py @@ -0,0 +1,15 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.GetModule() + obj.GetCompileUnit() + obj.GetFunction() + obj.GetBlock() + obj.GetLineEntry() + obj.GetSymbol() + obj.GetDescription(lldb.SBStream()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_target.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_target.py new file mode 100644 index 00000000000..3b521dcf6dd --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_target.py @@ -0,0 +1,65 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.GetProcess() + listener = lldb.SBListener() + error = lldb.SBError() + obj.Launch(listener, None, None, None, None, None, None, 0, True, error) + obj.LaunchSimple(None, None, None) + obj.AttachToProcessWithID(listener, 123, error) + obj.AttachToProcessWithName(listener, 'lldb', False, error) + obj.ConnectRemote(listener, "connect://to/here", None, error) + obj.GetExecutable() + obj.GetNumModules() + obj.GetModuleAtIndex(0xffffffff) + obj.GetDebugger() + filespec = lldb.SBFileSpec() + obj.FindModule(filespec) + sc_list = obj.FindFunctions("the_func") + sc_list = obj.FindFunctions("the_func", lldb.eFunctionNameTypeAny) + obj.FindFirstType("dont_care") + obj.FindTypes("dont_care") + obj.FindFirstType(None) + obj.GetInstructions(lldb.SBAddress(), bytearray()) + obj.GetSourceManager() + obj.FindGlobalVariables("my_global_var", 1) + address = obj.ResolveLoadAddress(0xffff) + obj.ResolveSymbolContextForAddress(address, 0) + obj.BreakpointCreateByLocation("filename", 20) + obj.BreakpointCreateByLocation(filespec, 20) + obj.BreakpointCreateByName("func", None) + obj.BreakpointCreateByRegex("func.", None) + obj.BreakpointCreateByAddress(0xf0f0) + obj.GetNumBreakpoints() + obj.GetBreakpointAtIndex(0) + obj.BreakpointDelete(0) + obj.FindBreakpointByID(0) + obj.EnableAllBreakpoints() + obj.DisableAllBreakpoints() + obj.DeleteAllBreakpoints() + obj.GetNumWatchpoints() + obj.GetWatchpointAtIndex(0) + obj.DeleteWatchpoint(0) + obj.FindWatchpointByID(0) + obj.EnableAllWatchpoints() + obj.DisableAllWatchpoints() + obj.DeleteAllWatchpoints() + obj.GetAddressByteSize() + obj.GetByteOrder() + obj.GetTriple() + error = lldb.SBError() + obj.WatchAddress(123, 8, True, True, error) + obj.GetBroadcaster() + obj.GetDescription(lldb.SBStream(), lldb.eDescriptionLevelBrief) + obj.Clear() + for module in obj.module_iter(): + s = str(module) + for bp in obj.breakpoint_iter(): + s = str(bp) + for wp in obj.watchpoint_iter(): + s = str(wp) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_thread.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_thread.py new file mode 100644 index 00000000000..0e5f9445db0 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_thread.py @@ -0,0 +1,38 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.GetStopReason() + obj.GetStopReasonDataCount() + obj.GetStopReasonDataAtIndex(100) + obj.GetStopDescription(256) + obj.GetThreadID() + obj.GetIndexID() + obj.GetName() + obj.GetQueueName() + obj.StepOver(lldb.eOnlyDuringStepping) + obj.StepInto(lldb.eOnlyDuringStepping) + obj.StepOut() + frame = lldb.SBFrame() + obj.StepOutOfFrame(frame) + obj.StepInstruction(True) + filespec = lldb.SBFileSpec() + obj.StepOverUntil(frame, filespec, 1234) + obj.RunToAddress(0xabcd) + obj.Suspend() + obj.Resume() + obj.IsSuspended() + obj.GetNumFrames() + obj.GetFrameAtIndex(200) + obj.GetSelectedFrame() + obj.SetSelectedFrame(999) + obj.GetProcess() + obj.GetDescription(lldb.SBStream()) + obj.Clear() + for frame in obj: + s = str(frame) + len(obj) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_type.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_type.py new file mode 100644 index 00000000000..54ab482484f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_type.py @@ -0,0 +1,22 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.GetName() + obj.GetByteSize() + # obj.GetEncoding(5) + obj.GetNumberChildren(True) + member = lldb.SBTypeMember() + obj.GetChildAtIndex(True, 0, member) + obj.GetChildIndexForName(True, "_member_field") + obj.IsAPointerType() + obj.GetPointeeType() + obj.GetDescription(lldb.SBStream()) + obj.IsPointerType(None) + lldb.SBType.IsPointerType(None) + for child_type in obj: + s = str(child_type) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_value.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_value.py new file mode 100644 index 00000000000..9e31a70a79b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_value.py @@ -0,0 +1,67 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.GetError() + obj.GetID() + obj.GetName() + obj.GetTypeName() + obj.GetByteSize() + obj.IsInScope() + obj.GetFormat() + obj.SetFormat(lldb.eFormatBoolean) + obj.GetValue() + obj.GetValueType() + obj.GetValueDidChange() + obj.GetSummary() + obj.GetObjectDescription() + obj.GetLocation() + obj.SetValueFromCString("my_new_value") + obj.GetChildAtIndex(1) + obj.GetChildAtIndex(2, lldb.eNoDynamicValues, False) + obj.GetIndexOfChildWithName("my_first_child") + obj.GetChildMemberWithName("my_first_child") + obj.GetChildMemberWithName("my_first_child", lldb.eNoDynamicValues) + obj.GetNumChildren() + obj.GetOpaqueType() + obj.Dereference() + obj.TypeIsPointerType() + stream = lldb.SBStream() + obj.GetDescription(stream) + obj.GetExpressionPath(stream) + obj.GetExpressionPath(stream, True) + error = lldb.SBError() + obj.Watch(True, True, False, error) + obj.WatchPointee(True, False, True, error) + for child_val in obj: + s = str(child_val) + error = lldb.SBError() + obj.GetValueAsSigned(error, 0) + obj.GetValueAsUnsigned(error, 0) + obj.GetValueAsSigned(0) + obj.GetValueAsUnsigned(0) + obj.GetDynamicValue(lldb.eNoDynamicValues) + obj.GetStaticValue() + obj.IsDynamic() + invalid_type = lldb.SBType() + obj.CreateChildAtOffset("a", 12, invalid_type) + obj.Cast(invalid_type) + obj.CreateValueFromExpression("pt->x", "pt->x") + obj.CreateValueFromAddress("x", 0x123, invalid_type) + invalid_data = lldb.SBData() + obj.CreateValueFromData("x", invalid_data, invalid_type) + obj.GetValueForExpressionPath("[0]") + obj.AddressOf() + obj.GetLoadAddress() + obj.GetAddress() + obj.GetPointeeData(0, 1) + obj.GetData() + obj.GetTarget() + obj.GetProcess() + obj.GetThread() + obj.GetFrame() + obj.GetType() diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_valuelist.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_valuelist.py new file mode 100644 index 00000000000..f20c8775249 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_valuelist.py @@ -0,0 +1,14 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.Append(lldb.SBValue()) + obj.GetSize() + obj.GetValueAtIndex(100) + obj.FindValueObjectByUID(200) + for val in obj: + s = str(val) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_watchpoint.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_watchpoint.py new file mode 100644 index 00000000000..8aa38126ad4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/default-constructor/sb_watchpoint.py @@ -0,0 +1,21 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import lldb + + +def fuzz_obj(obj): + obj.GetID() + obj.IsValid() + obj.GetHardwareIndex() + obj.GetWatchAddress() + obj.GetWatchSize() + obj.SetEnabled(True) + obj.IsEnabled() + obj.GetHitCount() + obj.GetIgnoreCount() + obj.SetIgnoreCount(5) + obj.GetDescription(lldb.SBStream(), lldb.eDescriptionLevelVerbose) + obj.SetCondition("shouldWeStop()") + obj.GetCondition() diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/disassemble-raw-data/TestDisassembleRawData.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/disassemble-raw-data/TestDisassembleRawData.py new file mode 100644 index 00000000000..8e2bc4ac45d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/disassemble-raw-data/TestDisassembleRawData.py @@ -0,0 +1,58 @@ +""" +Use lldb Python API to disassemble raw machine code bytes +""" + +from __future__ import print_function + + +import re +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class DisassembleRawDataTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @add_test_categories(['pyapi']) + @no_debug_info_test + @skipIfRemote + def test_disassemble_raw_data(self): + """Test disassembling raw bytes with the API.""" + # Create a target from the debugger. + arch = self.getArchitecture() + if re.match("mips*el", arch): + target = self.dbg.CreateTargetWithFileAndTargetTriple("", "mipsel") + raw_bytes = bytearray([0x21, 0xf0, 0xa0, 0x03]) + elif re.match("mips", arch): + target = self.dbg.CreateTargetWithFileAndTargetTriple("", "mips") + raw_bytes = bytearray([0x03, 0xa0, 0xf0, 0x21]) + elif re.match("powerpc64le", arch): + target = self.dbg.CreateTargetWithFileAndTargetTriple("", "powerpc64le") + raw_bytes = bytearray([0x00, 0x00, 0x80, 0x38]) + else: + target = self.dbg.CreateTargetWithFileAndTargetTriple("", "x86_64") + raw_bytes = bytearray([0x48, 0x89, 0xe5]) + + self.assertTrue(target, VALID_TARGET) + insts = target.GetInstructions(lldb.SBAddress(0, target), raw_bytes) + + inst = insts.GetInstructionAtIndex(0) + + if self.TraceOn(): + print() + print("Raw bytes: ", [hex(x) for x in raw_bytes]) + print("Disassembled%s" % str(inst)) + if re.match("mips", arch): + self.assertTrue(inst.GetMnemonic(target) == "move") + self.assertTrue(inst.GetOperands(target) == + '$' + "fp, " + '$' + "sp") + elif re.match("powerpc64le", arch): + self.assertTrue(inst.GetMnemonic(target) == "li") + self.assertTrue(inst.GetOperands(target) == "4, 0") + else: + self.assertTrue(inst.GetMnemonic(target) == "movq") + self.assertTrue(inst.GetOperands(target) == + '%' + "rsp, " + '%' + "rbp") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/disassemble-raw-data/TestDisassemble_VST1_64.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/disassemble-raw-data/TestDisassemble_VST1_64.py new file mode 100644 index 00000000000..e4d085de7c2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/disassemble-raw-data/TestDisassemble_VST1_64.py @@ -0,0 +1,78 @@ +""" +Use lldb Python API to disassemble raw machine code bytes +""" + +from __future__ import print_function + +from io import StringIO +import sys + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class Disassemble_VST1_64(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @add_test_categories(['pyapi']) + @no_debug_info_test + @skipIfLLVMTargetMissing("ARM") + def test_disassemble_invalid_vst_1_64_raw_data(self): + """Test disassembling invalid vst1.64 raw bytes with the API.""" + # Create a target from the debugger. + target = self.dbg.CreateTargetWithFileAndTargetTriple("", "thumbv7-apple-macosx") + self.assertTrue(target, VALID_TARGET) + + raw_bytes = bytearray([0xf0, 0xb5, 0x03, 0xaf, + 0x2d, 0xe9, 0x00, 0x0d, + 0xad, 0xf1, 0x40, 0x04, + 0x24, 0xf0, 0x0f, 0x04, + 0xa5, 0x46]) + + assembly = """ + push {r4, r5, r6, r7, lr} + add r7, sp, #0xc + push.w {r8, r10, r11} + sub.w r4, sp, #0x40 + bic r4, r4, #0xf + mov sp, r4 + """ + def split(s): + return [x.strip() for x in s.strip().splitlines()] + + insts = target.GetInstructions(lldb.SBAddress(), raw_bytes) + + if self.TraceOn(): + print() + for i in insts: + print("Disassembled %s" % str(i)) + + if sys.version_info.major >= 3: + sio = StringIO() + insts.Print(sio) + self.assertEqual(split(assembly), split(sio.getvalue())) + + self.assertEqual(insts.GetSize(), len(split(assembly))) + + if sys.version_info.major >= 3: + for i,asm in enumerate(split(assembly)): + inst = insts.GetInstructionAtIndex(i) + sio = StringIO() + inst.Print(sio) + self.assertEqual(asm, sio.getvalue().strip()) + + raw_bytes = bytearray([0x04, 0xf9, 0xed, 0x82]) + + insts = target.GetInstructions(lldb.SBAddress(), raw_bytes) + + inst = insts.GetInstructionAtIndex(0) + + if self.TraceOn(): + print() + print("Raw bytes: ", [hex(x) for x in raw_bytes]) + print("Disassembled%s" % str(inst)) + + self.assertTrue(inst.GetMnemonic(target) == "vst1.64") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/event/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/event/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/event/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/event/TestEvents.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/event/TestEvents.py new file mode 100644 index 00000000000..97ebe8ffc03 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/event/TestEvents.py @@ -0,0 +1,316 @@ +""" +Test lldb Python event APIs. +""" + +from __future__ import print_function + + +import re +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +@skipIfLinux # llvm.org/pr25924, sometimes generating SIGSEGV +@skipIfDarwin +class EventAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to of function 'c'. + self.line = line_number( + 'main.c', '// Find the line number of function "c" here.') + + @add_test_categories(['pyapi']) + @expectedFailureAll( + oslist=["linux"], + bugnumber="llvm.org/pr23730 Flaky, fails ~1/10 cases") + @skipIfWindows # This is flakey on Windows AND when it fails, it hangs: llvm.org/pr38373 + @skipIfNetBSD + def test_listen_for_and_print_event(self): + """Exercise SBEvent API.""" + self.build() + exe = self.getBuildArtifact("a.out") + + self.dbg.SetAsync(True) + + # 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') + + listener = lldb.SBListener("my listener") + + # Now launch the process, and do not stop at the entry point. + error = lldb.SBError() + process = target.Launch(listener, + None, # 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.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + + # Create an empty event object. + event = lldb.SBEvent() + + traceOn = self.TraceOn() + if traceOn: + lldbutil.print_stacktraces(process) + + # Create MyListeningThread class to wait for any kind of event. + import threading + + class MyListeningThread(threading.Thread): + + def run(self): + count = 0 + # Let's only try at most 4 times to retrieve any kind of event. + # After that, the thread exits. + while not count > 3: + if traceOn: + print("Try wait for event...") + if listener.WaitForEvent(5, event): + if traceOn: + desc = lldbutil.get_description(event) + print("Event description:", desc) + print("Event data flavor:", event.GetDataFlavor()) + print( + "Process state:", + lldbutil.state_type_to_str( + process.GetState())) + print() + else: + if traceOn: + print("timeout occurred waiting for event...") + count = count + 1 + listener.Clear() + return + + # Let's start the listening thread to retrieve the events. + my_thread = MyListeningThread() + my_thread.start() + + # Use Python API to continue the process. The listening thread should be + # able to receive the state changed events. + process.Continue() + + # Use Python API to kill the process. The listening thread should be + # able to receive the state changed event, too. + process.Kill() + + # Wait until the 'MyListeningThread' terminates. + my_thread.join() + + # Shouldn't we be testing against some kind of expectation here? + + @add_test_categories(['pyapi']) + @expectedFlakeyLinux("llvm.org/pr23730") # Flaky, fails ~1/100 cases + @skipIfWindows # This is flakey on Windows AND when it fails, it hangs: llvm.org/pr38373 + @skipIfNetBSD + def test_wait_for_event(self): + """Exercise SBListener.WaitForEvent() API.""" + self.build() + exe = self.getBuildArtifact("a.out") + + self.dbg.SetAsync(True) + + # 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) + + # Get the debugger listener. + listener = self.dbg.GetListener() + + # Now launch the process, and do not stop at entry point. + error = lldb.SBError() + process = target.Launch(listener, + None, # 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(error.Success() and process, PROCESS_IS_VALID) + + # Create an empty event object. + event = lldb.SBEvent() + self.assertFalse(event, "Event should not be valid initially") + + # Create MyListeningThread to wait for any kind of event. + import threading + + class MyListeningThread(threading.Thread): + + def run(self): + count = 0 + # Let's only try at most 3 times to retrieve any kind of event. + while not count > 3: + if listener.WaitForEvent(5, event): + #print("Got a valid event:", event) + #print("Event data flavor:", event.GetDataFlavor()) + #print("Event type:", lldbutil.state_type_to_str(event.GetType())) + listener.Clear() + return + count = count + 1 + print("Timeout: listener.WaitForEvent") + listener.Clear() + return + + # Use Python API to kill the process. The listening thread should be + # able to receive a state changed event. + process.Kill() + + # Let's start the listening thread to retrieve the event. + my_thread = MyListeningThread() + my_thread.start() + + # Wait until the 'MyListeningThread' terminates. + my_thread.join() + + self.assertTrue(event, + "My listening thread successfully received an event") + + @skipIfFreeBSD # llvm.org/pr21325 + @add_test_categories(['pyapi']) + @expectedFailureAll( + oslist=["linux"], + bugnumber="llvm.org/pr23617 Flaky, fails ~1/10 cases") + @skipIfWindows # This is flakey on Windows AND when it fails, it hangs: llvm.org/pr38373 + @expectedFlakeyNetBSD + def test_add_listener_to_broadcaster(self): + """Exercise some SBBroadcaster APIs.""" + self.build() + exe = self.getBuildArtifact("a.out") + + self.dbg.SetAsync(True) + + # 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) + + listener = lldb.SBListener("my listener") + + # Now launch the process, and do not stop at the entry point. + error = lldb.SBError() + process = target.Launch(listener, + None, # argv + None, # envp + None, # stdin_path + None, # stdout_path + None, # stderr_path + None, # working directory + 0, # launch flags + False, # Stop at entry + error) # error + + # Create an empty event object. + event = lldb.SBEvent() + self.assertFalse(event, "Event should not be valid initially") + + # The finite state machine for our custom listening thread, with an + # initial state of None, which means no event has been received. + # It changes to 'connected' after 'connected' event is received (for remote platforms) + # It changes to 'running' after 'running' event is received (should happen only if the + # currentstate is either 'None' or 'connected') + # It changes to 'stopped' if a 'stopped' event is received (should happen only if the + # current state is 'running'.) + self.state = None + + # Create MyListeningThread to wait for state changed events. + # By design, a "running" event is expected following by a "stopped" + # event. + import threading + + class MyListeningThread(threading.Thread): + + def run(self): + #print("Running MyListeningThread:", self) + + # Regular expression pattern for the event description. + pattern = re.compile("data = {.*, state = (.*)}$") + + # Let's only try at most 6 times to retrieve our events. + count = 0 + while True: + if listener.WaitForEvent(5, event): + desc = lldbutil.get_description(event) + #print("Event description:", desc) + match = pattern.search(desc) + if not match: + break + if match.group(1) == 'connected': + # When debugging remote targets with lldb-server, we + # first get the 'connected' event. + self.context.assertTrue(self.context.state is None) + self.context.state = 'connected' + continue + elif match.group(1) == 'running': + self.context.assertTrue( + self.context.state is None or self.context.state == 'connected') + self.context.state = 'running' + continue + elif match.group(1) == 'stopped': + self.context.assertTrue( + self.context.state == 'running') + # Whoopee, both events have been received! + self.context.state = 'stopped' + break + else: + break + print("Timeout: listener.WaitForEvent") + count = count + 1 + if count > 6: + break + listener.Clear() + return + + # Use Python API to continue the process. The listening thread should be + # able to receive the state changed events. + process.Continue() + + # Start the listening thread to receive the "running" followed by the + # "stopped" events. + my_thread = MyListeningThread() + # Supply the enclosing context so that our listening thread can access + # the 'state' variable. + my_thread.context = self + my_thread.start() + + # Wait until the 'MyListeningThread' terminates. + my_thread.join() + + # The final judgement. :-) + self.assertTrue(self.state == 'stopped', + "Both expected state changed events received") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/event/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/event/main.c new file mode 100644 index 00000000000..57369520dd1 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/event/main.c @@ -0,0 +1,48 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +// This simple program is to test the lldb Python API related to events. + +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) +{ + 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); + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/exprpath_synthetic/TestExprPathSynthetic.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/exprpath_synthetic/TestExprPathSynthetic.py new file mode 100644 index 00000000000..19832aefee9 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/exprpath_synthetic/TestExprPathSynthetic.py @@ -0,0 +1,7 @@ +from lldbsuite.test import decorators +from lldbsuite.test import lldbinline + +lldbinline.MakeInlineTest( + __file__, globals(), [ + decorators.skipIfFreeBSD, decorators.skipIfLinux, + decorators.skipIfWindows, decorators.skipIfNetBSD]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/exprpath_synthetic/main.mm b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/exprpath_synthetic/main.mm new file mode 100644 index 00000000000..365fe12dd60 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/exprpath_synthetic/main.mm @@ -0,0 +1,19 @@ +//===-- main.mm --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#import <Foundation/Foundation.h> +#include <vector> + +int main (int argc, char const *argv[]) +{ + std::vector<int> v{1,2,3,4,5}; + NSArray *a = @[@"Hello",@"World",@"From Me"]; + return 0; //% v = self.frame().FindVariable("v"); v0 = v.GetChildAtIndex(0); s = lldb.SBStream(); v0.GetExpressionPath(s); + //% self.runCmd("expr %s = 12" % s.GetData()); self.assertTrue(v0.GetValueAsUnsigned() == 12, "value change via expr failed") + //% a = self.frame().FindVariable("a"); a1 = a.GetChildAtIndex(1); s = lldb.SBStream(); a1.GetExpressionPath(s); + //% self.expect("po %s" % s.GetData(), substrs = ["World"]) +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/file_handle/TestFileHandle.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/file_handle/TestFileHandle.py new file mode 100644 index 00000000000..53ca64932d6 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/file_handle/TestFileHandle.py @@ -0,0 +1,919 @@ +""" +Test lldb Python API for file handles. +""" + + +import os +import io +import re +import sys +from contextlib import contextmanager + +import lldb +from lldbsuite.test import lldbtest +from lldbsuite.test.decorators import * + +class OhNoe(Exception): + pass + +class BadIO(io.TextIOBase): + @property + def closed(self): + return False + def writable(self): + return True + def readable(self): + return True + def write(self, s): + raise OhNoe('OH NOE') + def read(self, n): + raise OhNoe("OH NOE") + def flush(self): + raise OhNoe('OH NOE') + +# This class will raise an exception while it's being +# converted into a C++ object by swig +class ReallyBadIO(io.TextIOBase): + def fileno(self): + return 999 + def writable(self): + raise OhNoe("OH NOE!!!") + +class MutableBool(): + def __init__(self, value): + self.value = value + def set(self, value): + self.value = bool(value) + def __bool__(self): + return self.value + +class FlushTestIO(io.StringIO): + def __init__(self, mutable_flushed, mutable_closed): + super(FlushTestIO, self).__init__() + self.mut_flushed = mutable_flushed + self.mut_closed = mutable_closed + def close(self): + self.mut_closed.set(True) + return super(FlushTestIO, self).close() + def flush(self): + self.mut_flushed.set(True) + return super(FlushTestIO, self).flush() + +@contextmanager +def replace_stdout(new): + old = sys.stdout + sys.stdout = new + try: + yield + finally: + sys.stdout = old + +def readStrippedLines(f): + def i(): + for line in f: + line = line.strip() + if line: + yield line + return list(i()) + + +class FileHandleTestCase(lldbtest.TestBase): + + NO_DEBUG_INFO_TESTCASE = True + mydir = lldbtest.Base.compute_mydir(__file__) + + # The way this class interacts with the debugger is different + # than normal. Most of these test cases will mess with the + # debugger I/O streams, so we want a fresh debugger for each + # test so those mutations don't interfere with each other. + # + # Also, the way normal tests evaluate debugger commands is + # by using a SBCommandInterpreter directly, which captures + # the output in a result object. For many of tests tests + # we want the debugger to write the output directly to + # its I/O streams like it would have done interactively. + # + # For this reason we also define handleCmd() here, even though + # it is similar to runCmd(). + + def setUp(self): + super(FileHandleTestCase, self).setUp() + self.debugger = lldb.SBDebugger.Create() + self.out_filename = self.getBuildArtifact('output') + self.in_filename = self.getBuildArtifact('input') + + def tearDown(self): + lldb.SBDebugger.Destroy(self.debugger) + super(FileHandleTestCase, self).tearDown() + for name in (self.out_filename, self.in_filename): + if os.path.exists(name): + os.unlink(name) + + # Similar to runCmd(), but this uses the per-test debugger, and it + # supports, letting the debugger just print the results instead + # of collecting them. + def handleCmd(self, cmd, check=True, collect_result=True): + assert not check or collect_result + ret = lldb.SBCommandReturnObject() + if collect_result: + interpreter = self.debugger.GetCommandInterpreter() + interpreter.HandleCommand(cmd, ret) + else: + self.debugger.HandleCommand(cmd) + self.debugger.GetOutputFile().Flush() + self.debugger.GetErrorFile().Flush() + if collect_result and check: + self.assertTrue(ret.Succeeded()) + return ret.GetOutput() + + + @add_test_categories(['pyapi']) + def test_legacy_file_out_script(self): + with open(self.out_filename, 'w') as f: + self.debugger.SetOutputFileHandle(f, False) + # scripts print to output even if you capture the results + # I'm not sure I love that behavior, but that's the way + # it's been for a long time. That's why this test works + # even with collect_result=True. + self.handleCmd('script 1+1') + self.debugger.GetOutputFileHandle().write('FOO\n') + lldb.SBDebugger.Destroy(self.debugger) + with open(self.out_filename, 'r') as f: + self.assertEqual(readStrippedLines(f), ['2', 'FOO']) + + + @add_test_categories(['pyapi']) + def test_legacy_file_out(self): + with open(self.out_filename, 'w') as f: + self.debugger.SetOutputFileHandle(f, False) + self.handleCmd('p/x 3735928559', collect_result=False, check=False) + lldb.SBDebugger.Destroy(self.debugger) + with open(self.out_filename, 'r') as f: + self.assertIn('deadbeef', f.read()) + + @add_test_categories(['pyapi']) + def test_legacy_file_err_with_get(self): + with open(self.out_filename, 'w') as f: + self.debugger.SetErrorFileHandle(f, False) + self.handleCmd('lolwut', check=False, collect_result=False) + f2 = self.debugger.GetErrorFileHandle() + f2.write('FOOBAR\n') + f2.flush() + lldb.SBDebugger.Destroy(self.debugger) + with open(self.out_filename, 'r') as f: + errors = f.read() + self.assertTrue(re.search(r'error:.*lolwut', errors)) + self.assertTrue(re.search(r'FOOBAR', errors)) + + + @add_test_categories(['pyapi']) + def test_legacy_file_err(self): + with open(self.out_filename, 'w') as f: + self.debugger.SetErrorFileHandle(f, False) + self.handleCmd('lol', check=False, collect_result=False) + lldb.SBDebugger.Destroy(self.debugger) + with open(self.out_filename, 'r') as f: + self.assertIn("is not a valid command", f.read()) + + + @add_test_categories(['pyapi']) + def test_legacy_file_error(self): + debugger = self.debugger + with open(self.out_filename, 'w') as f: + debugger.SetErrorFileHandle(f, False) + self.handleCmd('lolwut', check=False, collect_result=False) + with open(self.out_filename, 'r') as f: + errors = f.read() + self.assertTrue(re.search(r'error:.*lolwut', errors)) + + @add_test_categories(['pyapi']) + def test_sbfile_type_errors(self): + sbf = lldb.SBFile() + self.assertRaises(Exception, sbf.Write, None) + self.assertRaises(Exception, sbf.Read, None) + self.assertRaises(Exception, sbf.Read, b'this bytes is not mutable') + self.assertRaises(Exception, sbf.Write, u"ham sandwich") + self.assertRaises(Exception, sbf.Read, u"ham sandwich") + + + @add_test_categories(['pyapi']) + def test_sbfile_write_fileno(self): + with open(self.out_filename, 'w') as f: + sbf = lldb.SBFile(f.fileno(), "w", False) + self.assertTrue(sbf.IsValid()) + e, n = sbf.Write(b'FOO\nBAR') + self.assertTrue(e.Success()) + self.assertEqual(n, 7) + sbf.Close() + self.assertFalse(sbf.IsValid()) + with open(self.out_filename, 'r') as f: + self.assertEqual(readStrippedLines(f), ['FOO', 'BAR']) + + + @add_test_categories(['pyapi']) + def test_sbfile_write(self): + with open(self.out_filename, 'w') as f: + sbf = lldb.SBFile(f) + e, n = sbf.Write(b'FOO\n') + self.assertTrue(e.Success()) + self.assertEqual(n, 4) + sbf.Close() + self.assertTrue(f.closed) + with open(self.out_filename, 'r') as f: + self.assertEqual(f.read().strip(), 'FOO') + + + @add_test_categories(['pyapi']) + def test_sbfile_read_fileno(self): + with open(self.out_filename, 'w') as f: + f.write('FOO') + with open(self.out_filename, 'r') as f: + sbf = lldb.SBFile(f.fileno(), "r", False) + self.assertTrue(sbf.IsValid()) + buffer = bytearray(100) + e, n = sbf.Read(buffer) + self.assertTrue(e.Success()) + self.assertEqual(buffer[:n], b'FOO') + + + @add_test_categories(['pyapi']) + def test_sbfile_read(self): + with open(self.out_filename, 'w') as f: + f.write('foo') + with open(self.out_filename, 'r') as f: + sbf = lldb.SBFile(f) + buf = bytearray(100) + e, n = sbf.Read(buf) + self.assertTrue(e.Success()) + self.assertEqual(n, 3) + self.assertEqual(buf[:n], b'foo') + sbf.Close() + self.assertTrue(f.closed) + + + @add_test_categories(['pyapi']) + def test_fileno_out(self): + with open(self.out_filename, 'w') as f: + sbf = lldb.SBFile(f.fileno(), "w", False) + status = self.debugger.SetOutputFile(sbf) + self.assertTrue(status.Success()) + self.handleCmd('script 1+2') + self.debugger.GetOutputFile().Write(b'quux') + + with open(self.out_filename, 'r') as f: + self.assertEqual(readStrippedLines(f), ['3', 'quux']) + + + @add_test_categories(['pyapi']) + def test_fileno_help(self): + with open(self.out_filename, 'w') as f: + sbf = lldb.SBFile(f.fileno(), "w", False) + status = self.debugger.SetOutputFile(sbf) + self.assertTrue(status.Success()) + self.handleCmd("help help", collect_result=False, check=False) + with open(self.out_filename, 'r') as f: + self.assertTrue(re.search(r'Show a list of all debugger commands', f.read())) + + + @add_test_categories(['pyapi']) + def test_help(self): + debugger = self.debugger + with open(self.out_filename, 'w') as f: + status = debugger.SetOutputFile(lldb.SBFile(f)) + self.assertTrue(status.Success()) + self.handleCmd("help help", check=False, collect_result=False) + with open(self.out_filename, 'r') as f: + self.assertIn('Show a list of all debugger commands', f.read()) + + + @add_test_categories(['pyapi']) + def test_immediate(self): + with open(self.out_filename, 'w') as f: + ret = lldb.SBCommandReturnObject() + ret.SetImmediateOutputFile(f) + interpreter = self.debugger.GetCommandInterpreter() + interpreter.HandleCommand("help help", ret) + # make sure the file wasn't closed early. + f.write("\nQUUX\n") + ret = None # call destructor and flush streams + with open(self.out_filename, 'r') as f: + output = f.read() + self.assertTrue(re.search(r'Show a list of all debugger commands', output)) + self.assertTrue(re.search(r'QUUX', output)) + + + @add_test_categories(['pyapi']) + @skipIf(py_version=['<', (3,)]) + def test_immediate_string(self): + f = io.StringIO() + ret = lldb.SBCommandReturnObject() + ret.SetImmediateOutputFile(f) + interpreter = self.debugger.GetCommandInterpreter() + interpreter.HandleCommand("help help", ret) + # make sure the file wasn't closed early. + f.write("\nQUUX\n") + ret = None # call destructor and flush streams + output = f.getvalue() + self.assertTrue(re.search(r'Show a list of all debugger commands', output)) + self.assertTrue(re.search(r'QUUX', output)) + + + @add_test_categories(['pyapi']) + @skipIf(py_version=['<', (3,)]) + def test_immediate_sbfile_string(self): + f = io.StringIO() + ret = lldb.SBCommandReturnObject() + ret.SetImmediateOutputFile(lldb.SBFile(f)) + interpreter = self.debugger.GetCommandInterpreter() + interpreter.HandleCommand("help help", ret) + output = f.getvalue() + ret = None # call destructor and flush streams + # sbfile default constructor doesn't borrow the file + self.assertTrue(f.closed) + self.assertTrue(re.search(r'Show a list of all debugger commands', output)) + + + @add_test_categories(['pyapi']) + def test_fileno_inout(self): + with open(self.in_filename, 'w') as f: + f.write("help help\n") + + with open(self.out_filename, 'w') as outf, open(self.in_filename, 'r') as inf: + + outsbf = lldb.SBFile(outf.fileno(), "w", False) + status = self.debugger.SetOutputFile(outsbf) + self.assertTrue(status.Success()) + + insbf = lldb.SBFile(inf.fileno(), "r", False) + status = self.debugger.SetInputFile(insbf) + self.assertTrue(status.Success()) + + opts = lldb.SBCommandInterpreterRunOptions() + self.debugger.RunCommandInterpreter(True, False, opts, 0, False, False) + self.debugger.GetOutputFile().Flush() + + with open(self.out_filename, 'r') as f: + self.assertTrue(re.search(r'Show a list of all debugger commands', f.read())) + + + @add_test_categories(['pyapi']) + def test_inout(self): + with open(self.in_filename, 'w') as f: + f.write("help help\n") + with open(self.out_filename, 'w') as outf, \ + open(self.in_filename, 'r') as inf: + status = self.debugger.SetOutputFile(lldb.SBFile(outf)) + self.assertTrue(status.Success()) + status = self.debugger.SetInputFile(lldb.SBFile(inf)) + self.assertTrue(status.Success()) + opts = lldb.SBCommandInterpreterRunOptions() + self.debugger.RunCommandInterpreter(True, False, opts, 0, False, False) + self.debugger.GetOutputFile().Flush() + with open(self.out_filename, 'r') as f: + output = f.read() + self.assertIn('Show a list of all debugger commands', output) + + + @add_test_categories(['pyapi']) + def test_binary_inout(self): + debugger = self.debugger + with open(self.in_filename, 'w') as f: + f.write("help help\n") + with open(self.out_filename, 'wb') as outf, \ + open(self.in_filename, 'rb') as inf: + status = debugger.SetOutputFile(lldb.SBFile(outf)) + self.assertTrue(status.Success()) + status = debugger.SetInputFile(lldb.SBFile(inf)) + self.assertTrue(status.Success()) + opts = lldb.SBCommandInterpreterRunOptions() + debugger.RunCommandInterpreter(True, False, opts, 0, False, False) + debugger.GetOutputFile().Flush() + with open(self.out_filename, 'r') as f: + output = f.read() + self.assertIn('Show a list of all debugger commands', output) + + + @add_test_categories(['pyapi']) + @skipIf(py_version=['<', (3,)]) + def test_string_inout(self): + inf = io.StringIO("help help\np/x ~0\n") + outf = io.StringIO() + status = self.debugger.SetOutputFile(lldb.SBFile(outf)) + self.assertTrue(status.Success()) + status = self.debugger.SetInputFile(lldb.SBFile(inf)) + self.assertTrue(status.Success()) + opts = lldb.SBCommandInterpreterRunOptions() + self.debugger.RunCommandInterpreter(True, False, opts, 0, False, False) + self.debugger.GetOutputFile().Flush() + output = outf.getvalue() + self.assertIn('Show a list of all debugger commands', output) + self.assertIn('0xfff', output) + + + @add_test_categories(['pyapi']) + @skipIf(py_version=['<', (3,)]) + def test_bytes_inout(self): + inf = io.BytesIO(b"help help\nhelp b\n") + outf = io.BytesIO() + status = self.debugger.SetOutputFile(lldb.SBFile(outf)) + self.assertTrue(status.Success()) + status = self.debugger.SetInputFile(lldb.SBFile(inf)) + self.assertTrue(status.Success()) + opts = lldb.SBCommandInterpreterRunOptions() + self.debugger.RunCommandInterpreter(True, False, opts, 0, False, False) + self.debugger.GetOutputFile().Flush() + output = outf.getvalue() + self.assertIn(b'Show a list of all debugger commands', output) + self.assertIn(b'Set a breakpoint', output) + + + @add_test_categories(['pyapi']) + def test_fileno_error(self): + with open(self.out_filename, 'w') as f: + + sbf = lldb.SBFile(f.fileno(), 'w', False) + status = self.debugger.SetErrorFile(sbf) + self.assertTrue(status.Success()) + + self.handleCmd('lolwut', check=False, collect_result=False) + + self.debugger.GetErrorFile().Write(b'\nzork\n') + + with open(self.out_filename, 'r') as f: + errors = f.read() + self.assertTrue(re.search(r'error:.*lolwut', errors)) + self.assertTrue(re.search(r'zork', errors)) + + + @add_test_categories(['pyapi']) + def test_replace_stdout(self): + f = io.StringIO() + with replace_stdout(f): + self.assertEqual(sys.stdout, f) + self.handleCmd('script sys.stdout.write("lol")', + collect_result=False, check=False) + self.assertEqual(sys.stdout, f) + + + @add_test_categories(['pyapi']) + def test_replace_stdout_with_nonfile(self): + debugger = self.debugger + f = io.StringIO() + with replace_stdout(f): + class Nothing(): + pass + with replace_stdout(Nothing): + self.assertEqual(sys.stdout, Nothing) + self.handleCmd('script sys.stdout.write("lol")', + check=False, collect_result=False) + self.assertEqual(sys.stdout, Nothing) + sys.stdout.write(u"FOO") + self.assertEqual(f.getvalue(), "FOO") + + + @add_test_categories(['pyapi']) + def test_sbfile_write_borrowed(self): + with open(self.out_filename, 'w') as f: + sbf = lldb.SBFile.Create(f, borrow=True) + e, n = sbf.Write(b'FOO') + self.assertTrue(e.Success()) + self.assertEqual(n, 3) + sbf.Close() + self.assertFalse(f.closed) + f.write('BAR\n') + with open(self.out_filename, 'r') as f: + self.assertEqual(f.read().strip(), 'FOOBAR') + + + + @add_test_categories(['pyapi']) + @skipIf(py_version=['<', (3,)]) + def test_sbfile_write_forced(self): + with open(self.out_filename, 'w') as f: + written = MutableBool(False) + orig_write = f.write + def mywrite(x): + written.set(True) + return orig_write(x) + f.write = mywrite + sbf = lldb.SBFile.Create(f, force_io_methods=True) + e, n = sbf.Write(b'FOO') + self.assertTrue(written) + self.assertTrue(e.Success()) + self.assertEqual(n, 3) + sbf.Close() + self.assertTrue(f.closed) + with open(self.out_filename, 'r') as f: + self.assertEqual(f.read().strip(), 'FOO') + + + @add_test_categories(['pyapi']) + @skipIf(py_version=['<', (3,)]) + def test_sbfile_write_forced_borrowed(self): + with open(self.out_filename, 'w') as f: + written = MutableBool(False) + orig_write = f.write + def mywrite(x): + written.set(True) + return orig_write(x) + f.write = mywrite + sbf = lldb.SBFile.Create(f, borrow=True, force_io_methods=True) + e, n = sbf.Write(b'FOO') + self.assertTrue(written) + self.assertTrue(e.Success()) + self.assertEqual(n, 3) + sbf.Close() + self.assertFalse(f.closed) + with open(self.out_filename, 'r') as f: + self.assertEqual(f.read().strip(), 'FOO') + + + @add_test_categories(['pyapi']) + @skipIf(py_version=['<', (3,)]) + def test_sbfile_write_string(self): + f = io.StringIO() + sbf = lldb.SBFile(f) + e, n = sbf.Write(b'FOO') + self.assertEqual(f.getvalue().strip(), "FOO") + self.assertTrue(e.Success()) + self.assertEqual(n, 3) + sbf.Close() + self.assertTrue(f.closed) + + + @add_test_categories(['pyapi']) + @skipIf(py_version=['<', (3,)]) + def test_string_out(self): + f = io.StringIO() + status = self.debugger.SetOutputFile(f) + self.assertTrue(status.Success()) + self.handleCmd("script 'foobar'") + self.assertEqual(f.getvalue().strip(), "'foobar'") + + + @add_test_categories(['pyapi']) + @skipIf(py_version=['<', (3,)]) + def test_string_error(self): + f = io.StringIO() + debugger = self.debugger + status = debugger.SetErrorFile(f) + self.assertTrue(status.Success()) + self.handleCmd('lolwut', check=False, collect_result=False) + errors = f.getvalue() + self.assertTrue(re.search(r'error:.*lolwut', errors)) + + + @add_test_categories(['pyapi']) + @skipIf(py_version=['<', (3,)]) + def test_sbfile_write_bytes(self): + f = io.BytesIO() + sbf = lldb.SBFile(f) + e, n = sbf.Write(b'FOO') + self.assertEqual(f.getvalue().strip(), b"FOO") + self.assertTrue(e.Success()) + self.assertEqual(n, 3) + sbf.Close() + self.assertTrue(f.closed) + + @add_test_categories(['pyapi']) + @skipIf(py_version=['<', (3,)]) + def test_sbfile_read_string(self): + f = io.StringIO('zork') + sbf = lldb.SBFile(f) + buf = bytearray(100) + e, n = sbf.Read(buf) + self.assertTrue(e.Success()) + self.assertEqual(buf[:n], b'zork') + + + @add_test_categories(['pyapi']) + @skipIf(py_version=['<', (3,)]) + def test_sbfile_read_string_one_byte(self): + f = io.StringIO('z') + sbf = lldb.SBFile(f) + buf = bytearray(1) + e, n = sbf.Read(buf) + self.assertTrue(e.Fail()) + self.assertEqual(n, 0) + self.assertEqual(e.GetCString(), "can't read less than 6 bytes from a utf8 text stream") + + + @add_test_categories(['pyapi']) + @skipIf(py_version=['<', (3,)]) + def test_sbfile_read_bytes(self): + f = io.BytesIO(b'zork') + sbf = lldb.SBFile(f) + buf = bytearray(100) + e, n = sbf.Read(buf) + self.assertTrue(e.Success()) + self.assertEqual(buf[:n], b'zork') + + + @add_test_categories(['pyapi']) + @skipIf(py_version=['<', (3,)]) + def test_sbfile_out(self): + with open(self.out_filename, 'w') as f: + sbf = lldb.SBFile(f) + status = self.debugger.SetOutputFile(sbf) + self.assertTrue(status.Success()) + self.handleCmd('script 2+2') + with open(self.out_filename, 'r') as f: + self.assertEqual(f.read().strip(), '4') + + + @add_test_categories(['pyapi']) + @skipIf(py_version=['<', (3,)]) + def test_file_out(self): + with open(self.out_filename, 'w') as f: + status = self.debugger.SetOutputFile(f) + self.assertTrue(status.Success()) + self.handleCmd('script 2+2') + with open(self.out_filename, 'r') as f: + self.assertEqual(f.read().strip(), '4') + + + @add_test_categories(['pyapi']) + def test_sbfile_error(self): + with open(self.out_filename, 'w') as f: + sbf = lldb.SBFile(f) + status = self.debugger.SetErrorFile(sbf) + self.assertTrue(status.Success()) + self.handleCmd('lolwut', check=False, collect_result=False) + with open(self.out_filename, 'r') as f: + errors = f.read() + self.assertTrue(re.search(r'error:.*lolwut', errors)) + + + @add_test_categories(['pyapi']) + def test_file_error(self): + with open(self.out_filename, 'w') as f: + status = self.debugger.SetErrorFile(f) + self.assertTrue(status.Success()) + self.handleCmd('lolwut', check=False, collect_result=False) + with open(self.out_filename, 'r') as f: + errors = f.read() + self.assertTrue(re.search(r'error:.*lolwut', errors)) + + + @add_test_categories(['pyapi']) + def test_exceptions(self): + self.assertRaises(Exception, lldb.SBFile, None) + self.assertRaises(Exception, lldb.SBFile, "ham sandwich") + if sys.version_info[0] < 3: + self.assertRaises(Exception, lldb.SBFile, ReallyBadIO()) + else: + self.assertRaises(OhNoe, lldb.SBFile, ReallyBadIO()) + error, n = lldb.SBFile(BadIO()).Write(b"FOO") + self.assertEqual(n, 0) + self.assertTrue(error.Fail()) + self.assertIn('OH NOE', error.GetCString()) + error, n = lldb.SBFile(BadIO()).Read(bytearray(100)) + self.assertEqual(n, 0) + self.assertTrue(error.Fail()) + self.assertIn('OH NOE', error.GetCString()) + + + @add_test_categories(['pyapi']) + @skipIf(py_version=['<', (3,)]) + def test_exceptions_logged(self): + messages = list() + self.debugger.SetLoggingCallback(messages.append) + self.handleCmd('log enable lldb script') + self.debugger.SetOutputFile(lldb.SBFile(BadIO())) + self.handleCmd('script 1+1') + self.assertTrue(any('OH NOE' in msg for msg in messages)) + + + @add_test_categories(['pyapi']) + @skipIf(py_version=['<', (3,)]) + def test_flush(self): + flushed = MutableBool(False) + closed = MutableBool(False) + f = FlushTestIO(flushed, closed) + self.assertFalse(flushed) + self.assertFalse(closed) + sbf = lldb.SBFile(f) + self.assertFalse(flushed) + self.assertFalse(closed) + sbf = None + self.assertFalse(flushed) + self.assertTrue(closed) + self.assertTrue(f.closed) + + flushed = MutableBool(False) + closed = MutableBool(False) + f = FlushTestIO(flushed, closed) + self.assertFalse(flushed) + self.assertFalse(closed) + sbf = lldb.SBFile.Create(f, borrow=True) + self.assertFalse(flushed) + self.assertFalse(closed) + sbf = None + self.assertTrue(flushed) + self.assertFalse(closed) + self.assertFalse(f.closed) + + + @add_test_categories(['pyapi']) + def test_fileno_flush(self): + with open(self.out_filename, 'w') as f: + f.write("foo") + sbf = lldb.SBFile(f) + sbf.Write(b'bar') + sbf = None + self.assertTrue(f.closed) + with open(self.out_filename, 'r') as f: + self.assertEqual(f.read(), 'foobar') + + with open(self.out_filename, 'w+') as f: + f.write("foo") + sbf = lldb.SBFile.Create(f, borrow=True) + sbf.Write(b'bar') + sbf = None + self.assertFalse(f.closed) + f.seek(0) + self.assertEqual(f.read(), 'foobar') + + + @add_test_categories(['pyapi']) + def test_close(self): + debugger = self.debugger + with open(self.out_filename, 'w') as f: + status = debugger.SetOutputFile(f) + self.assertTrue(status.Success()) + self.handleCmd("help help", check=False, collect_result=False) + # make sure the file wasn't closed early. + f.write("\nZAP\n") + lldb.SBDebugger.Destroy(debugger) + # check that output file was closed when debugger was destroyed. + with self.assertRaises(ValueError): + f.write("\nQUUX\n") + with open(self.out_filename, 'r') as f: + output = f.read() + self.assertTrue(re.search(r'Show a list of all debugger commands', output)) + self.assertTrue(re.search(r'ZAP', output)) + + + @add_test_categories(['pyapi']) + @skipIf(py_version=['<', (3,)]) + def test_stdout(self): + f = io.StringIO() + status = self.debugger.SetOutputFile(f) + self.assertTrue(status.Success()) + self.handleCmd(r"script sys.stdout.write('foobar\n')") + self.assertEqual(f.getvalue().strip().split(), ["foobar", "7"]) + + + @add_test_categories(['pyapi']) + def test_stdout_file(self): + with open(self.out_filename, 'w') as f: + status = self.debugger.SetOutputFile(f) + self.assertTrue(status.Success()) + self.handleCmd(r"script sys.stdout.write('foobar\n')") + with open(self.out_filename, 'r') as f: + # In python2 sys.stdout.write() returns None, which + # the REPL will ignore, but in python3 it will + # return the number of bytes written, which the REPL + # will print out. + lines = [x for x in f.read().strip().split() if x != "7"] + self.assertEqual(lines, ["foobar"]) + + + @add_test_categories(['pyapi']) + @skipIf(py_version=['<', (3,)]) + def test_identity(self): + + f = io.StringIO() + sbf = lldb.SBFile(f) + self.assertTrue(f is sbf.GetFile()) + sbf.Close() + self.assertTrue(f.closed) + + f = io.StringIO() + sbf = lldb.SBFile.Create(f, borrow=True) + self.assertTrue(f is sbf.GetFile()) + sbf.Close() + self.assertFalse(f.closed) + + with open(self.out_filename, 'w') as f: + sbf = lldb.SBFile(f) + self.assertTrue(f is sbf.GetFile()) + sbf.Close() + self.assertTrue(f.closed) + + with open(self.out_filename, 'w') as f: + sbf = lldb.SBFile.Create(f, borrow=True) + self.assertFalse(f is sbf.GetFile()) + sbf.Write(b"foobar\n") + self.assertEqual(f.fileno(), sbf.GetFile().fileno()) + sbf.Close() + self.assertFalse(f.closed) + + with open(self.out_filename, 'r') as f: + self.assertEqual("foobar", f.read().strip()) + + with open(self.out_filename, 'wb') as f: + sbf = lldb.SBFile.Create(f, borrow=True, force_io_methods=True) + self.assertTrue(f is sbf.GetFile()) + sbf.Write(b"foobar\n") + self.assertEqual(f.fileno(), sbf.GetFile().fileno()) + sbf.Close() + self.assertFalse(f.closed) + + with open(self.out_filename, 'r') as f: + self.assertEqual("foobar", f.read().strip()) + + with open(self.out_filename, 'wb') as f: + sbf = lldb.SBFile.Create(f, force_io_methods=True) + self.assertTrue(f is sbf.GetFile()) + sbf.Write(b"foobar\n") + self.assertEqual(f.fileno(), sbf.GetFile().fileno()) + sbf.Close() + self.assertTrue(f.closed) + + with open(self.out_filename, 'r') as f: + self.assertEqual("foobar", f.read().strip()) + + + @add_test_categories(['pyapi']) + def test_back_and_forth(self): + with open(self.out_filename, 'w') as f: + # at each step here we're borrowing the file, so we have to keep + # them all alive until the end. + sbf = lldb.SBFile.Create(f, borrow=True) + def i(sbf): + for i in range(10): + f = sbf.GetFile() + self.assertEqual(f.mode, "w") + yield f + sbf = lldb.SBFile.Create(f, borrow=True) + yield sbf + sbf.Write(str(i).encode('ascii') + b"\n") + files = list(i(sbf)) + with open(self.out_filename, 'r') as f: + self.assertEqual(list(range(10)), list(map(int, f.read().strip().split()))) + + + @add_test_categories(['pyapi']) + def test_set_filehandle_none(self): + self.assertRaises(Exception, self.debugger.SetOutputFile, None) + self.assertRaises(Exception, self.debugger.SetOutputFile, "ham sandwich") + self.assertRaises(Exception, self.debugger.SetOutputFileHandle, "ham sandwich") + self.assertRaises(Exception, self.debugger.SetInputFile, None) + self.assertRaises(Exception, self.debugger.SetInputFile, "ham sandwich") + self.assertRaises(Exception, self.debugger.SetInputFileHandle, "ham sandwich") + self.assertRaises(Exception, self.debugger.SetErrorFile, None) + self.assertRaises(Exception, self.debugger.SetErrorFile, "ham sandwich") + self.assertRaises(Exception, self.debugger.SetErrorFileHandle, "ham sandwich") + + with open(self.out_filename, 'w') as f: + status = self.debugger.SetOutputFile(f) + self.assertTrue(status.Success()) + status = self.debugger.SetErrorFile(f) + self.assertTrue(status.Success()) + self.debugger.SetOutputFileHandle(None, False) + self.debugger.SetErrorFileHandle(None, False) + sbf = self.debugger.GetOutputFile() + if sys.version_info.major >= 3: + # python 2 lacks PyFile_FromFd, so GetFile() will + # have to duplicate the file descriptor and make a FILE* + # in order to convert a NativeFile it back to a python + # file. + self.assertEqual(sbf.GetFile().fileno(), 1) + sbf = self.debugger.GetErrorFile() + if sys.version_info.major >= 3: + self.assertEqual(sbf.GetFile().fileno(), 2) + with open(self.out_filename, 'r') as f: + status = self.debugger.SetInputFile(f) + self.assertTrue(status.Success()) + self.debugger.SetInputFileHandle(None, False) + sbf = self.debugger.GetInputFile() + if sys.version_info.major >= 3: + self.assertEqual(sbf.GetFile().fileno(), 0) + + + @add_test_categories(['pyapi']) + def test_sbstream(self): + + with open(self.out_filename, 'w') as f: + stream = lldb.SBStream() + stream.RedirectToFile(f) + stream.Print("zork") + with open(self.out_filename, 'r') as f: + self.assertEqual(f.read().strip(), "zork") + + with open(self.out_filename, 'w') as f: + stream = lldb.SBStream() + stream.RedirectToFileHandle(f, True) + stream.Print("Yendor") + with open(self.out_filename, 'r') as f: + self.assertEqual(f.read().strip(), "Yendor") + + stream = lldb.SBStream() + f = open(self.out_filename, 'w') + stream.RedirectToFile(lldb.SBFile.Create(f, borrow=False)) + stream.Print("Frobozz") + stream = None + self.assertTrue(f.closed) + with open(self.out_filename, 'r') as f: + self.assertEqual(f.read().strip(), "Frobozz") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/findvalue_duplist/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/findvalue_duplist/Makefile new file mode 100644 index 00000000000..33da5d0645e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/findvalue_duplist/Makefile @@ -0,0 +1,8 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules + +# Clean renamed executable on 'make clean' +clean:: + $(RM) -f no_synth + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/findvalue_duplist/TestSBFrameFindValue.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/findvalue_duplist/TestSBFrameFindValue.py new file mode 100644 index 00000000000..0c9e2800768 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/findvalue_duplist/TestSBFrameFindValue.py @@ -0,0 +1,80 @@ +"""Test that SBFrame::FindValue finds things but does not duplicate the entire variables list""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class SBFrameFindValueTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + @add_test_categories(['pyapi']) + def test_formatters_api(self): + """Test that SBFrame::FindValue finds things but does not duplicate the entire variables list""" + self.build() + self.setTearDownCleanup() + + exe = self.getBuildArtifact("a.out") + + # Create the target + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Set the breakpoints + breakpoint = target.BreakpointCreateBySourceRegex( + 'Set breakpoint here', lldb.SBFileSpec("main.cpp")) + self.assertTrue(breakpoint.GetNumLocations() > 0, VALID_BREAKPOINT) + + # Launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # Frame #0 should be at our breakpoint. + threads = lldbutil.get_threads_stopped_at_breakpoint( + process, breakpoint) + + self.assertTrue(len(threads) == 1) + self.thread = threads[0] + self.frame = self.thread.frames[0] + self.assertTrue(self.frame, "Frame 0 is valid.") + + self.assertTrue( + self.frame.GetVariables( + True, + True, + False, + True).GetSize() == 2, + "variable count is off") + self.assertFalse( + self.frame.FindValue( + "NoSuchThing", + lldb.eValueTypeVariableArgument, + lldb.eDynamicCanRunTarget).IsValid(), + "found something that should not be here") + self.assertTrue( + self.frame.GetVariables( + True, + True, + False, + True).GetSize() == 2, + "variable count is off after failed FindValue()") + self.assertTrue( + self.frame.FindValue( + "a", + lldb.eValueTypeVariableArgument, + lldb.eDynamicCanRunTarget).IsValid(), + "FindValue() didn't find an argument") + self.assertTrue( + self.frame.GetVariables( + True, + True, + False, + True).GetSize() == 2, + "variable count is off after successful FindValue()") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/findvalue_duplist/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/findvalue_duplist/main.cpp new file mode 100644 index 00000000000..7058d46b04a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/findvalue_duplist/main.cpp @@ -0,0 +1,7 @@ +int foo(int a, int b) { + return a + b; // Set breakpoint here +} + +int main() { + return foo(1,3); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/formatters/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/formatters/Makefile new file mode 100644 index 00000000000..16a823213db --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/formatters/Makefile @@ -0,0 +1,7 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules + +# Clean renamed executable on 'make clean' +clean:: + $(RM) -f no_synth diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/formatters/TestFormattersSBAPI.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/formatters/TestFormattersSBAPI.py new file mode 100644 index 00000000000..f01d7c457c5 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/formatters/TestFormattersSBAPI.py @@ -0,0 +1,500 @@ +"""Test Python APIs for working with formatters""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class SBFormattersAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + self.line = line_number('main.cpp', '// Set break point at this line.') + + @add_test_categories(['pyapi']) + def test_formatters_api(self): + """Test Python APIs for working with formatters""" + self.build() + self.setTearDownCleanup() + + """Test Python APIs for working with formatters""" + self.runCmd("file " + self.getBuildArtifact("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 synthetic clear', check=False) + self.runCmd('type category delete foobar', check=False) + self.runCmd('type category delete JASSynth', check=False) + self.runCmd('type category delete newbar', check=False) + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + + format = lldb.SBTypeFormat(lldb.eFormatHex) + category = self.dbg.GetDefaultCategory() + category.AddTypeFormat(lldb.SBTypeNameSpecifier("int"), format) + + self.expect("frame variable foo.A", + substrs=['0x00000001']) + self.expect("frame variable foo.E", matching=False, + substrs=['b8cca70a']) + + category.AddTypeFormat(lldb.SBTypeNameSpecifier("long"), format) + self.expect("frame variable foo.A", + substrs=['0x00000001']) + self.expect("frame variable foo.E", + substrs=['b8cca70a']) + + format.SetFormat(lldb.eFormatOctal) + category.AddTypeFormat(lldb.SBTypeNameSpecifier("int"), format) + self.expect("frame variable foo.A", + substrs=[' 01']) + self.expect("frame variable foo.E", + substrs=['b8cca70a']) + + category.DeleteTypeFormat(lldb.SBTypeNameSpecifier("int")) + category.DeleteTypeFormat(lldb.SBTypeNameSpecifier("long")) + self.expect("frame variable foo.A", matching=False, + substrs=[' 01']) + self.expect("frame variable foo.E", matching=False, + substrs=['b8cca70a']) + + summary = lldb.SBTypeSummary.CreateWithSummaryString( + "the hello world you'll never see") + summary.SetSummaryString('hello world') + new_category = self.dbg.GetCategory("foobar") + self.assertFalse( + new_category.IsValid(), + "getting a non-existing category worked") + new_category = self.dbg.CreateCategory("foobar") + new_category.SetEnabled(True) + new_category.AddTypeSummary( + lldb.SBTypeNameSpecifier( + "^.*t$", + True, # is_regexp + ), summary) + + self.expect("frame variable foo.A", + substrs=['hello world']) + self.expect("frame variable foo.E", matching=False, + substrs=['hello world']) + self.expect("frame variable foo.B", + substrs=['hello world']) + self.expect("frame variable foo.F", + substrs=['hello world']) + new_category.SetEnabled(False) + self.expect("frame variable foo.A", matching=False, + substrs=['hello world']) + self.expect("frame variable foo.E", matching=False, + substrs=['hello world']) + self.expect("frame variable foo.B", matching=False, + substrs=['hello world']) + self.expect("frame variable foo.F", matching=False, + substrs=['hello world']) + self.dbg.DeleteCategory(new_category.GetName()) + self.expect("frame variable foo.A", matching=False, + substrs=['hello world']) + self.expect("frame variable foo.E", matching=False, + substrs=['hello world']) + self.expect("frame variable foo.B", matching=False, + substrs=['hello world']) + self.expect("frame variable foo.F", matching=False, + substrs=['hello world']) + + filter = lldb.SBTypeFilter(0) + filter.AppendExpressionPath("A") + filter.AppendExpressionPath("D") + self.assertTrue( + filter.GetNumberOfExpressionPaths() == 2, + "filter with two items does not have two items") + + category.AddTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct"), filter) + self.expect("frame variable foo", + substrs=['A = 1', 'D = 6.28']) + self.expect("frame variable foo", matching=False, + substrs=['B = ', 'C = ', 'E = ', 'F = ']) + + category.DeleteTypeFilter( + lldb.SBTypeNameSpecifier( + "JustAStruct", True)) + self.expect("frame variable foo", + substrs=['A = 1', 'D = 6.28']) + self.expect("frame variable foo", matching=False, + substrs=['B = ', 'C = ', 'E = ', 'F = ']) + + category.DeleteTypeFilter( + lldb.SBTypeNameSpecifier( + "JustAStruct", False)) + self.expect("frame variable foo", + substrs=['A = 1', 'D = 6.28']) + self.expect("frame variable foo", matching=True, + substrs=['B = ', 'C = ', 'E = ', 'F = ']) + + self.runCmd("command script import --allow-reload ./synth.py") + + self.expect("frame variable foo", matching=False, + substrs=['X = 1']) + + self.dbg.GetCategory("JASSynth").SetEnabled(True) + self.expect("frame variable foo", matching=True, + substrs=['X = 1']) + + self.dbg.GetCategory("CCCSynth").SetEnabled(True) + self.expect( + "frame variable ccc", + matching=True, + substrs=[ + 'CCC object with leading value (int) a = 111', + 'a = 111', + 'b = 222', + 'c = 333']) + + foo_var = self.dbg.GetSelectedTarget().GetProcess( + ).GetSelectedThread().GetSelectedFrame().FindVariable('foo') + self.assertTrue(foo_var.IsValid(), 'could not find foo') + self.assertTrue( + foo_var.GetDeclaration().IsValid(), + 'foo declaration is invalid') + + self.assertTrue( + foo_var.GetNumChildren() == 2, + 'synthetic value has wrong number of child items (synth)') + self.assertTrue( + foo_var.GetChildMemberWithName('X').GetValueAsUnsigned() == 1, + 'foo_synth.X has wrong value (synth)') + self.assertFalse( + foo_var.GetChildMemberWithName('B').IsValid(), + 'foo_synth.B is valid but should not (synth)') + + self.dbg.GetCategory("JASSynth").SetEnabled(False) + foo_var = self.dbg.GetSelectedTarget().GetProcess( + ).GetSelectedThread().GetSelectedFrame().FindVariable('foo') + self.assertTrue(foo_var.IsValid(), 'could not find foo') + + self.assertFalse( + foo_var.GetNumChildren() == 2, + 'still seeing synthetic value') + + filter = lldb.SBTypeFilter(0) + filter.AppendExpressionPath("A") + filter.AppendExpressionPath("D") + category.AddTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct"), filter) + self.expect("frame variable foo", + substrs=['A = 1', 'D = 6.28']) + + foo_var = self.dbg.GetSelectedTarget().GetProcess( + ).GetSelectedThread().GetSelectedFrame().FindVariable('foo') + self.assertTrue(foo_var.IsValid(), 'could not find foo') + + self.assertTrue( + foo_var.GetNumChildren() == 2, + 'synthetic value has wrong number of child items (filter)') + self.assertTrue( + foo_var.GetChildMemberWithName('X').GetValueAsUnsigned() == 0, + 'foo_synth.X has wrong value (filter)') + self.assertTrue( + foo_var.GetChildMemberWithName('A').GetValueAsUnsigned() == 1, + 'foo_synth.A has wrong value (filter)') + + self.assertTrue(filter.ReplaceExpressionPathAtIndex( + 0, "C"), "failed to replace an expression path in filter") + self.expect("frame variable foo", + substrs=['A = 1', 'D = 6.28']) + category.AddTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct"), filter) + self.expect("frame variable foo", + substrs=["C = 'e'", 'D = 6.28']) + category.AddTypeFilter(lldb.SBTypeNameSpecifier("FooType"), filter) + filter.ReplaceExpressionPathAtIndex(1, "F") + self.expect("frame variable foo", + substrs=["C = 'e'", 'D = 6.28']) + category.AddTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct"), filter) + self.expect("frame variable foo", + substrs=["C = 'e'", 'F = 0']) + self.expect("frame variable bar", + substrs=["C = 'e'", 'D = 6.28']) + + foo_var = self.dbg.GetSelectedTarget().GetProcess( + ).GetSelectedThread().GetSelectedFrame().FindVariable('foo') + self.assertTrue(foo_var.IsValid(), 'could not find foo') + self.assertTrue( + foo_var.GetChildMemberWithName('C').GetValueAsUnsigned() == ord('e'), + 'foo_synth.C has wrong value (filter)') + + chosen = self.dbg.GetFilterForType( + lldb.SBTypeNameSpecifier("JustAStruct")) + self.assertTrue( + chosen.count == 2, + "wrong filter found for JustAStruct") + self.assertTrue( + chosen.GetExpressionPathAtIndex(0) == 'C', + "wrong item at index 0 for JustAStruct") + self.assertTrue( + chosen.GetExpressionPathAtIndex(1) == 'F', + "wrong item at index 1 for JustAStruct") + + self.assertFalse( + category.DeleteTypeFilter( + lldb.SBTypeNameSpecifier("NoSuchType")), + "deleting a non-existing filter worked") + self.assertFalse( + category.DeleteTypeSummary( + lldb.SBTypeNameSpecifier("NoSuchType")), + "deleting a non-existing summary worked") + self.assertFalse( + category.DeleteTypeFormat( + lldb.SBTypeNameSpecifier("NoSuchType")), + "deleting a non-existing format worked") + self.assertFalse( + category.DeleteTypeSynthetic( + lldb.SBTypeNameSpecifier("NoSuchType")), + "deleting a non-existing synthetic worked") + + self.assertFalse( + category.DeleteTypeFilter( + lldb.SBTypeNameSpecifier("")), + "deleting a filter for '' worked") + self.assertFalse( + category.DeleteTypeSummary( + lldb.SBTypeNameSpecifier("")), + "deleting a summary for '' worked") + self.assertFalse( + category.DeleteTypeFormat( + lldb.SBTypeNameSpecifier("")), + "deleting a format for '' worked") + self.assertFalse( + category.DeleteTypeSynthetic( + lldb.SBTypeNameSpecifier("")), + "deleting a synthetic for '' worked") + + try: + self.assertFalse( + category.AddTypeSummary( + lldb.SBTypeNameSpecifier("NoneSuchType"), + None), + "adding a summary valued None worked") + except: + pass + else: + self.assertFalse(True, "adding a summary valued None worked") + + try: + self.assertFalse( + category.AddTypeFilter( + lldb.SBTypeNameSpecifier("NoneSuchType"), + None), + "adding a filter valued None worked") + except: + pass + else: + self.assertFalse(True, "adding a filter valued None worked") + + try: + self.assertFalse( + category.AddTypeSynthetic( + lldb.SBTypeNameSpecifier("NoneSuchType"), + None), + "adding a synthetic valued None worked") + except: + pass + else: + self.assertFalse(True, "adding a synthetic valued None worked") + + try: + self.assertFalse( + category.AddTypeFormat( + lldb.SBTypeNameSpecifier("NoneSuchType"), + None), + "adding a format valued None worked") + except: + pass + else: + self.assertFalse(True, "adding a format valued None worked") + + self.assertFalse( + category.AddTypeSummary( + lldb.SBTypeNameSpecifier("EmptySuchType"), + lldb.SBTypeSummary()), + "adding a summary without value worked") + self.assertFalse( + category.AddTypeFilter( + lldb.SBTypeNameSpecifier("EmptySuchType"), + lldb.SBTypeFilter()), + "adding a filter without value worked") + self.assertFalse( + category.AddTypeSynthetic( + lldb.SBTypeNameSpecifier("EmptySuchType"), + lldb.SBTypeSynthetic()), + "adding a synthetic without value worked") + self.assertFalse( + category.AddTypeFormat( + lldb.SBTypeNameSpecifier("EmptySuchType"), + lldb.SBTypeFormat()), + "adding a format without value worked") + + self.assertFalse( + category.AddTypeSummary( + lldb.SBTypeNameSpecifier(""), + lldb.SBTypeSummary.CreateWithSummaryString("")), + "adding a summary for an invalid type worked") + self.assertFalse( + category.AddTypeFilter( + lldb.SBTypeNameSpecifier(""), + lldb.SBTypeFilter(0)), + "adding a filter for an invalid type worked") + self.assertFalse( + category.AddTypeSynthetic( + lldb.SBTypeNameSpecifier(""), + lldb.SBTypeSynthetic.CreateWithClassName("")), + "adding a synthetic for an invalid type worked") + self.assertFalse( + category.AddTypeFormat( + lldb.SBTypeNameSpecifier(""), + lldb.SBTypeFormat( + lldb.eFormatHex)), + "adding a format for an invalid type worked") + + new_category = self.dbg.CreateCategory("newbar") + new_category.AddTypeSummary( + lldb.SBTypeNameSpecifier("JustAStruct"), + lldb.SBTypeSummary.CreateWithScriptCode("return 'hello scripted world';")) + self.expect("frame variable foo", matching=False, + substrs=['hello scripted world']) + new_category.SetEnabled(True) + self.expect("frame variable foo", matching=True, + substrs=['hello scripted world']) + + self.expect("frame variable foo_ptr", matching=True, + substrs=['hello scripted world']) + new_category.AddTypeSummary( + lldb.SBTypeNameSpecifier("JustAStruct"), + lldb.SBTypeSummary.CreateWithScriptCode( + "return 'hello scripted world';", + lldb.eTypeOptionSkipPointers)) + self.expect("frame variable foo", matching=True, + substrs=['hello scripted world']) + + frame = self.dbg.GetSelectedTarget().GetProcess( + ).GetSelectedThread().GetSelectedFrame() + foo_ptr = frame.FindVariable("foo_ptr") + summary = foo_ptr.GetTypeSummary() + + self.assertFalse( + summary.IsValid(), + "summary found for foo* when none was planned") + + self.expect("frame variable foo_ptr", matching=False, + substrs=['hello scripted world']) + + new_category.AddTypeSummary( + lldb.SBTypeNameSpecifier("JustAStruct"), + lldb.SBTypeSummary.CreateWithSummaryString( + "hello static world", + lldb.eTypeOptionNone)) + + summary = foo_ptr.GetTypeSummary() + + self.assertTrue( + summary.IsValid(), + "no summary found for foo* when one was in place") + self.assertTrue( + summary.GetData() == "hello static world", + "wrong summary found for foo*") + + self.expect("frame variable e1", substrs=["I am an empty Empty1 {}"]) + self.expect("frame variable e2", substrs=["I am an empty Empty2"]) + self.expect( + "frame variable e2", + substrs=["I am an empty Empty2 {}"], + matching=False) + + self.assertTrue( + self.dbg.GetCategory( + lldb.eLanguageTypeObjC) is not None, + "ObjC category is None") + + @add_test_categories(['pyapi']) + def test_force_synth_off(self): + """Test that one can have the public API return non-synthetic SBValues if desired""" + self.build(dictionary={'EXE': 'no_synth'}) + self.setTearDownCleanup() + + self.runCmd("file " + self.getBuildArtifact("no_synth"), + 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 synthetic clear', check=False) + self.runCmd('type category delete foobar', check=False) + self.runCmd('type category delete JASSynth', check=False) + self.runCmd('type category delete newbar', check=False) + self.runCmd('settings set target.enable-synthetic-value true') + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + + frame = self.dbg.GetSelectedTarget().GetProcess( + ).GetSelectedThread().GetSelectedFrame() + int_vector = frame.FindVariable("int_vector") + if self.TraceOn(): + print(int_vector) + self.assertTrue( + int_vector.GetNumChildren() == 0, + 'synthetic vector is empty') + + self.runCmd('settings set target.enable-synthetic-value false') + frame = self.dbg.GetSelectedTarget().GetProcess( + ).GetSelectedThread().GetSelectedFrame() + int_vector = frame.FindVariable("int_vector") + if self.TraceOn(): + print(int_vector) + self.assertFalse( + int_vector.GetNumChildren() == 0, + '"physical" vector is not empty') + + self.runCmd('settings set target.enable-synthetic-value true') + frame = self.dbg.GetSelectedTarget().GetProcess( + ).GetSelectedThread().GetSelectedFrame() + int_vector = frame.FindVariable("int_vector") + if self.TraceOn(): + print(int_vector) + self.assertTrue( + int_vector.GetNumChildren() == 0, + 'synthetic vector is still empty') diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/formatters/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/formatters/main.cpp new file mode 100644 index 00000000000..f21c956144c --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/formatters/main.cpp @@ -0,0 +1,59 @@ +#include <stdio.h> +#include <vector> + +struct JustAStruct +{ + int A; + float B; + char C; + double D; + long E; + short F; +}; + +struct FooType +{ + int A; + float B; + char C; + double D; + long E; + short F; +}; + +struct CCC +{ + int a, b, c; +}; + +struct Empty1 { void *data; }; +struct Empty2 { void *data; }; + + +int main(int argc, char const *argv[]) { + JustAStruct foo; + foo.A = 1; + foo.B = 3.14; + foo.C = 'e'; + foo.D = 6.28; + foo.E = 3100419850; + foo.F = 0; + + FooType bar; + bar.A = 1; + bar.B = 3.14; + bar.C = 'e'; + bar.D = 6.28; + bar.E = 3100419850; + bar.F = 0; + JustAStruct* foo_ptr = &foo; + + std::vector<int> int_vector; + + CCC ccc = {111, 222, 333}; + + Empty1 e1; + Empty2 e2; + + return 0; // Set break point at this line. +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/formatters/synth.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/formatters/synth.py new file mode 100644 index 00000000000..75a8d6cfc65 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/formatters/synth.py @@ -0,0 +1,117 @@ +import lldb + + +class jasSynthProvider: + + def __init__(self, valobj, dict): + self.valobj = valobj + + def num_children(self): + return 2 + + def get_child_at_index(self, index): + child = None + if index == 0: + child = self.valobj.GetChildMemberWithName('A') + if index == 1: + child = self.valobj.CreateValueFromExpression('X', '(int)1') + return child + + def get_child_index(self, name): + if name == 'A': + return 0 + if name == 'X': + return 1 + return None + + +def ccc_summary(sbvalue, internal_dict): + sbvalue = sbvalue.GetNonSyntheticValue() + # This tests that the SBValue.GetNonSyntheticValue() actually returns a + # non-synthetic value. If it does not, then sbvalue.GetChildMemberWithName("a") + # in the following statement will call the 'get_child_index' method of the + # synthetic child provider CCCSynthProvider below (which raises an + # exception). + return "CCC object with leading value " + \ + str(sbvalue.GetChildMemberWithName("a")) + + +class CCCSynthProvider(object): + + def __init__(self, sbvalue, internal_dict): + self._sbvalue = sbvalue + + def num_children(self): + return 3 + + def get_child_index(self, name): + raise RuntimeError("I don't want to be called!") + + def get_child_at_index(self, index): + if index == 0: + return self._sbvalue.GetChildMemberWithName("a") + if index == 1: + return self._sbvalue.GetChildMemberWithName("b") + if index == 2: + return self._sbvalue.GetChildMemberWithName("c") + + +def empty1_summary(sbvalue, internal_dict): + return "I am an empty Empty1" + + +class Empty1SynthProvider(object): + + def __init__(self, sbvalue, internal_dict): + self._sbvalue = sbvalue + + def num_children(self): + return 0 + + def get_child_at_index(self, index): + return None + + +def empty2_summary(sbvalue, internal_dict): + return "I am an empty Empty2" + + +class Empty2SynthProvider(object): + + def __init__(self, sbvalue, internal_dict): + self._sbvalue = sbvalue + + def num_children(self): + return 0 + + def get_child_at_index(self, index): + return None + + +def __lldb_init_module(debugger, dict): + debugger.CreateCategory("JASSynth").AddTypeSynthetic( + lldb.SBTypeNameSpecifier("JustAStruct"), + lldb.SBTypeSynthetic.CreateWithClassName("synth.jasSynthProvider")) + cat = debugger.CreateCategory("CCCSynth") + cat.AddTypeSynthetic( + lldb.SBTypeNameSpecifier("CCC"), + lldb.SBTypeSynthetic.CreateWithClassName("synth.CCCSynthProvider", + lldb.eTypeOptionCascade)) + cat.AddTypeSummary( + lldb.SBTypeNameSpecifier("CCC"), + lldb.SBTypeSummary.CreateWithFunctionName("synth.ccc_summary", + lldb.eTypeOptionCascade)) + cat.AddTypeSynthetic( + lldb.SBTypeNameSpecifier("Empty1"), + lldb.SBTypeSynthetic.CreateWithClassName("synth.Empty1SynthProvider")) + cat.AddTypeSummary( + lldb.SBTypeNameSpecifier("Empty1"), + lldb.SBTypeSummary.CreateWithFunctionName("synth.empty1_summary")) + cat.AddTypeSynthetic( + lldb.SBTypeNameSpecifier("Empty2"), + lldb.SBTypeSynthetic.CreateWithClassName("synth.Empty2SynthProvider")) + cat.AddTypeSummary( + lldb.SBTypeNameSpecifier("Empty2"), + lldb.SBTypeSummary.CreateWithFunctionName( + "synth.empty2_summary", + lldb.eTypeOptionHideEmptyAggregates)) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/TestFrames.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/TestFrames.py new file mode 100644 index 00000000000..91ac30e36e3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/TestFrames.py @@ -0,0 +1,221 @@ +""" +Use lldb Python SBFrame API to get the argument values of the call stacks. +And other SBFrame API tests. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class FrameAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @add_test_categories(['pyapi']) + def test_get_arg_vals_for_call_stack(self): + """Exercise SBFrame.GetVariables() API to get argument vals.""" + self.build() + exe = self.getBuildArtifact("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) + + # Now 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) + + # Keeps track of the number of times 'a' is called where it is within a + # depth of 3 of the 'c' leaf function. + callsOfA = 0 + + from six import StringIO as SixStringIO + session = SixStringIO() + while process.GetState() == lldb.eStateStopped: + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertIsNotNone(thread) + # Inspect at most 3 frames. + numFrames = min(3, thread.GetNumFrames()) + for i in range(numFrames): + frame = thread.GetFrameAtIndex(i) + if self.TraceOn(): + print("frame:", frame) + + name = frame.GetFunction().GetName() + if name == 'a': + callsOfA = callsOfA + 1 + + # We'll inspect only the arguments for the current frame: + # + # arguments => True + # locals => False + # statics => False + # in_scope_only => True + valList = frame.GetVariables(True, False, False, True) + argList = [] + for val in valList: + argList.append("(%s)%s=%s" % (val.GetTypeName(), + val.GetName(), + val.GetValue())) + print("%s(%s)" % (name, ", ".join(argList)), file=session) + + # Also check the generic pc & stack pointer. We can't test their absolute values, + # but they should be valid. Uses get_GPRs() from the lldbutil + # module. + gpr_reg_set = lldbutil.get_GPRs(frame) + pc_value = gpr_reg_set.GetChildMemberWithName("pc") + self.assertTrue(pc_value, "We should have a valid PC.") + pc_value_int = int(pc_value.GetValue(), 0) + # Make sure on arm targets we dont mismatch PC value on the basis of thumb bit. + # Frame PC will not have thumb bit set in case of a thumb + # instruction as PC. + if self.getArchitecture() in ['arm', 'armv7', 'armv7k']: + pc_value_int &= ~1 + self.assertTrue( + pc_value_int == frame.GetPC(), + "PC gotten as a value should equal frame's GetPC") + sp_value = gpr_reg_set.GetChildMemberWithName("sp") + self.assertTrue( + sp_value, "We should have a valid Stack Pointer.") + self.assertTrue(int(sp_value.GetValue(), 0) == frame.GetSP( + ), "SP gotten as a value should equal frame's GetSP") + + print("---", file=session) + process.Continue() + + # At this point, the inferior process should have exited. + self.assertTrue( + process.GetState() == lldb.eStateExited, + PROCESS_EXITED) + + # Expect to find 'a' on the call stacks two times. + self.assertTrue(callsOfA == 2, + "Expect to find 'a' on the call stacks two times") + # By design, the 'a' call frame has the following arg vals: + # o a((int)val=1, (char)ch='A') + # o a((int)val=3, (char)ch='A') + if self.TraceOn(): + print("Full stack traces when stopped on the breakpoint 'c':") + print(session.getvalue()) + self.expect(session.getvalue(), "Argugment values displayed correctly", + exe=False, + substrs=["a((int)val=1, (char)ch='A')", + "a((int)val=3, (char)ch='A')"]) + + @add_test_categories(['pyapi']) + def test_frame_api_boundary_condition(self): + """Exercise SBFrame APIs with boundary condition inputs.""" + self.build() + exe = self.getBuildArtifact("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) + + # Now 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 = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertIsNotNone(thread) + frame = thread.GetFrameAtIndex(0) + if self.TraceOn(): + print("frame:", frame) + + # Boundary condition testings. + val1 = frame.FindVariable(None, True) + val2 = frame.FindVariable(None, False) + val3 = frame.FindValue(None, lldb.eValueTypeVariableGlobal) + if self.TraceOn(): + print("val1:", val1) + print("val2:", val2) + + frame.EvaluateExpression(None) + + @add_test_categories(['pyapi']) + def test_frame_api_IsEqual(self): + """Exercise SBFrame API IsEqual.""" + self.build() + exe = self.getBuildArtifact("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) + + # Now 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 = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertIsNotNone(thread) + + frameEntered = thread.GetFrameAtIndex(0) + if self.TraceOn(): + print(frameEntered) + lldbutil.print_stacktrace(thread) + self.assertTrue(frameEntered) + + # Doing two step overs while still inside c(). + thread.StepOver() + thread.StepOver() + self.assertTrue(thread) + frameNow = thread.GetFrameAtIndex(0) + if self.TraceOn(): + print(frameNow) + lldbutil.print_stacktrace(thread) + self.assertTrue(frameNow) + + # The latest two frames are considered equal. + self.assertTrue(frameEntered.IsEqual(frameNow)) + + # Now let's step out of frame c(). + thread.StepOutOfFrame(frameNow) + frameOutOfC = thread.GetFrameAtIndex(0) + if self.TraceOn(): + print(frameOutOfC) + lldbutil.print_stacktrace(thread) + self.assertTrue(frameOutOfC) + + # The latest two frames should not be equal. + self.assertFalse(frameOutOfC.IsEqual(frameNow)) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/get-variables/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/get-variables/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/get-variables/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/get-variables/TestGetVariables.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/get-variables/TestGetVariables.py new file mode 100644 index 00000000000..7ced4ddb98f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/get-variables/TestGetVariables.py @@ -0,0 +1,294 @@ +""" +Test that SBFrame::GetVariables() calls work correctly. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbplatform +from lldbsuite.test import lldbutil + + +def get_names_from_value_list(value_list): + names = list() + for value in value_list: + names.append(value.GetName()) + return names + + +class TestGetVariables(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + self.source = 'main.c' + + def verify_variable_names(self, description, value_list, names): + copy_names = list(names) + actual_names = get_names_from_value_list(value_list) + for name in actual_names: + if name in copy_names: + copy_names.remove(name) + else: + self.assertTrue( + False, "didn't find '%s' in %s" % + (name, copy_names)) + self.assertEqual( + len(copy_names), 0, "%s: we didn't find variables: %s in value list (%s)" % + (description, copy_names, actual_names)) + + def test(self): + self.build() + + # Set debugger into synchronous mode + self.dbg.SetAsync(False) + + # Create a target by the debugger. + exe = self.getBuildArtifact("a.out") + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + line1 = line_number(self.source, '// breakpoint 1') + line2 = line_number(self.source, '// breakpoint 2') + line3 = line_number(self.source, '// breakpoint 3') + + breakpoint1 = target.BreakpointCreateByLocation(self.source, line1) + breakpoint2 = target.BreakpointCreateByLocation(self.source, line2) + breakpoint3 = target.BreakpointCreateByLocation(self.source, line3) + + self.assertTrue(breakpoint1.GetNumLocations() >= 1, PROCESS_IS_VALID) + self.assertTrue(breakpoint2.GetNumLocations() >= 1, PROCESS_IS_VALID) + self.assertTrue(breakpoint3.GetNumLocations() >= 1, PROCESS_IS_VALID) + + # 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) + + threads = lldbutil.get_threads_stopped_at_breakpoint( + process, breakpoint1) + self.assertEqual( + len(threads), + 1, + "There should be a thread stopped at breakpoint 1") + + thread = threads[0] + self.assertTrue(thread.IsValid(), "Thread must be valid") + frame = thread.GetFrameAtIndex(0) + self.assertTrue(frame.IsValid(), "Frame must be valid") + + arg_names = ['argc', 'argv'] + local_names = ['i', 'j', 'k'] + static_names = ['static_var', 'g_global_var', 'g_static_var'] + breakpoint1_locals = ['i'] + breakpoint1_statics = ['static_var'] + num_args = len(arg_names) + num_locals = len(local_names) + num_statics = len(static_names) + args_yes = True + args_no = False + locals_yes = True + locals_no = False + statics_yes = True + statics_no = False + in_scopy_only = True + ignore_scope = False + + # Verify if we ask for only arguments that we got what we expect + vars = frame.GetVariables( + args_yes, locals_no, statics_no, ignore_scope) + self.assertEqual( + vars.GetSize(), + num_args, + "There should be %i arguments, but we are reporting %i" % + (num_args, + vars.GetSize())) + self.verify_variable_names("check names of arguments", vars, arg_names) + self.assertEqual( + len(arg_names), + num_args, + "make sure verify_variable_names() didn't mutate list") + + # Verify if we ask for only locals that we got what we expect + vars = frame.GetVariables( + args_no, locals_yes, statics_no, ignore_scope) + self.assertEqual( + vars.GetSize(), + num_locals, + "There should be %i local variables, but we are reporting %i" % + (num_locals, + vars.GetSize())) + self.verify_variable_names("check names of locals", vars, local_names) + + # Verify if we ask for only statics that we got what we expect + vars = frame.GetVariables( + args_no, locals_no, statics_yes, ignore_scope) + print('statics: ', str(vars)) + self.assertEqual( + vars.GetSize(), + num_statics, + "There should be %i static variables, but we are reporting %i" % + (num_statics, + vars.GetSize())) + self.verify_variable_names( + "check names of statics", vars, static_names) + + # Verify if we ask for arguments and locals that we got what we expect + vars = frame.GetVariables( + args_yes, locals_yes, statics_no, ignore_scope) + desc = 'arguments + locals' + names = arg_names + local_names + count = len(names) + self.assertEqual( + vars.GetSize(), + count, + "There should be %i %s (%s) but we are reporting %i (%s)" % + (count, + desc, + names, + vars.GetSize(), + get_names_from_value_list(vars))) + self.verify_variable_names("check names of %s" % (desc), vars, names) + + # Verify if we ask for arguments and statics that we got what we expect + vars = frame.GetVariables( + args_yes, locals_no, statics_yes, ignore_scope) + desc = 'arguments + statics' + names = arg_names + static_names + count = len(names) + self.assertEqual( + vars.GetSize(), + count, + "There should be %i %s (%s) but we are reporting %i (%s)" % + (count, + desc, + names, + vars.GetSize(), + get_names_from_value_list(vars))) + self.verify_variable_names("check names of %s" % (desc), vars, names) + + # Verify if we ask for locals and statics that we got what we expect + vars = frame.GetVariables( + args_no, locals_yes, statics_yes, ignore_scope) + desc = 'locals + statics' + names = local_names + static_names + count = len(names) + self.assertEqual( + vars.GetSize(), + count, + "There should be %i %s (%s) but we are reporting %i (%s)" % + (count, + desc, + names, + vars.GetSize(), + get_names_from_value_list(vars))) + self.verify_variable_names("check names of %s" % (desc), vars, names) + + # Verify if we ask for arguments, locals and statics that we got what + # we expect + vars = frame.GetVariables( + args_yes, locals_yes, statics_yes, ignore_scope) + desc = 'arguments + locals + statics' + names = arg_names + local_names + static_names + count = len(names) + self.assertEqual( + vars.GetSize(), + count, + "There should be %i %s (%s) but we are reporting %i (%s)" % + (count, + desc, + names, + vars.GetSize(), + get_names_from_value_list(vars))) + self.verify_variable_names("check names of %s" % (desc), vars, names) + + # Verify if we ask for in scope locals that we got what we expect + vars = frame.GetVariables( + args_no, locals_yes, statics_no, in_scopy_only) + desc = 'in scope locals at breakpoint 1' + names = ['i'] + count = len(names) + self.assertEqual( + vars.GetSize(), + count, + "There should be %i %s (%s) but we are reporting %i (%s)" % + (count, + desc, + names, + vars.GetSize(), + get_names_from_value_list(vars))) + self.verify_variable_names("check names of %s" % (desc), vars, names) + + # Continue to breakpoint 2 + process.Continue() + + threads = lldbutil.get_threads_stopped_at_breakpoint( + process, breakpoint2) + self.assertEqual( + len(threads), + 1, + "There should be a thread stopped at breakpoint 2") + + thread = threads[0] + self.assertTrue(thread.IsValid(), "Thread must be valid") + frame = thread.GetFrameAtIndex(0) + self.assertTrue(frame.IsValid(), "Frame must be valid") + + # Verify if we ask for in scope locals that we got what we expect + vars = frame.GetVariables( + args_no, locals_yes, statics_no, in_scopy_only) + desc = 'in scope locals at breakpoint 2' + names = ['i', 'j'] + count = len(names) + self.assertEqual( + vars.GetSize(), + count, + "There should be %i %s (%s) but we are reporting %i (%s)" % + (count, + desc, + names, + vars.GetSize(), + get_names_from_value_list(vars))) + self.verify_variable_names("check names of %s" % (desc), vars, names) + + # Continue to breakpoint 3 + process.Continue() + + threads = lldbutil.get_threads_stopped_at_breakpoint( + process, breakpoint3) + self.assertEqual( + len(threads), + 1, + "There should be a thread stopped at breakpoint 3") + + thread = threads[0] + self.assertTrue(thread.IsValid(), "Thread must be valid") + frame = thread.GetFrameAtIndex(0) + self.assertTrue(frame.IsValid(), "Frame must be valid") + + # Verify if we ask for in scope locals that we got what we expect + vars = frame.GetVariables( + args_no, locals_yes, statics_no, in_scopy_only) + desc = 'in scope locals at breakpoint 3' + names = ['i', 'j', 'k'] + count = len(names) + self.assertEqual( + vars.GetSize(), + count, + "There should be %i %s (%s) but we are reporting %i (%s)" % + (count, + desc, + names, + vars.GetSize(), + get_names_from_value_list(vars))) + self.verify_variable_names("check names of %s" % (desc), vars, names) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/get-variables/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/get-variables/main.c new file mode 100644 index 00000000000..7606e2ac909 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/get-variables/main.c @@ -0,0 +1,28 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +int g_global_var = 123; +static int g_static_var = 123; + +int main (int argc, char const *argv[]) +{ + static int static_var = 123; + g_static_var = 123; // clang bug. Need to touch this variable, otherwise it disappears. + int i = 0; // breakpoint 1 + for (i=0; i<1; ++i) + { + int j = i*2; + printf("i = %i, j = %i\n", i, j); // breakpoint 2 + { + int k = i*j*3; + printf("i = %i, j = %i\n", i, j); // breakpoint 3 + } + } + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/inlines/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/inlines/Makefile new file mode 100644 index 00000000000..e6d9d8310a0 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/inlines/Makefile @@ -0,0 +1,7 @@ +C_SOURCES := inlines.c + +ifneq (,$(findstring icc,$(CC))) + CFLAGS_EXTRAS := -debug inline-debug-info +endif + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/inlines/TestInlinedFrame.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/inlines/TestInlinedFrame.py new file mode 100644 index 00000000000..da4e9cb06e7 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/inlines/TestInlinedFrame.py @@ -0,0 +1,94 @@ +""" +Testlldb Python SBFrame APIs IsInlined() and GetFunctionName(). +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class InlinedFrameAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to of function 'c'. + self.source = 'inlines.c' + self.first_stop = line_number( + self.source, '// This should correspond to the first break stop.') + self.second_stop = line_number( + self.source, '// This should correspond to the second break stop.') + + @add_test_categories(['pyapi']) + def test_stop_at_outer_inline(self): + """Exercise SBFrame.IsInlined() and SBFrame.GetFunctionName().""" + self.build() + exe = self.getBuildArtifact("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 the name of 'inner_inline'. + breakpoint = target.BreakpointCreateByName('inner_inline', 'a.out') + #print("breakpoint:", breakpoint) + self.assertTrue(breakpoint and + breakpoint.GetNumLocations() > 1, + VALID_BREAKPOINT) + + # Now 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) + + import lldbsuite.test.lldbutil as lldbutil + stack_traces1 = lldbutil.print_stacktraces(process, string_buffer=True) + if self.TraceOn(): + print( + "Full stack traces when first stopped on the breakpoint 'inner_inline':") + print(stack_traces1) + + # The first breakpoint should correspond to an inlined call frame. + # If it's an inlined call frame, expect to find, in the stack trace, + # that there is a frame which corresponds to the following call site: + # + # outer_inline (argc); + # + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertIsNotNone(thread) + + frame0 = thread.GetFrameAtIndex(0) + if frame0.IsInlined(): + filename = frame0.GetLineEntry().GetFileSpec().GetFilename() + self.assertTrue(filename == self.source) + self.expect( + stack_traces1, "First stop at %s:%d" % + (self.source, self.first_stop), exe=False, substrs=[ + '%s:%d' % + (self.source, self.first_stop)]) + + # Expect to break again for the second time. + process.Continue() + self.assertTrue(process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + stack_traces2 = lldbutil.print_stacktraces( + process, string_buffer=True) + if self.TraceOn(): + print( + "Full stack traces when stopped on the breakpoint 'inner_inline' for the second time:") + print(stack_traces2) + self.expect( + stack_traces2, "Second stop at %s:%d" % + (self.source, self.second_stop), exe=False, substrs=[ + '%s:%d' % + (self.source, self.second_stop)]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/inlines/inlines.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/inlines/inlines.c new file mode 100644 index 00000000000..a2a8212278d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/inlines/inlines.c @@ -0,0 +1,53 @@ +#include <stdio.h> +#include "inlines.h" + +#define INLINE_ME __inline__ __attribute__((always_inline)) + +int +not_inlined_2 (int input) +{ + printf ("Called in not_inlined_2 with : %d.\n", input); + return input; +} + +int +not_inlined_1 (int input) +{ + printf ("Called in not_inlined_1 with %d.\n", input); + return not_inlined_2(input); +} + +INLINE_ME int +inner_inline (int inner_input, int mod_value) +{ + int inner_result; + inner_result = inner_input % mod_value; + printf ("Returning: %d.\n", inner_result); + return not_inlined_1 (inner_result); +} + +INLINE_ME int +outer_inline (int outer_input) +{ + int outer_result; + + outer_result = inner_inline (outer_input, outer_input % 3); + return outer_result; +} + +int +main (int argc, char **argv) +{ + printf ("Starting...\n"); + + int (*func_ptr) (int); + func_ptr = outer_inline; + + outer_inline (argc); // This should correspond to the first break stop. + + func_ptr (argc); // This should correspond to the second break stop. + + return 0; +} + + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/inlines/inlines.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/inlines/inlines.h new file mode 100644 index 00000000000..265d7b4966e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/inlines/inlines.h @@ -0,0 +1,4 @@ +int inner_inline (int inner_input, int mod_value); +int outer_inline (int outer_input); +int not_inlined_2 (int input); +int not_inlined_1 (int input); diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/main.c new file mode 100644 index 00000000000..75f4448758b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/frame/main.c @@ -0,0 +1,57 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +// This simple program is to test the lldb Python API related to frames. + +int a(int, char); +int b(int, char); +int c(int, char); + +int a(int val, char ch) +{ + int my_val = val; + char my_ch = ch; + printf("a(val=%d, ch='%c')\n", val, ch); + if (val <= 1) + return b(val+1, ch+1); + else if (val >= 3) + return c(val+1, ch+1); + + return val; +} + +int b(int val, char ch) +{ + int my_val = val; + char my_ch = ch; + printf("b(val=%d, ch='%c')\n", val, ch); + return c(val+1, ch+1); +} + +int c(int val, char ch) +{ + int my_val = val; + char my_ch = ch; + printf("c(val=%d, ch='%c')\n", val, ch); + return val + 3 + ch; +} + +int main (int argc, char const *argv[]) +{ + int A1 = a(1, 'A'); // a(1, 'A') -> b(2, 'B') -> c(3, 'C') + printf("a(1, 'A') returns %d\n", A1); + + int B2 = b(2, 'B'); // b(2, 'B') -> c(3, 'C') + printf("b(2, 'B') returns %d\n", B2); + + int A3 = a(3, 'A'); // a(3, 'A') -> c(4, 'B') + printf("a(3, 'A') returns %d\n", A3); + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/function_symbol/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/function_symbol/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/function_symbol/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/function_symbol/TestDisasmAPI.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/function_symbol/TestDisasmAPI.py new file mode 100644 index 00000000000..2278d69fbbe --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/function_symbol/TestDisasmAPI.py @@ -0,0 +1,123 @@ +""" +Test retrieval of SBAddress from function/symbol, disassembly, and SBAddress APIs. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class DisasmAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + 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 for breakpoint 1 here.') + self.line2 = line_number( + 'main.c', '// Find the line number for breakpoint 2 here.') + + @add_test_categories(['pyapi']) + @expectedFailureAll(oslist=["windows"], bugnumber='llvm.org/pr21765') + def test(self): + """Exercise getting SBAddress objects, disassembly, and SBAddress APIs.""" + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Now create the two breakpoints inside function 'a'. + breakpoint1 = target.BreakpointCreateByLocation('main.c', self.line1) + breakpoint2 = target.BreakpointCreateByLocation('main.c', self.line2) + #print("breakpoint1:", breakpoint1) + #print("breakpoint2:", breakpoint2) + self.assertTrue(breakpoint1 and + breakpoint1.GetNumLocations() == 1, + VALID_BREAKPOINT) + self.assertTrue(breakpoint2 and + breakpoint2.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. + self.assertTrue(process.GetState() == lldb.eStateStopped) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint condition") + frame0 = thread.GetFrameAtIndex(0) + lineEntry = frame0.GetLineEntry() + self.assertTrue(lineEntry.GetLine() == self.line1) + + address1 = lineEntry.GetStartAddress() + #print("address1:", address1) + + # Now call SBTarget.ResolveSymbolContextForAddress() with address1. + context1 = target.ResolveSymbolContextForAddress( + address1, lldb.eSymbolContextEverything) + + self.assertTrue(context1) + if self.TraceOn(): + print("context1:", context1) + + # Continue the inferior, the breakpoint 2 should be hit. + process.Continue() + self.assertTrue(process.GetState() == lldb.eStateStopped) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint condition") + frame0 = thread.GetFrameAtIndex(0) + lineEntry = frame0.GetLineEntry() + self.assertTrue(lineEntry.GetLine() == self.line2) + + # Verify that the symbol and the function has the same address range + # per function 'a'. + symbol = context1.GetSymbol() + function = frame0.GetFunction() + self.assertTrue(symbol and function) + + disasm_output = lldbutil.disassemble(target, symbol) + if self.TraceOn(): + print("symbol:", symbol) + print("disassembly=>\n", disasm_output) + + disasm_output = lldbutil.disassemble(target, function) + if self.TraceOn(): + print("function:", function) + print("disassembly=>\n", disasm_output) + + sa1 = symbol.GetStartAddress() + #print("sa1:", sa1) + #print("sa1.GetFileAddress():", hex(sa1.GetFileAddress())) + #ea1 = symbol.GetEndAddress() + #print("ea1:", ea1) + sa2 = function.GetStartAddress() + #print("sa2:", sa2) + #print("sa2.GetFileAddress():", hex(sa2.GetFileAddress())) + #ea2 = function.GetEndAddress() + #print("ea2:", ea2) + self.assertTrue(sa1 and sa2 and sa1 == sa2, + "The two starting addresses should be the same") + + from lldbsuite.test.lldbutil import get_description + desc1 = get_description(sa1) + desc2 = get_description(sa2) + self.assertTrue( + desc1 and desc2 and desc1 == desc2, + "SBAddress.GetDescription() API of sa1 and sa2 should return the same string") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/function_symbol/TestSymbolAPI.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/function_symbol/TestSymbolAPI.py new file mode 100644 index 00000000000..56fa73c84ad --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/function_symbol/TestSymbolAPI.py @@ -0,0 +1,92 @@ +""" +Test newly added SBSymbol and SBAddress APIs. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class SymbolAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + 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 for breakpoint 1 here.') + self.line2 = line_number( + 'main.c', '// Find the line number for breakpoint 2 here.') + + @add_test_categories(['pyapi']) + @expectedFailureAll(oslist=["windows"], bugnumber='llvm.org/pr21765') + def test(self): + """Exercise some SBSymbol and SBAddress APIs.""" + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Now create the two breakpoints inside function 'a'. + breakpoint1 = target.BreakpointCreateByLocation('main.c', self.line1) + breakpoint2 = target.BreakpointCreateByLocation('main.c', self.line2) + #print("breakpoint1:", breakpoint1) + #print("breakpoint2:", breakpoint2) + self.assertTrue(breakpoint1 and + breakpoint1.GetNumLocations() == 1, + VALID_BREAKPOINT) + self.assertTrue(breakpoint2 and + breakpoint2.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. + self.assertTrue(process.GetState() == lldb.eStateStopped) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint condition") + frame0 = thread.GetFrameAtIndex(0) + symbol_line1 = frame0.GetSymbol() + # We should have a symbol type of code. + self.assertTrue(symbol_line1.GetType() == lldb.eSymbolTypeCode) + addr_line1 = symbol_line1.GetStartAddress() + # And a section type of code, too. + self.assertTrue(addr_line1.GetSection().GetSectionType() + == lldb.eSectionTypeCode) + + # Continue the inferior, the breakpoint 2 should be hit. + process.Continue() + self.assertTrue(process.GetState() == lldb.eStateStopped) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint condition") + frame0 = thread.GetFrameAtIndex(0) + symbol_line2 = frame0.GetSymbol() + # We should have a symbol type of code. + self.assertTrue(symbol_line2.GetType() == lldb.eSymbolTypeCode) + addr_line2 = symbol_line2.GetStartAddress() + # And a section type of code, too. + self.assertTrue(addr_line2.GetSection().GetSectionType() + == lldb.eSectionTypeCode) + + # Now verify that both addresses point to the same module. + if self.TraceOn(): + print("UUID:", addr_line1.GetModule().GetUUIDString()) + self.assertTrue(addr_line1.GetModule().GetUUIDString() + == addr_line2.GetModule().GetUUIDString()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/function_symbol/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/function_symbol/main.c new file mode 100644 index 00000000000..33eea200bc4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/function_symbol/main.c @@ -0,0 +1,59 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +// This simple program is to test the lldb Python APIs SBTarget, SBFrame, +// SBFunction, SBSymbol, and SBAddress. +// +// When stopped on breakppint 1, we can get the line entry using SBFrame API +// SBFrame.GetLineEntry(). We'll get the start address for the line entry +// with the SBAddress type, resolve the symbol context using the SBTarget API +// SBTarget.ResolveSymbolContextForAddress() in order to get the SBSymbol. +// +// We then stop at breakpoint 2, get the SBFrame, and the SBFunction object. +// +// The address from calling GetStartAddress() on the symbol and the function +// should point to the same address, and we also verify that. + +int a(int); +int b(int); +int c(int); + +int a(int val) +{ + if (val <= 1) // Find the line number for breakpoint 1 here. + val = b(val); + else if (val >= 3) + val = c(val); + + return val; // Find the line number for breakpoint 2 here. +} + +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/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/get-value-32bit-int/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/get-value-32bit-int/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/get-value-32bit-int/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/get-value-32bit-int/TestGetValue32BitInt.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/get-value-32bit-int/TestGetValue32BitInt.py new file mode 100644 index 00000000000..025226471bd --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/get-value-32bit-int/TestGetValue32BitInt.py @@ -0,0 +1,19 @@ +""" +Check that SBValue.GetValueAsSigned() does the right thing for a 32-bit -1. +""" + +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class TestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def test_with_run_command(self): + self.build() + lldbutil.run_to_source_breakpoint(self,"// break here", lldb.SBFileSpec("main.cpp")) + + self.assertEqual(self.frame().FindVariable("myvar").GetValueAsSigned(), -1) + self.assertEqual(self.frame().FindVariable("myvar").GetValueAsUnsigned(), 0xFFFFFFFF) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/get-value-32bit-int/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/get-value-32bit-int/main.cpp new file mode 100644 index 00000000000..61f40fb2a78 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/get-value-32bit-int/main.cpp @@ -0,0 +1,5 @@ +#include <cstdint> +int main () { + int32_t myvar = -1; + return myvar; // break here +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/hello_world/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/hello_world/Makefile new file mode 100644 index 00000000000..73625f4733f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/hello_world/Makefile @@ -0,0 +1,5 @@ +C_SOURCES := main.c +# See TestHelloWorld.py, which specifies the executable name with a dictionary. +EXE := hello_world + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/hello_world/TestHelloWorld.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/hello_world/TestHelloWorld.py new file mode 100644 index 00000000000..fc6ef4882a0 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/hello_world/TestHelloWorld.py @@ -0,0 +1,155 @@ +"""Test Python APIs for target (launch and attach), breakpoint, and process.""" + + + +import os + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class HelloWorldTestCase(TestBase): + NO_DEBUG_INFO_TESTCASE = True + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find a couple of the line numbers within main.c. + self.line1 = line_number('main.c', '// Set break point at this line.') + self.line2 = line_number('main.c', '// Waiting to be attached...') + + def tearDown(self): + # Destroy process before TestBase.tearDown() + self.dbg.GetSelectedTarget().GetProcess().Destroy() + # Call super's tearDown(). + TestBase.tearDown(self) + + @add_test_categories(['pyapi']) + @skipIfiOSSimulator + def test_with_process_launch_api(self): + """Create target, breakpoint, launch a process, and then kill it.""" + # Get the full path to our executable to be attached/debugged. + exe = '%s_%d'%(self.getBuildArtifact(self.testMethodName), os.getpid()) + d = {'EXE': exe} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + target = self.dbg.CreateTarget(exe) + + breakpoint = target.BreakpointCreateByLocation("main.c", self.line1) + + # The default state after breakpoint creation should be enabled. + self.assertTrue(breakpoint.IsEnabled(), + "Breakpoint should be enabled after creation") + + breakpoint.SetEnabled(False) + self.assertTrue(not breakpoint.IsEnabled(), + "Breakpoint.SetEnabled(False) works") + + breakpoint.SetEnabled(True) + self.assertTrue(breakpoint.IsEnabled(), + "Breakpoint.SetEnabled(True) works") + + # rdar://problem/8364687 + # SBTarget.Launch() issue (or is there some race condition)? + + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + # The following isn't needed anymore, rdar://8364687 is fixed. + # + # Apply some dances after LaunchProcess() in order to break at "main". + # It only works sometimes. + #self.breakAfterLaunch(process, "main") + + process = target.GetProcess() + self.assertTrue(process, PROCESS_IS_VALID) + + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertIsNotNone(thread) + + # The breakpoint should have a hit count of 1. + self.assertEqual(breakpoint.GetHitCount(), 1, BREAKPOINT_HIT_ONCE) + + @add_test_categories(['pyapi']) + @skipIfiOSSimulator + @expectedFailureNetBSD + def test_with_attach_to_process_with_id_api(self): + """Create target, spawn a process, and attach to it with process id.""" + exe = '%s_%d'%(self.testMethodName, os.getpid()) + d = {'EXE': exe} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + target = self.dbg.CreateTarget(self.getBuildArtifact(exe)) + + # Spawn a new process + token = exe+'.token' + if not lldb.remote_platform: + token = self.getBuildArtifact(token) + if os.path.exists(token): + os.remove(token) + popen = self.spawnSubprocess(self.getBuildArtifact(exe), [token]) + self.addTearDownHook(self.cleanupSubprocesses) + lldbutil.wait_for_file_on_target(self, token) + + listener = lldb.SBListener("my.attach.listener") + error = lldb.SBError() + process = target.AttachToProcessWithID(listener, popen.pid, error) + + self.assertTrue(error.Success() and process, PROCESS_IS_VALID) + + # Let's check the stack traces of the attached process. + stacktraces = lldbutil.print_stacktraces(process, string_buffer=True) + self.expect(stacktraces, exe=False, + substrs=['main.c:%d' % self.line2, + '(int)argc=2']) + + @add_test_categories(['pyapi']) + @skipIfiOSSimulator + @skipIfAsan # FIXME: Hangs indefinitely. + @expectedFailureNetBSD + def test_with_attach_to_process_with_name_api(self): + """Create target, spawn a process, and attach to it with process name.""" + exe = '%s_%d'%(self.testMethodName, os.getpid()) + d = {'EXE': exe} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + target = self.dbg.CreateTarget(self.getBuildArtifact(exe)) + + # Spawn a new process. + token = exe+'.token' + if not lldb.remote_platform: + token = self.getBuildArtifact(token) + if os.path.exists(token): + os.remove(token) + popen = self.spawnSubprocess(self.getBuildArtifact(exe), [token]) + self.addTearDownHook(self.cleanupSubprocesses) + lldbutil.wait_for_file_on_target(self, token) + + listener = lldb.SBListener("my.attach.listener") + error = lldb.SBError() + # Pass 'False' since we don't want to wait for new instance of + # "hello_world" to be launched. + name = os.path.basename(exe) + + # While we're at it, make sure that passing a None as the process name + # does not hang LLDB. + target.AttachToProcessWithName(listener, None, False, error) + # Also boundary condition test ConnectRemote(), too. + target.ConnectRemote(listener, None, None, error) + + process = target.AttachToProcessWithName(listener, name, False, error) + self.assertTrue(error.Success() and process, PROCESS_IS_VALID) + + # Verify that after attach, our selected target indeed matches name. + self.expect( + self.dbg.GetSelectedTarget().GetExecutable().GetFilename(), + exe=False, + startstr=name) + + # Let's check the stack traces of the attached process. + stacktraces = lldbutil.print_stacktraces(process, string_buffer=True) + self.expect(stacktraces, exe=False, + substrs=['main.c:%d' % self.line2, + '(int)argc=2']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/hello_world/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/hello_world/main.c new file mode 100644 index 00000000000..c516f923614 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/hello_world/main.c @@ -0,0 +1,29 @@ +#include <stdio.h> +#ifdef _MSC_VER +#include <windows.h> +#define sleep(x) Sleep((x) * 1000) +#else +#include <unistd.h> +#endif + +int main(int argc, char const *argv[]) +{ + lldb_enable_attach(); + + printf("Hello world.\n"); // Set break point at this line. + if (argc == 1) + return 1; + + // Create the synchronization token. + FILE *f; + if (f = fopen(argv[1], "wx")) { + fputs("\n", f); + fflush(f); + fclose(f); + } else + return 1; + + // Waiting to be attached by the debugger, otherwise. + while (1) + sleep(1); // Waiting to be attached... +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/interpreter/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/interpreter/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/interpreter/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/interpreter/TestCommandInterpreterAPI.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/interpreter/TestCommandInterpreterAPI.py new file mode 100644 index 00000000000..a920ce845b8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/interpreter/TestCommandInterpreterAPI.py @@ -0,0 +1,91 @@ +"""Test the SBCommandInterpreter APIs.""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class CommandInterpreterAPICase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + 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.') + + @add_test_categories(['pyapi']) + def test_with_process_launch_api(self): + """Test the SBCommandInterpreter APIs.""" + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Retrieve the associated command interpreter from our debugger. + ci = self.dbg.GetCommandInterpreter() + self.assertTrue(ci, VALID_COMMAND_INTERPRETER) + + # Exercise some APIs.... + + self.assertTrue(ci.HasCommands()) + self.assertTrue(ci.HasAliases()) + self.assertTrue(ci.HasAliasOptions()) + self.assertTrue(ci.CommandExists("breakpoint")) + self.assertTrue(ci.CommandExists("target")) + self.assertTrue(ci.CommandExists("platform")) + self.assertTrue(ci.AliasExists("file")) + self.assertTrue(ci.AliasExists("run")) + self.assertTrue(ci.AliasExists("bt")) + + res = lldb.SBCommandReturnObject() + ci.HandleCommand("breakpoint set -f main.c -l %d" % self.line, res) + self.assertTrue(res.Succeeded()) + ci.HandleCommand("process launch", res) + self.assertTrue(res.Succeeded()) + + # Boundary conditions should not crash lldb! + self.assertFalse(ci.CommandExists(None)) + self.assertFalse(ci.AliasExists(None)) + ci.HandleCommand(None, res) + self.assertFalse(res.Succeeded()) + res.AppendMessage("Just appended a message.") + res.AppendMessage(None) + if self.TraceOn(): + print(res) + + process = ci.GetProcess() + self.assertTrue(process) + + import lldbsuite.test.lldbutil as lldbutil + 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())) + + if self.TraceOn(): + lldbutil.print_stacktraces(process) + + @add_test_categories(['pyapi']) + def test_command_output(self): + """Test command output handling.""" + ci = self.dbg.GetCommandInterpreter() + self.assertTrue(ci, VALID_COMMAND_INTERPRETER) + + # Test that a command which produces no output returns "" instead of + # None. + res = lldb.SBCommandReturnObject() + ci.HandleCommand("settings set use-color false", res) + self.assertTrue(res.Succeeded()) + self.assertIsNotNone(res.GetOutput()) + self.assertEquals(res.GetOutput(), "") + self.assertIsNotNone(res.GetError()) + self.assertEquals(res.GetError(), "") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/interpreter/TestRunCommandInterpreterAPI.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/interpreter/TestRunCommandInterpreterAPI.py new file mode 100644 index 00000000000..a32805bf859 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/interpreter/TestRunCommandInterpreterAPI.py @@ -0,0 +1,75 @@ +"""Test the RunCommandInterpreter API.""" + +import os +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * + +class CommandRunInterpreterLegacyAPICase(TestBase): + + NO_DEBUG_INFO_TESTCASE = True + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + TestBase.setUp(self) + + self.stdin_path = self.getBuildArtifact("stdin.txt") + + with open(self.stdin_path, 'w') as input_handle: + input_handle.write("nonexistingcommand\nquit") + + # Python will close the file descriptor if all references + # to the filehandle object lapse, so we need to keep one + # around. + self.filehandle = open(self.stdin_path, 'r') + self.dbg.SetInputFileHandle(self.filehandle, False) + + # No need to track the output + self.devnull = open(os.devnull, 'w') + self.dbg.SetOutputFileHandle(self.devnull, False) + self.dbg.SetErrorFileHandle (self.devnull, False) + + @add_test_categories(['pyapi']) + def test_run_session_with_error_and_quit_legacy(self): + """Run non-existing and quit command returns appropriate values""" + + n_errors, quit_requested, has_crashed = self.dbg.RunCommandInterpreter( + True, False, lldb.SBCommandInterpreterRunOptions(), 0, False, + False) + + self.assertGreater(n_errors, 0) + self.assertTrue(quit_requested) + self.assertFalse(has_crashed) + + +class CommandRunInterpreterAPICase(TestBase): + + NO_DEBUG_INFO_TESTCASE = True + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + TestBase.setUp(self) + + self.stdin_path = self.getBuildArtifact("stdin.txt") + + with open(self.stdin_path, 'w') as input_handle: + input_handle.write("nonexistingcommand\nquit") + + self.dbg.SetInputFile(open(self.stdin_path, 'r')) + + # No need to track the output + devnull = open(os.devnull, 'w') + self.dbg.SetOutputFile(devnull) + self.dbg.SetErrorFile(devnull) + + @add_test_categories(['pyapi']) + def test_run_session_with_error_and_quit(self): + """Run non-existing and quit command returns appropriate values""" + + n_errors, quit_requested, has_crashed = self.dbg.RunCommandInterpreter( + True, False, lldb.SBCommandInterpreterRunOptions(), 0, False, + False) + + self.assertGreater(n_errors, 0) + self.assertTrue(quit_requested) + self.assertFalse(has_crashed) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/interpreter/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/interpreter/main.c new file mode 100644 index 00000000000..277aa54a4ee --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/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/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/TestSwigVersion.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/TestSwigVersion.py new file mode 100644 index 00000000000..8c5c6efda53 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/TestSwigVersion.py @@ -0,0 +1,27 @@ +""" +Test that we embed the swig version into the lldb module +""" + + +""" +import os +import time +import re +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test import lldbutil +""" +from lldbsuite.test.lldbtest import * + +class SwigVersionTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def test(self): + self.assertTrue(getattr(lldb, "swig_version")) + self.assertIsInstance(lldb.swig_version, tuple) + self.assertEqual(len(lldb.swig_version), 3) + self.assertGreaterEqual(lldb.swig_version[0], 1) + for v in lldb.swig_version: + self.assertGreaterEqual(v, 0) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/frame/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/frame/Makefile new file mode 100644 index 00000000000..c5fa38429c6 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/frame/Makefile @@ -0,0 +1,4 @@ +C_SOURCES := main.c +MAKE_DSYM :=NO + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/frame/TestFrameUtils.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/frame/TestFrameUtils.py new file mode 100644 index 00000000000..ec8d1f84ded --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/frame/TestFrameUtils.py @@ -0,0 +1,63 @@ +""" +Test utility functions for the frame object. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class FrameUtilsTestCase(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', + "// Find the line number here.") + + @add_test_categories(['pyapi']) + def test_frame_utils(self): + """Test utility functions for the frame object.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation("main.c", self.line) + 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()) + + if not process: + self.fail("SBTarget.LaunchProcess() failed") + self.assertTrue(process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + + import lldbsuite.test.lldbutil as lldbutil + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue(thread) + frame0 = thread.GetFrameAtIndex(0) + self.assertTrue(frame0) + frame1 = thread.GetFrameAtIndex(1) + self.assertTrue(frame1) + parent = lldbutil.get_parent_frame(frame0) + self.assertTrue(parent and parent.GetFrameID() == frame1.GetFrameID()) + frame0_args = lldbutil.get_args_as_string(frame0) + parent_args = lldbutil.get_args_as_string(parent) + self.assertTrue( + frame0_args and parent_args and "(int)val=1" in frame0_args) + if self.TraceOn(): + lldbutil.print_stacktrace(thread) + print("Current frame: %s" % frame0_args) + print("Parent frame: %s" % parent_args) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/frame/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/frame/main.c new file mode 100644 index 00000000000..f83709616e5 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/frame/main.c @@ -0,0 +1,46 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.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) +{ + return c(val); +} + +int c(int val) +{ + return val + 3; // Find the line number 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); + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/iter/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/iter/Makefile new file mode 100644 index 00000000000..4d11bbc8b6a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/iter/Makefile @@ -0,0 +1,6 @@ +CFLAGS_EXTRAS := -D__STDC_LIMIT_MACROS +ENABLE_THREADS := YES +CXX_SOURCES := main.cpp +MAKE_DSYM := NO + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/iter/TestLLDBIterator.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/iter/TestLLDBIterator.py new file mode 100644 index 00000000000..050ec87fb2b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/iter/TestLLDBIterator.py @@ -0,0 +1,126 @@ +""" +Test the iteration protocol for some lldb container objects. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class LLDBIteratorTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break inside main(). + self.line1 = line_number( + 'main.cpp', '// Set break point at this line.') + self.line2 = line_number('main.cpp', '// And that line.') + + @add_test_categories(['pyapi']) + def test_lldb_iter_module(self): + """Test module_iter works correctly for SBTarget -> SBModule.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line1) + 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()) + + if not process: + self.fail("SBTarget.LaunchProcess() failed") + + from lldbsuite.test.lldbutil import get_description + yours = [] + for i in range(target.GetNumModules()): + yours.append(target.GetModuleAtIndex(i)) + mine = [] + for m in target.module_iter(): + mine.append(m) + + self.assertTrue(len(yours) == len(mine)) + for i in range(len(yours)): + if self.TraceOn(): + print("yours[%d]='%s'" % (i, get_description(yours[i]))) + print("mine[%d]='%s'" % (i, get_description(mine[i]))) + self.assertTrue( + yours[i] == mine[i], + "UUID+FileSpec of yours[{0}] and mine[{0}] matches".format(i)) + + @add_test_categories(['pyapi']) + def test_lldb_iter_breakpoint(self): + """Test breakpoint_iter works correctly for SBTarget -> SBBreakpoint.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line1) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line2) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + self.assertTrue(target.GetNumBreakpoints() == 2) + + from lldbsuite.test.lldbutil import get_description + yours = [] + for i in range(target.GetNumBreakpoints()): + yours.append(target.GetBreakpointAtIndex(i)) + mine = [] + for b in target.breakpoint_iter(): + mine.append(b) + + self.assertTrue(len(yours) == len(mine)) + for i in range(len(yours)): + if self.TraceOn(): + print("yours[%d]='%s'" % (i, get_description(yours[i]))) + print("mine[%d]='%s'" % (i, get_description(mine[i]))) + self.assertTrue(yours[i] == mine[i], + "ID of yours[{0}] and mine[{0}] matches".format(i)) + + @add_test_categories(['pyapi']) + def test_lldb_iter_frame(self): + """Test iterator works correctly for SBProcess->SBThread->SBFrame.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line1) + 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()) + + if not process: + self.fail("SBTarget.LaunchProcess() failed") + + from lldbsuite.test.lldbutil import print_stacktrace + stopped_due_to_breakpoint = False + for thread in process: + if self.TraceOn(): + print_stacktrace(thread) + ID = thread.GetThreadID() + if thread.GetStopReason() == lldb.eStopReasonBreakpoint: + stopped_due_to_breakpoint = True + for frame in thread: + self.assertTrue(frame.GetThread().GetThreadID() == ID) + if self.TraceOn(): + print(frame) + + self.assertTrue(stopped_due_to_breakpoint) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/iter/TestRegistersIterator.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/iter/TestRegistersIterator.py new file mode 100644 index 00000000000..fbb8bff4128 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/iter/TestRegistersIterator.py @@ -0,0 +1,105 @@ +""" +Test the iteration protocol for frame registers. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class RegistersIteratorTestCase(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.line1 = line_number( + 'main.cpp', '// Set break point at this line.') + + @add_test_categories(['pyapi']) + def test_iter_registers(self): + """Test iterator works correctly for lldbutil.iter_registers().""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line1) + 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()) + + if not process: + self.fail("SBTarget.LaunchProcess() failed") + + import lldbsuite.test.lldbutil as lldbutil + for thread in process: + if thread.GetStopReason() == lldb.eStopReasonBreakpoint: + for frame in thread: + # Dump the registers of this frame using + # lldbutil.get_GPRs() and friends. + if self.TraceOn(): + print(frame) + + REGs = lldbutil.get_GPRs(frame) + num = len(REGs) + if self.TraceOn(): + print( + "\nNumber of general purpose registers: %d" % + num) + for reg in REGs: + self.assertTrue(reg) + if self.TraceOn(): + print("%s => %s" % (reg.GetName(), reg.GetValue())) + + REGs = lldbutil.get_FPRs(frame) + num = len(REGs) + if self.TraceOn(): + print("\nNumber of floating point registers: %d" % num) + for reg in REGs: + self.assertTrue(reg) + if self.TraceOn(): + print("%s => %s" % (reg.GetName(), reg.GetValue())) + + REGs = lldbutil.get_ESRs(frame) + if self.platformIsDarwin(): + if self.getArchitecture() != 'armv7' and self.getArchitecture() != 'armv7k': + num = len(REGs) + if self.TraceOn(): + print( + "\nNumber of exception state registers: %d" % + num) + for reg in REGs: + self.assertTrue(reg) + if self.TraceOn(): + print( + "%s => %s" % + (reg.GetName(), reg.GetValue())) + else: + self.assertIsNone(REGs) + + # And these should also work. + for kind in ["General Purpose Registers", + "Floating Point Registers"]: + REGs = lldbutil.get_registers(frame, kind) + self.assertTrue(REGs) + + REGs = lldbutil.get_registers( + frame, "Exception State Registers") + if self.platformIsDarwin(): + if self.getArchitecture() != 'armv7' and self.getArchitecture() != 'armv7k': + self.assertIsNotNone(REGs) + else: + self.assertIsNone(REGs) + + # We've finished dumping the registers for frame #0. + break diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/iter/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/iter/main.cpp new file mode 100644 index 00000000000..6823ccc4eb8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/iter/main.cpp @@ -0,0 +1,133 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// C includes +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> + +// C++ includes +#include <chrono> +#include <mutex> +#include <random> +#include <thread> + +std::thread g_thread_1; +std::thread g_thread_2; +std::thread g_thread_3; +std::mutex g_mask_mutex; + +enum MaskAction { + eGet, + eAssign, + eClearBits +}; + +uint32_t mask_access (MaskAction action, uint32_t mask = 0); + +uint32_t +mask_access (MaskAction action, uint32_t mask) +{ + static uint32_t g_mask = 0; + + std::lock_guard<std::mutex> lock(g_mask_mutex); + switch (action) + { + case eGet: + break; + + case eAssign: + g_mask |= mask; + break; + + case eClearBits: + g_mask &= ~mask; + break; + } + return g_mask; +} + +void * +thread_func (void *arg) +{ + uint32_t thread_index = *((uint32_t *)arg); + uint32_t thread_mask = (1u << (thread_index)); + printf ("%s (thread index = %u) startng...\n", __FUNCTION__, thread_index); + + std::default_random_engine generator; + std::uniform_int_distribution<int> distribution(0, 3000000); + + while (mask_access(eGet) & thread_mask) + { + // random micro second sleep from zero to 3 seconds + int usec = distribution(generator); + printf ("%s (thread = %u) doing a usleep (%d)...\n", __FUNCTION__, thread_index, usec); + + std::chrono::microseconds duration(usec); + std::this_thread::sleep_for(duration); + printf ("%s (thread = %u) after usleep ...\n", __FUNCTION__, thread_index); // Set break point at this line. + } + printf ("%s (thread index = %u) exiting...\n", __FUNCTION__, thread_index); + return NULL; +} + + +int main (int argc, char const *argv[]) +{ + uint32_t thread_index_1 = 1; + uint32_t thread_index_2 = 2; + uint32_t thread_index_3 = 3; + uint32_t thread_mask_1 = (1u << thread_index_1); + uint32_t thread_mask_2 = (1u << thread_index_2); + uint32_t thread_mask_3 = (1u << thread_index_3); + + // Make a mask that will keep all threads alive + mask_access (eAssign, thread_mask_1 | thread_mask_2 | thread_mask_3); // And that line. + + // Create 3 threads + g_thread_1 = std::thread(thread_func, (void*)&thread_index_1); + g_thread_2 = std::thread(thread_func, (void*)&thread_index_2); + g_thread_3 = std::thread(thread_func, (void*)&thread_index_3); + + char line[64]; + while (mask_access(eGet) != 0) + { + printf ("Enter thread index to kill or ENTER for all:\n"); + fflush (stdout); + // Kill threads by index, or ENTER for all threads + + if (fgets (line, sizeof(line), stdin)) + { + if (line[0] == '\n' || line[0] == '\r' || line[0] == '\0') + { + printf ("Exiting all threads...\n"); + break; + } + int32_t index = strtoul (line, NULL, 0); + switch (index) + { + case 1: mask_access (eClearBits, thread_mask_1); break; + case 2: mask_access (eClearBits, thread_mask_2); break; + case 3: mask_access (eClearBits, thread_mask_3); break; + } + continue; + } + + break; + } + + // Clear all thread bits to they all exit + mask_access (eClearBits, UINT32_MAX); + + // Join all of our threads + g_thread_1.join(); + g_thread_2.join(); + g_thread_3.join(); + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/process/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/process/Makefile new file mode 100644 index 00000000000..6b33049a78b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/process/Makefile @@ -0,0 +1,6 @@ +CFLAGS_EXTRAS := -D__STDC_LIMIT_MACROS +ENABLE_THREADS := YES +CXX_SOURCES := main.cpp +MAKE_DSYM :=NO + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/process/TestPrintStackTraces.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/process/TestPrintStackTraces.py new file mode 100644 index 00000000000..123b60e4cd7 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/process/TestPrintStackTraces.py @@ -0,0 +1,25 @@ +""" +Test SBprocess and SBThread APIs with printing of the stack traces using lldbutil. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ThreadsStackTracesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @add_test_categories(['pyapi']) + def test_stack_traces(self): + """Test SBprocess and SBThread APIs with printing of the stack traces.""" + self.build() + (_, process, _, _) = lldbutil.run_to_source_breakpoint(self, + "// BREAK HERE", lldb.SBFileSpec("main.cpp")) + stacktraces = lldbutil.print_stacktraces(process, string_buffer=True) + self.expect(stacktraces, exe=False, + substrs=['(int)x=4', '(int)y=6', '(int)x=3', '(int)argc=1']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/process/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/process/main.cpp new file mode 100644 index 00000000000..a490d8f9900 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/lldbutil/process/main.cpp @@ -0,0 +1,20 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +static int foo(int x, int y) { + return x + y; // BREAK HERE +} + +static int bar(int x) { + return foo(x + 1, x * 2); +} + +int main (int argc, char const *argv[]) +{ + return bar(argc + 2); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/module_section/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/module_section/Makefile new file mode 100644 index 00000000000..79209db9696 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/module_section/Makefile @@ -0,0 +1,6 @@ +CFLAGS_EXTRAS := -D__STDC_LIMIT_MACROS +ENABLE_THREADS := YES +CXX_SOURCES := main.cpp b.cpp c.cpp +MAKE_DSYM :=NO + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/module_section/TestModuleAndSection.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/module_section/TestModuleAndSection.py new file mode 100644 index 00000000000..95d457697e7 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/module_section/TestModuleAndSection.py @@ -0,0 +1,167 @@ +""" +Test some SBModule and SBSection APIs. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil +from lldbsuite.test.lldbutil import symbol_type_to_str + + +class ModuleAndSectionAPIsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + # Py3 asserts due to a bug in SWIG. A fix for this was upstreamed into + # SWIG 3.0.8. + @skipIf(py_version=['>=', (3, 0)], swig_version=['<', (3, 0, 8)]) + @add_test_categories(['pyapi']) + def test_module_and_section(self): + """Test module and section APIs.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + self.assertTrue(target.GetNumModules() > 0) + + # Hide stdout if not running with '-t' option. + if not self.TraceOn(): + self.HideStdout() + + print("Number of modules for the target: %d" % target.GetNumModules()) + for module in target.module_iter(): + print(module) + + # Get the executable module at index 0. + exe_module = target.GetModuleAtIndex(0) + + print("Exe module: %s" % str(exe_module)) + print("Number of sections: %d" % exe_module.GetNumSections()) + print("Number of symbols: %d" % len(exe_module)) + INDENT = ' ' * 4 + INDENT2 = INDENT * 2 + for sec in exe_module.section_iter(): + print(sec) + print( + INDENT + + "Number of subsections: %d" % + sec.GetNumSubSections()) + if sec.GetNumSubSections() == 0: + for sym in exe_module.symbol_in_section_iter(sec): + print(INDENT + str(sym)) + print( + INDENT + + "symbol type: %s" % + symbol_type_to_str( + sym.GetType())) + else: + for subsec in sec: + print(INDENT + str(subsec)) + # Now print the symbols belonging to the subsection.... + for sym in exe_module.symbol_in_section_iter(subsec): + print(INDENT2 + str(sym)) + print( + INDENT2 + + "symbol type: %s" % + symbol_type_to_str( + sym.GetType())) + + @add_test_categories(['pyapi']) + def test_module_and_section_boundary_condition(self): + """Test module and section APIs by passing None when it expects a Python string.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + self.assertTrue(target.GetNumModules() > 0) + + # Hide stdout if not running with '-t' option. + if not self.TraceOn(): + self.HideStdout() + + print("Number of modules for the target: %d" % target.GetNumModules()) + for module in target.module_iter(): + print(module) + + # Get the executable module at index 0. + exe_module = target.GetModuleAtIndex(0) + + print("Exe module: %s" % str(exe_module)) + print("Number of sections: %d" % exe_module.GetNumSections()) + + # Boundary condition testings. Should not crash lldb! + exe_module.FindFirstType(None) + exe_module.FindTypes(None) + exe_module.FindGlobalVariables(target, None, 1) + exe_module.FindFunctions(None, 0) + exe_module.FindSection(None) + + # Get the section at index 1. + if exe_module.GetNumSections() > 1: + sec1 = exe_module.GetSectionAtIndex(1) + print(sec1) + else: + sec1 = None + + if sec1: + sec1.FindSubSection(None) + + @add_test_categories(['pyapi']) + def test_module_compile_unit_iter(self): + """Test module's compile unit iterator APIs.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + self.assertTrue(target.GetNumModules() > 0) + + # Hide stdout if not running with '-t' option. + if not self.TraceOn(): + self.HideStdout() + + print("Number of modules for the target: %d" % target.GetNumModules()) + for module in target.module_iter(): + print(module) + + # Get the executable module at index 0. + exe_module = target.GetModuleAtIndex(0) + + print("Exe module: %s" % str(exe_module)) + print("Number of compile units: %d" % exe_module.GetNumCompileUnits()) + INDENT = ' ' * 4 + INDENT2 = INDENT * 2 + for cu in exe_module.compile_unit_iter(): + print(cu) + + @add_test_categories(['pyapi']) + def test_find_compile_units(self): + """Exercise SBModule.FindCompileUnits() API.""" + d = {'EXE': 'b.out'} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + self.find_compile_units(self.getBuildArtifact('b.out')) + + def find_compile_units(self, exe): + """Exercise SBModule.FindCompileUnits() API.""" + source_name_list = ["main.cpp", "b.cpp", "c.cpp"] + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + num_modules = target.GetNumModules() + for i in range(num_modules): + module = target.GetModuleAtIndex(i) + for source_name in source_name_list: + list = module.FindCompileUnits(lldb.SBFileSpec(source_name, False)) + for sc in list: + self.assertTrue( + sc.GetCompileUnit().GetFileSpec().GetFilename() == + source_name) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/module_section/b.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/module_section/b.cpp new file mode 100644 index 00000000000..4e3e54138e5 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/module_section/b.cpp @@ -0,0 +1,3 @@ +int b_function(int input) { + return input * 2; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/module_section/c.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/module_section/c.cpp new file mode 100644 index 00000000000..3c87bfe30c6 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/module_section/c.cpp @@ -0,0 +1,3 @@ +int c_function(int input) { + return input * 3; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/module_section/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/module_section/main.cpp new file mode 100644 index 00000000000..943123b4059 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/module_section/main.cpp @@ -0,0 +1,5 @@ +#include <stdio.h> + +int main() { + printf("Hello World\n"); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/name_lookup/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/name_lookup/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/name_lookup/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/name_lookup/TestNameLookup.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/name_lookup/TestNameLookup.py new file mode 100644 index 00000000000..6cd8d4fa9c4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/name_lookup/TestNameLookup.py @@ -0,0 +1,63 @@ +""" +Test SBTarget APIs. +""" + + + +import unittest2 +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestNameLookup(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @add_test_categories(['pyapi']) + @expectedFailureAll(oslist=["windows"], bugnumber='llvm.org/pr21765') + def test_target(self): + """Exercise SBTarget.FindFunctions() with various name masks. + + A previous regression caused mangled names to not be able to be looked up. + This test verifies that using a mangled name with eFunctionNameTypeFull works + and that using a function basename with eFunctionNameTypeFull works for all + C++ functions that are at the global namespace level.""" + self.build(); + exe = self.getBuildArtifact("a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + exe_module = target.FindModule(target.GetExecutable()) + + c_name_to_symbol = {} + cpp_name_to_symbol = {} + mangled_to_symbol = {} + num_symbols = exe_module.GetNumSymbols(); + for i in range(num_symbols): + symbol = exe_module.GetSymbolAtIndex(i); + name = symbol.GetName() + if name and 'unique_function_name' in name and '__PRETTY_FUNCTION__' not in name: + mangled = symbol.GetMangledName() + if mangled: + mangled_to_symbol[mangled] = symbol + if name: + cpp_name_to_symbol[name] = symbol + elif name: + c_name_to_symbol[name] = symbol + + # Make sure each mangled name turns up exactly one match when looking up + # functions by full name and using the mangled name as the name in the + # lookup + self.assertGreaterEqual(len(mangled_to_symbol), 6) + for mangled in mangled_to_symbol.keys(): + symbol_contexts = target.FindFunctions(mangled, lldb.eFunctionNameTypeFull) + self.assertTrue(symbol_contexts.GetSize() == 1) + for symbol_context in symbol_contexts: + self.assertTrue(symbol_context.GetFunction().IsValid()) + self.assertTrue(symbol_context.GetSymbol().IsValid()) + + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/name_lookup/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/name_lookup/main.cpp new file mode 100644 index 00000000000..b38208ce2a3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/name_lookup/main.cpp @@ -0,0 +1,54 @@ +#include <stdio.h> + +extern "C" int unique_function_name(int i) +{ + return puts(__PRETTY_FUNCTION__); +} + +int unique_function_name() +{ + return puts(__PRETTY_FUNCTION__); +} + +int unique_function_name(float f) +{ + return puts(__PRETTY_FUNCTION__); +} + +namespace e +{ + int unique_function_name() + { + return puts(__PRETTY_FUNCTION__); + } + + namespace g + { + int unique_function_name() + { + return puts(__PRETTY_FUNCTION__); + } + } +} + +class g +{ +public: + int unique_function_name() + { + return puts(__PRETTY_FUNCTION__); + } + + int unique_function_name(int i) + { + return puts(__PRETTY_FUNCTION__); + } +}; + +int main (int argc, char const *argv[]) +{ + g g; + g.unique_function_name(); + g.unique_function_name(argc); + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/objc_type/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/objc_type/Makefile new file mode 100644 index 00000000000..8b322ff320b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/objc_type/Makefile @@ -0,0 +1,8 @@ +OBJC_SOURCES := main.m + +CFLAGS_EXTRAS := -w + + + +LD_EXTRAS := -framework Foundation +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/objc_type/TestObjCType.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/objc_type/TestObjCType.py new file mode 100644 index 00000000000..37f53758d44 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/objc_type/TestObjCType.py @@ -0,0 +1,70 @@ +""" +Test SBType for ObjC classes. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ObjCSBTypeTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + self.line = line_number("main.m", '// Break at this line') + + @skipUnlessDarwin + @add_test_categories(['pyapi']) + def test(self): + """Test SBType for ObjC classes.""" + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Create the breakpoint inside function 'main'. + breakpoint = target.BreakpointCreateByLocation("main.m", self.line) + 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) + + # Get Frame #0. + self.assertTrue(process.GetState() == lldb.eStateStopped) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint condition") + + aBar = self.frame().FindVariable("aBar") + aBarType = aBar.GetType() + self.assertTrue(aBarType.IsValid(), "Bar should be a valid data type") + self.assertTrue( + aBarType.GetName() == "Bar *", + "Bar has the right name") + + self.assertTrue( + aBarType.GetNumberOfDirectBaseClasses() == 1, + "Bar has a superclass") + aFooType = aBarType.GetDirectBaseClassAtIndex(0) + + self.assertTrue(aFooType.IsValid(), "Foo should be a valid data type") + self.assertTrue(aFooType.GetName() == "Foo", "Foo has the right name") + + self.assertTrue(aBarType.GetNumberOfFields() == 1, "Bar has a field") + aBarField = aBarType.GetFieldAtIndex(0) + + self.assertTrue( + aBarField.GetName() == "_iVar", + "The field has the right name") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/objc_type/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/objc_type/main.m new file mode 100644 index 00000000000..a2a7b0b4bce --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/objc_type/main.m @@ -0,0 +1,51 @@ +//===-- main.m ------------------------------------------------*- ObjC -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#import <Foundation/Foundation.h> + +@interface Foo: NSObject +{} +- (id) init; +@end + +@interface Bar: Foo +{ + int _iVar; +} +- (id) init; +@end + +@implementation Foo + +- (id) init +{ + self = [super init]; + return self; +} + +@end + +@implementation Bar + +- (id) init +{ + self = [super init]; + if (self) + self->_iVar = 5; + return self; +} + +@end + +int main() +{ + Bar* aBar = [Bar new]; + id nothing = [aBar noSuchSelector]; // Break at this line + return 0; +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/TestProcessAPI.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/TestProcessAPI.py new file mode 100644 index 00000000000..d26933a4289 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/TestProcessAPI.py @@ -0,0 +1,401 @@ +""" +Test SBProcess APIs, including ReadMemory(), WriteMemory(), and others. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test.lldbutil import get_stopped_thread, state_type_to_str + + +class ProcessAPITestCase(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 and check variable 'my_char'.") + + @add_test_categories(['pyapi']) + def test_read_memory(self): + """Test Python SBProcess.ReadMemory() API.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + # Launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint") + frame = thread.GetFrameAtIndex(0) + + # Get the SBValue for the global variable 'my_char'. + val = frame.FindValue("my_char", lldb.eValueTypeVariableGlobal) + self.DebugSBValue(val) + + # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and + # expect to get a Python string as the result object! + error = lldb.SBError() + self.assertFalse(val.TypeIsPointerType()) + content = process.ReadMemory( + val.AddressOf().GetValueAsUnsigned(), 1, error) + if not error.Success(): + self.fail("SBProcess.ReadMemory() failed") + if self.TraceOn(): + print("memory content:", content) + + self.expect( + content, + "Result from SBProcess.ReadMemory() matches our expected output: 'x'", + exe=False, + startstr=b'x') + + # Read (char *)my_char_ptr. + val = frame.FindValue("my_char_ptr", lldb.eValueTypeVariableGlobal) + self.DebugSBValue(val) + cstring = process.ReadCStringFromMemory( + val.GetValueAsUnsigned(), 256, error) + if not error.Success(): + self.fail("SBProcess.ReadCStringFromMemory() failed") + if self.TraceOn(): + print("cstring read is:", cstring) + + self.expect( + cstring, + "Result from SBProcess.ReadCStringFromMemory() matches our expected output", + exe=False, + startstr='Does it work?') + + # Get the SBValue for the global variable 'my_cstring'. + val = frame.FindValue("my_cstring", lldb.eValueTypeVariableGlobal) + self.DebugSBValue(val) + + # Due to the typemap magic (see lldb.swig), we pass in 256 to read at most 256 bytes + # from the address, and expect to get a Python string as the result + # object! + self.assertFalse(val.TypeIsPointerType()) + cstring = process.ReadCStringFromMemory( + val.AddressOf().GetValueAsUnsigned(), 256, error) + if not error.Success(): + self.fail("SBProcess.ReadCStringFromMemory() failed") + if self.TraceOn(): + print("cstring read is:", cstring) + + self.expect( + cstring, + "Result from SBProcess.ReadCStringFromMemory() matches our expected output", + exe=False, + startstr='lldb.SBProcess.ReadCStringFromMemory() works!') + + # Get the SBValue for the global variable 'my_uint32'. + val = frame.FindValue("my_uint32", lldb.eValueTypeVariableGlobal) + self.DebugSBValue(val) + + # Due to the typemap magic (see lldb.swig), we pass in 4 to read 4 bytes + # from the address, and expect to get an int as the result! + self.assertFalse(val.TypeIsPointerType()) + my_uint32 = process.ReadUnsignedFromMemory( + val.AddressOf().GetValueAsUnsigned(), 4, error) + if not error.Success(): + self.fail("SBProcess.ReadCStringFromMemory() failed") + if self.TraceOn(): + print("uint32 read is:", my_uint32) + + if my_uint32 != 12345: + self.fail( + "Result from SBProcess.ReadUnsignedFromMemory() does not match our expected output") + + @add_test_categories(['pyapi']) + def test_write_memory(self): + """Test Python SBProcess.WriteMemory() API.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + # Launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint") + frame = thread.GetFrameAtIndex(0) + + # Get the SBValue for the global variable 'my_char'. + val = frame.FindValue("my_char", lldb.eValueTypeVariableGlobal) + self.DebugSBValue(val) + + # If the variable does not have a load address, there's no sense + # continuing. + if not val.GetLocation().startswith("0x"): + return + + # OK, let's get the hex location of the variable. + location = int(val.GetLocation(), 16) + + # The program logic makes the 'my_char' variable to have memory content as 'x'. + # But we want to use the WriteMemory() API to assign 'a' to the + # variable. + + # Now use WriteMemory() API to write 'a' into the global variable. + error = lldb.SBError() + result = process.WriteMemory(location, 'a', error) + if not error.Success() or result != 1: + self.fail("SBProcess.WriteMemory() failed") + + # Read from the memory location. This time it should be 'a'. + # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and + # expect to get a Python string as the result object! + content = process.ReadMemory(location, 1, error) + if not error.Success(): + self.fail("SBProcess.ReadMemory() failed") + if self.TraceOn(): + print("memory content:", content) + + self.expect( + content, + "Result from SBProcess.ReadMemory() matches our expected output: 'a'", + exe=False, + startstr=b'a') + + @add_test_categories(['pyapi']) + def test_access_my_int(self): + """Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + # Launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint") + frame = thread.GetFrameAtIndex(0) + + # Get the SBValue for the global variable 'my_int'. + val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal) + self.DebugSBValue(val) + + # If the variable does not have a load address, there's no sense + # continuing. + if not val.GetLocation().startswith("0x"): + return + + # OK, let's get the hex location of the variable. + location = int(val.GetLocation(), 16) + + # Note that the canonical from of the bytearray is little endian. + from lldbsuite.test.lldbutil import int_to_bytearray, bytearray_to_int + + byteSize = val.GetByteSize() + bytes = int_to_bytearray(256, byteSize) + + byteOrder = process.GetByteOrder() + if byteOrder == lldb.eByteOrderBig: + bytes.reverse() + elif byteOrder == lldb.eByteOrderLittle: + pass + else: + # Neither big endian nor little endian? Return for now. + # Add more logic here if we want to handle other types. + return + + # The program logic makes the 'my_int' variable to have int type and value of 0. + # But we want to use the WriteMemory() API to assign 256 to the + # variable. + + # Now use WriteMemory() API to write 256 into the global variable. + error = lldb.SBError() + result = process.WriteMemory(location, bytes, error) + if not error.Success() or result != byteSize: + self.fail("SBProcess.WriteMemory() failed") + + # Make sure that the val we got originally updates itself to notice the + # change: + self.expect( + val.GetValue(), + "SBProcess.ReadMemory() successfully writes (int)256 to the memory location for 'my_int'", + exe=False, + startstr='256') + + # And for grins, get the SBValue for the global variable 'my_int' + # again, to make sure that also tracks the new value: + val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal) + self.expect( + val.GetValue(), + "SBProcess.ReadMemory() successfully writes (int)256 to the memory location for 'my_int'", + exe=False, + startstr='256') + + # Now read the memory content. The bytearray should have (byte)1 as + # the second element. + content = process.ReadMemory(location, byteSize, error) + if not error.Success(): + self.fail("SBProcess.ReadMemory() failed") + + # The bytearray_to_int utility function expects a little endian + # bytearray. + if byteOrder == lldb.eByteOrderBig: + content = bytearray(content, 'ascii') + content.reverse() + + new_value = bytearray_to_int(content, byteSize) + if new_value != 256: + self.fail("Memory content read from 'my_int' does not match (int)256") + + # Dump the memory content.... + if self.TraceOn(): + for i in content: + print("byte:", i) + + @add_test_categories(['pyapi']) + def test_remote_launch(self): + """Test SBProcess.RemoteLaunch() API with a process not in eStateConnected, and it should fail.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + if self.TraceOn(): + print("process state:", state_type_to_str(process.GetState())) + self.assertTrue(process.GetState() != lldb.eStateConnected) + + error = lldb.SBError() + success = process.RemoteLaunch( + None, None, None, None, None, None, 0, False, error) + self.assertTrue( + not success, + "RemoteLaunch() should fail for process state != eStateConnected") + + @add_test_categories(['pyapi']) + def test_get_num_supported_hardware_watchpoints(self): + """Test SBProcess.GetNumSupportedHardwareWatchpoints() API with a process.""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + # Launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + error = lldb.SBError() + num = process.GetNumSupportedHardwareWatchpoints(error) + if self.TraceOn() and error.Success(): + print("Number of supported hardware watchpoints: %d" % num) + + @add_test_categories(['pyapi']) + @no_debug_info_test + def test_get_process_info(self): + """Test SBProcess::GetProcessInfo() API with a locally launched process.""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Launch the process and stop at the entry point. + launch_info = lldb.SBLaunchInfo(None) + launch_info.SetWorkingDirectory(self.get_process_working_directory()) + launch_flags = launch_info.GetLaunchFlags() + launch_flags |= lldb.eLaunchFlagStopAtEntry + launch_info.SetLaunchFlags(launch_flags) + error = lldb.SBError() + process = target.Launch(launch_info, error) + + if not error.Success(): + self.fail("Failed to launch process") + + # Verify basic process info can be retrieved successfully + process_info = process.GetProcessInfo() + self.assertTrue(process_info.IsValid()) + file_spec = process_info.GetExecutableFile() + self.assertTrue(file_spec.IsValid()) + process_name = process_info.GetName() + self.assertIsNotNone(process_name, "Process has a name") + self.assertGreater(len(process_name), 0, "Process name isn't blank") + self.assertEqual(file_spec.GetFilename(), "a.out") + self.assertNotEqual( + process_info.GetProcessID(), lldb.LLDB_INVALID_PROCESS_ID, + "Process ID is valid") + + # Additional process info varies by platform, so just check that + # whatever info was retrieved is consistent and nothing blows up. + if process_info.UserIDIsValid(): + self.assertNotEqual( + process_info.GetUserID(), lldb.UINT32_MAX, + "Process user ID is valid") + else: + self.assertEqual( + process_info.GetUserID(), lldb.UINT32_MAX, + "Process user ID is invalid") + + if process_info.GroupIDIsValid(): + self.assertNotEqual( + process_info.GetGroupID(), lldb.UINT32_MAX, + "Process group ID is valid") + else: + self.assertEqual( + process_info.GetGroupID(), lldb.UINT32_MAX, + "Process group ID is invalid") + + if process_info.EffectiveUserIDIsValid(): + self.assertNotEqual( + process_info.GetEffectiveUserID(), lldb.UINT32_MAX, + "Process effective user ID is valid") + else: + self.assertEqual( + process_info.GetEffectiveUserID(), lldb.UINT32_MAX, + "Process effective user ID is invalid") + + if process_info.EffectiveGroupIDIsValid(): + self.assertNotEqual( + process_info.GetEffectiveGroupID(), lldb.UINT32_MAX, + "Process effective group ID is valid") + else: + self.assertEqual( + process_info.GetEffectiveGroupID(), lldb.UINT32_MAX, + "Process effective group ID is invalid") + + process_info.GetParentProcessID() diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/io/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/io/Makefile new file mode 100644 index 00000000000..4aa78325888 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/io/Makefile @@ -0,0 +1,4 @@ +C_SOURCES := main.c +EXE := process_io + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/io/TestProcessIO.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/io/TestProcessIO.py new file mode 100644 index 00000000000..365d486650f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/io/TestProcessIO.py @@ -0,0 +1,239 @@ +"""Test Python APIs for process IO.""" + +from __future__ import print_function + + +import os +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ProcessIOTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def setup_test(self): + # Get the full path to our executable to be debugged. + self.exe = self.getBuildArtifact("process_io") + self.local_input_file = self.getBuildArtifact("input.txt") + self.local_output_file = self.getBuildArtifact("output.txt") + self.local_error_file = self.getBuildArtifact("error.txt") + + self.input_file = os.path.join( + self.get_process_working_directory(), "input.txt") + self.output_file = os.path.join( + self.get_process_working_directory(), "output.txt") + self.error_file = os.path.join( + self.get_process_working_directory(), "error.txt") + self.lines = ["Line 1", "Line 2", "Line 3"] + + @skipIfWindows # stdio manipulation unsupported on Windows + @add_test_categories(['pyapi']) + @expectedFlakeyLinux(bugnumber="llvm.org/pr26437") + @skipIfDarwinEmbedded # I/O redirection like this is not supported on remote iOS devices yet <rdar://problem/54581135> + def test_stdin_by_api(self): + """Exercise SBProcess.PutSTDIN().""" + self.setup_test() + self.build() + self.create_target() + self.run_process(True) + output = self.process.GetSTDOUT(1000) + self.check_process_output(output, output) + + @skipIfWindows # stdio manipulation unsupported on Windows + @add_test_categories(['pyapi']) + @expectedFlakeyLinux(bugnumber="llvm.org/pr26437") + def test_stdin_redirection(self): + """Exercise SBLaunchInfo::AddOpenFileAction() for STDIN without specifying STDOUT or STDERR.""" + self.setup_test() + self.build() + self.create_target() + self.redirect_stdin() + self.run_process(False) + output = self.process.GetSTDOUT(1000) + self.check_process_output(output, output) + + @skipIfWindows # stdio manipulation unsupported on Windows + @add_test_categories(['pyapi']) + @expectedFlakeyLinux(bugnumber="llvm.org/pr26437") + @skipIfDarwinEmbedded # debugserver can't create/write files on the device + def test_stdout_redirection(self): + """Exercise SBLaunchInfo::AddOpenFileAction() for STDOUT without specifying STDIN or STDERR.""" + self.setup_test() + self.build() + self.create_target() + self.redirect_stdout() + self.run_process(True) + output = self.read_output_file_and_delete() + error = self.process.GetSTDOUT(1000) + self.check_process_output(output, error) + + @skipIfWindows # stdio manipulation unsupported on Windows + @add_test_categories(['pyapi']) + @expectedFlakeyLinux(bugnumber="llvm.org/pr26437") + @skipIfDarwinEmbedded # debugserver can't create/write files on the device + def test_stderr_redirection(self): + """Exercise SBLaunchInfo::AddOpenFileAction() for STDERR without specifying STDIN or STDOUT.""" + self.setup_test() + self.build() + self.create_target() + self.redirect_stderr() + self.run_process(True) + output = self.process.GetSTDOUT(1000) + error = self.read_error_file_and_delete() + self.check_process_output(output, error) + + @skipIfWindows # stdio manipulation unsupported on Windows + @add_test_categories(['pyapi']) + @expectedFlakeyLinux(bugnumber="llvm.org/pr26437") + @skipIfDarwinEmbedded # debugserver can't create/write files on the device + def test_stdout_stderr_redirection(self): + """Exercise SBLaunchInfo::AddOpenFileAction() for STDOUT and STDERR without redirecting STDIN.""" + self.setup_test() + self.build() + self.create_target() + self.redirect_stdout() + self.redirect_stderr() + self.run_process(True) + output = self.read_output_file_and_delete() + error = self.read_error_file_and_delete() + self.check_process_output(output, error) + + # target_file - path on local file system or remote file system if running remote + # local_file - path on local system + def read_file_and_delete(self, target_file, local_file): + if lldb.remote_platform: + self.runCmd('platform get-file "{remote}" "{local}"'.format( + remote=target_file, local=local_file)) + + self.assertTrue( + os.path.exists(local_file), + 'Make sure "{local}" file exists'.format( + local=local_file)) + f = open(local_file, 'r') + contents = f.read() + f.close() + + # TODO: add 'platform delete-file' file command + # if lldb.remote_platform: + # self.runCmd('platform delete-file "{remote}"'.format(remote=target_file)) + os.unlink(local_file) + return contents + + def read_output_file_and_delete(self): + return self.read_file_and_delete( + self.output_file, self.local_output_file) + + def read_error_file_and_delete(self): + return self.read_file_and_delete( + self.error_file, self.local_error_file) + + def create_target(self): + '''Create the target and launch info that will be used by all tests''' + self.target = self.dbg.CreateTarget(self.exe) + self.launch_info = lldb.SBLaunchInfo([self.exe]) + self.launch_info.SetWorkingDirectory( + self.get_process_working_directory()) + + def redirect_stdin(self): + '''Redirect STDIN (file descriptor 0) to use our input.txt file + + Make the input.txt file to use when redirecting STDIN, setup a cleanup action + to delete the input.txt at the end of the test in case exceptions are thrown, + and redirect STDIN in the launch info.''' + f = open(self.local_input_file, 'w') + for line in self.lines: + f.write(line + "\n") + f.close() + + if lldb.remote_platform: + self.runCmd('platform put-file "{local}" "{remote}"'.format( + local=self.local_input_file, remote=self.input_file)) + + # This is the function to remove the custom formats in order to have a + # clean slate for the next test case. + def cleanup(): + os.unlink(self.local_input_file) + # TODO: add 'platform delete-file' file command + # if lldb.remote_platform: + # self.runCmd('platform delete-file "{remote}"'.format(remote=self.input_file)) + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + self.launch_info.AddOpenFileAction(0, self.input_file, True, False) + + def redirect_stdout(self): + '''Redirect STDOUT (file descriptor 1) to use our output.txt file''' + self.launch_info.AddOpenFileAction(1, self.output_file, False, True) + + def redirect_stderr(self): + '''Redirect STDERR (file descriptor 2) to use our error.txt file''' + self.launch_info.AddOpenFileAction(2, self.error_file, False, True) + + def run_process(self, put_stdin): + '''Run the process to completion and optionally put lines to STDIN via the API if "put_stdin" is True''' + # Set the breakpoints + self.breakpoint = self.target.BreakpointCreateBySourceRegex( + 'Set breakpoint here', lldb.SBFileSpec("main.c")) + self.assertTrue( + self.breakpoint.GetNumLocations() > 0, + VALID_BREAKPOINT) + + # Launch the process, and do not stop at the entry point. + error = lldb.SBError() + # This should launch the process and it should exit by the time we get back + # because we have synchronous mode enabled + self.process = self.target.Launch(self.launch_info, error) + + self.assertTrue( + error.Success(), + "Make sure process launched successfully") + self.assertTrue(self.process, PROCESS_IS_VALID) + + if self.TraceOn(): + print("process launched.") + + # Frame #0 should be at our breakpoint. + threads = lldbutil.get_threads_stopped_at_breakpoint( + self.process, self.breakpoint) + + self.assertTrue(len(threads) == 1) + self.thread = threads[0] + self.frame = self.thread.frames[0] + self.assertTrue(self.frame, "Frame 0 is valid.") + + if self.TraceOn(): + print("process stopped at breakpoint, sending STDIN via LLDB API.") + + # Write data to stdin via the public API if we were asked to + if put_stdin: + for line in self.lines: + self.process.PutSTDIN(line + "\n") + + # Let process continue so it will exit + self.process.Continue() + state = self.process.GetState() + self.assertTrue(state == lldb.eStateExited, PROCESS_IS_VALID) + + def check_process_output(self, output, error): + # Since we launched the process without specifying stdin/out/err, + # a pseudo terminal is used for stdout/err, and we are satisfied + # once "input line=>1" appears in stdout. + # See also main.c. + if self.TraceOn(): + print("output = '%s'" % output) + print("error = '%s'" % error) + + for line in self.lines: + check_line = 'input line to stdout: %s' % (line) + self.assertTrue( + check_line in output, + "verify stdout line shows up in STDOUT") + for line in self.lines: + check_line = 'input line to stderr: %s' % (line) + self.assertTrue( + check_line in error, + "verify stderr line shows up in STDERR") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/io/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/io/main.c new file mode 100644 index 00000000000..c9a5707f0e1 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/io/main.c @@ -0,0 +1,19 @@ +#include <stdio.h> + +int main(int argc, char const *argv[]) { + printf("Hello world.\n"); // Set breakpoint here + char line[100]; + if (fgets(line, sizeof(line), stdin)) { + fprintf(stdout, "input line to stdout: %s", line); + fprintf(stderr, "input line to stderr: %s", line); + } + if (fgets(line, sizeof(line), stdin)) { + fprintf(stdout, "input line to stdout: %s", line); + fprintf(stderr, "input line to stderr: %s", line); + } + if (fgets(line, sizeof(line), stdin)) { + fprintf(stdout, "input line to stdout: %s", line); + fprintf(stderr, "input line to stderr: %s", line); + } + printf("Exiting now\n"); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/main.cpp new file mode 100644 index 00000000000..32c6dee8044 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/main.cpp @@ -0,0 +1,30 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> +#include <stdint.h> + +// This simple program is to test the lldb Python API related to process. + +char my_char = 'u'; +char my_cstring[] = "lldb.SBProcess.ReadCStringFromMemory() works!"; +char *my_char_ptr = (char *)"Does it work?"; +uint32_t my_uint32 = 12345; +int my_int = 0; + +int main (int argc, char const *argv[]) +{ + for (int i = 0; i < 3; ++i) { + printf("my_char='%c'\n", my_char); + ++my_char; + } + + printf("after the loop: my_char='%c'\n", my_char); // 'my_char' should print out as 'x'. + + return 0; // Set break point at this line and check variable 'my_char'. + // Use lldb Python API to set memory content for my_int and check the result. +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/read-mem-cstring/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/read-mem-cstring/Makefile new file mode 100644 index 00000000000..6bc1b47f1f3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/read-mem-cstring/Makefile @@ -0,0 +1,4 @@ +C_SOURCES := main.c +EXE := read-mem-cstring + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/read-mem-cstring/TestReadMemCString.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/read-mem-cstring/TestReadMemCString.py new file mode 100644 index 00000000000..fc26c3b6c86 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/read-mem-cstring/TestReadMemCString.py @@ -0,0 +1,58 @@ +"""Test reading c-strings from memory via SB API.""" + + +import os +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestReadMemCString(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def test_read_memory_c_string(self): + """Test corner case behavior of SBProcess::ReadCStringFromMemory""" + self.build() + self.dbg.SetAsync(False) + + self.main_source = "main.c" + self.main_source_path = os.path.join(self.getSourceDir(), + self.main_source) + self.main_source_spec = lldb.SBFileSpec(self.main_source_path) + self.exe = self.getBuildArtifact("read-mem-cstring") + + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( + self, 'breakpoint here', self.main_source_spec, None, self.exe) + + frame = thread.GetFrameAtIndex(0) + + err = lldb.SBError() + + empty_str_addr = frame.FindVariable("empty_string").GetValueAsUnsigned(err) + self.assertTrue(err.Success()) + self.assertTrue(empty_str_addr != lldb.LLDB_INVALID_ADDRESS) + + one_letter_str_addr = frame.FindVariable("one_letter_string").GetValueAsUnsigned(err) + self.assertTrue(err.Success()) + self.assertTrue(one_letter_str_addr != lldb.LLDB_INVALID_ADDRESS) + + invalid_memory_str_addr = frame.FindVariable("invalid_memory_string").GetValueAsUnsigned(err) + self.assertTrue(err.Success()) + self.assertTrue(invalid_memory_str_addr != lldb.LLDB_INVALID_ADDRESS) + + # Important: An empty (0-length) c-string must come back as a Python string, not a + # None object. + empty_str = process.ReadCStringFromMemory(empty_str_addr, 2048, err) + self.assertTrue(err.Success()) + self.assertTrue(empty_str == "") + + one_letter_string = process.ReadCStringFromMemory(one_letter_str_addr, 2048, err) + self.assertTrue(err.Success()) + self.assertTrue(one_letter_string == "1") + + invalid_memory_string = process.ReadCStringFromMemory(invalid_memory_str_addr, 2048, err) + self.assertTrue(err.Fail()) + self.assertTrue(invalid_memory_string == "" or invalid_memory_string == None) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/read-mem-cstring/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/read-mem-cstring/main.c new file mode 100644 index 00000000000..03c66741712 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/process/read-mem-cstring/main.c @@ -0,0 +1,11 @@ +#include <stdlib.h> +int main () +{ + const char *empty_string = ""; + const char *one_letter_string = "1"; + // This expects that lower 4k of memory will be mapped unreadable, which most + // OSs do (to catch null pointer dereferences). + const char *invalid_memory_string = (char*)0x100; + + return empty_string[0] + one_letter_string[0]; // breakpoint here +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbdata/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbdata/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbdata/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbdata/TestSBData.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbdata/TestSBData.py new file mode 100644 index 00000000000..a12f683d601 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbdata/TestSBData.py @@ -0,0 +1,521 @@ +"""Test the SBData APIs.""" + + + +from math import fabs +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class SBDataAPICase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + 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.cpp', '// set breakpoint here') + + @add_test_categories(['pyapi']) + def test_byte_order_and_address_byte_size(self): + """Test the SBData::SetData() to ensure the byte order and address + byte size are obeyed""" + addr_data = b'\x11\x22\x33\x44\x55\x66\x77\x88' + error = lldb.SBError() + data = lldb.SBData() + data.SetData(error, addr_data, lldb.eByteOrderBig, 4) + addr = data.GetAddress(error, 0) + self.assertTrue(addr == 0x11223344); + data.SetData(error, addr_data, lldb.eByteOrderBig, 8) + addr = data.GetAddress(error, 0) + self.assertTrue(addr == 0x1122334455667788); + data.SetData(error, addr_data, lldb.eByteOrderLittle, 4) + addr = data.GetAddress(error, 0) + self.assertTrue(addr == 0x44332211); + data.SetData(error, addr_data, lldb.eByteOrderLittle, 8) + addr = data.GetAddress(error, 0) + self.assertTrue(addr == 0x8877665544332211); + + @add_test_categories(['pyapi']) + def test_with_run_command(self): + """Test the SBData APIs.""" + self.build() + self.runCmd("file " + self.getBuildArtifact("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']) + + target = self.dbg.GetSelectedTarget() + + process = target.GetProcess() + + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertIsNotNone(thread) + + frame = thread.GetSelectedFrame() + foobar = frame.FindVariable('foobar') + self.assertTrue(foobar.IsValid()) + data = foobar.GetPointeeData(0, 2) + offset = 0 + error = lldb.SBError() + + self.assert_data(data.GetUnsignedInt32, offset, 1) + offset += 4 + low = data.GetSignedInt16(error, offset) + self.assertTrue(error.Success()) + offset += 2 + high = data.GetSignedInt16(error, offset) + self.assertTrue(error.Success()) + offset += 2 + self.assertTrue( + (low == 9 and high == 0) or ( + low == 0 and high == 9), + 'foo[0].b == 9') + self.assertTrue( + fabs( + data.GetFloat( + error, + offset) - + 3.14) < 1, + 'foo[0].c == 3.14') + self.assertTrue(error.Success()) + offset += 4 + self.assert_data(data.GetUnsignedInt32, offset, 8) + offset += 4 + self.assert_data(data.GetUnsignedInt32, offset, 5) + offset += 4 + + self.runCmd("n") + + offset = 16 + + self.assert_data(data.GetUnsignedInt32, offset, 5) + + data = foobar.GetPointeeData(1, 1) + + offset = 0 + + self.assert_data(data.GetSignedInt32, offset, 8) + offset += 4 + self.assert_data(data.GetSignedInt32, offset, 7) + offset += 8 + self.assertTrue( + data.GetUnsignedInt32( + error, + offset) == 0, + 'do not read beyond end') + self.assertTrue(not error.Success()) + error.Clear() # clear the error for the next test + + star_foobar = foobar.Dereference() + self.assertTrue(star_foobar.IsValid()) + + data = star_foobar.GetData() + + offset = 0 + self.assert_data(data.GetUnsignedInt32, offset, 1) + offset += 4 + self.assert_data(data.GetUnsignedInt32, offset, 9) + + foobar_addr = star_foobar.GetLoadAddress() + foobar_addr += 12 + + # http://llvm.org/bugs/show_bug.cgi?id=11579 + # lldb::SBValue::CreateValueFromAddress does not verify SBType::GetPointerType succeeds + # This should not crash LLDB. + nothing = foobar.CreateValueFromAddress( + "nothing", foobar_addr, star_foobar.GetType().GetBasicType( + lldb.eBasicTypeInvalid)) + + new_foobar = foobar.CreateValueFromAddress( + "f00", foobar_addr, star_foobar.GetType()) + self.assertTrue(new_foobar.IsValid()) + data = new_foobar.GetData() + + self.assertTrue(data.uint32[0] == 8, 'then foo[1].a == 8') + self.assertTrue(data.uint32[1] == 7, 'then foo[1].b == 7') + # exploiting that sizeof(uint32) == sizeof(float) + self.assertTrue(fabs(data.float[2] - 3.14) < 1, 'foo[1].c == 3.14') + + self.runCmd("n") + + offset = 0 + self.assert_data(data.GetUnsignedInt32, offset, 8) + offset += 4 + self.assert_data(data.GetUnsignedInt32, offset, 7) + offset += 4 + self.assertTrue( + fabs( + data.GetFloat( + error, + offset) - + 3.14) < 1, + 'foo[1].c == 3.14') + self.assertTrue(error.Success()) + + data = new_foobar.GetData() + + offset = 0 + self.assert_data(data.GetUnsignedInt32, offset, 8) + offset += 4 + self.assert_data(data.GetUnsignedInt32, offset, 7) + offset += 4 + self.assertTrue( + fabs( + data.GetFloat( + error, + offset) - + 6.28) < 1, + 'foo[1].c == 6.28') + self.assertTrue(error.Success()) + + self.runCmd("n") + + barfoo = frame.FindVariable('barfoo') + + data = barfoo.GetData() + offset = 0 + self.assert_data(data.GetUnsignedInt32, offset, 1) + offset += 4 + self.assert_data(data.GetUnsignedInt32, offset, 2) + offset += 4 + self.assertTrue( + fabs( + data.GetFloat( + error, + offset) - + 3) < 1, + 'barfoo[0].c == 3') + self.assertTrue(error.Success()) + offset += 4 + self.assert_data(data.GetUnsignedInt32, offset, 4) + offset += 4 + self.assert_data(data.GetUnsignedInt32, offset, 5) + offset += 4 + self.assertTrue( + fabs( + data.GetFloat( + error, + offset) - + 6) < 1, + 'barfoo[1].c == 6') + self.assertTrue(error.Success()) + + new_object = barfoo.CreateValueFromData( + "new_object", data, barfoo.GetType().GetBasicType( + lldb.eBasicTypeInt)) + self.assertTrue(new_object.GetValue() == "1", 'new_object == 1') + + if data.GetByteOrder() == lldb.eByteOrderBig: + data.SetData( + error, + '\0\0\0A', + data.GetByteOrder(), + data.GetAddressByteSize()) + else: + data.SetData( + error, + 'A\0\0\0', + data.GetByteOrder(), + data.GetAddressByteSize()) + self.assertTrue(error.Success()) + + data2 = lldb.SBData() + data2.SetData( + error, + 'BCD', + data.GetByteOrder(), + data.GetAddressByteSize()) + self.assertTrue(error.Success()) + + data.Append(data2) + + # this breaks on EBCDIC + offset = 0 + self.assert_data(data.GetUnsignedInt32, offset, 65) + offset += 4 + self.assert_data(data.GetUnsignedInt8, offset, 66) + offset += 1 + self.assert_data(data.GetUnsignedInt8, offset, 67) + offset += 1 + self.assert_data(data.GetUnsignedInt8, offset, 68) + offset += 1 + + # check the new API calls introduced per LLVM llvm.org/prenhancement request + # 11619 (Allow creating SBData values from arrays or primitives in + # Python) + + hello_str = "hello!" + data2 = lldb.SBData.CreateDataFromCString( + process.GetByteOrder(), process.GetAddressByteSize(), hello_str) + self.assertTrue(len(data2.uint8) == len(hello_str)) + self.assertTrue(data2.uint8[0] == 104, 'h == 104') + self.assertTrue(data2.uint8[1] == 101, 'e == 101') + self.assertTrue(data2.uint8[2] == 108, 'l == 108') + self.assert_data(data2.GetUnsignedInt8, 3, 108) # l + self.assertTrue(data2.uint8[4] == 111, 'o == 111') + self.assert_data(data2.GetUnsignedInt8, 5, 33) # ! + + uint_lists = [[1, 2, 3, 4, 5], [int(i) for i in [1, 2, 3, 4, 5]]] + int_lists = [[2, -2], [int(i) for i in [2, -2]]] + + for l in uint_lists: + data2 = lldb.SBData.CreateDataFromUInt64Array( + process.GetByteOrder(), process.GetAddressByteSize(), l) + self.assert_data(data2.GetUnsignedInt64, 0, 1) + self.assert_data(data2.GetUnsignedInt64, 8, 2) + self.assert_data(data2.GetUnsignedInt64, 16, 3) + self.assert_data(data2.GetUnsignedInt64, 24, 4) + self.assert_data(data2.GetUnsignedInt64, 32, 5) + + self.assertTrue( + data2.uint64s == [ + 1, + 2, + 3, + 4, + 5], + 'read_data_helper failure: data2 == [1,2,3,4,5]') + + for l in int_lists: + data2 = lldb.SBData.CreateDataFromSInt32Array( + process.GetByteOrder(), process.GetAddressByteSize(), l) + self.assertTrue( + data2.sint32[ + 0:2] == [ + 2, -2], 'signed32 data2 = [2,-2]') + + data2.Append( + lldb.SBData.CreateDataFromSInt64Array( + process.GetByteOrder(), + process.GetAddressByteSize(), + int_lists[0])) + self.assert_data(data2.GetSignedInt32, 0, 2) + self.assert_data(data2.GetSignedInt32, 4, -2) + self.assertTrue( + data2.sint64[ + 1:3] == [ + 2, -2], 'signed64 data2 = [2,-2]') + + for l in int_lists: + data2 = lldb.SBData.CreateDataFromSInt64Array( + process.GetByteOrder(), process.GetAddressByteSize(), l) + self.assert_data(data2.GetSignedInt64, 0, 2) + self.assert_data(data2.GetSignedInt64, 8, -2) + self.assertTrue( + data2.sint64[ + 0:2] == [ + 2, -2], 'signed64 data2 = [2,-2]') + + for l in uint_lists: + data2 = lldb.SBData.CreateDataFromUInt32Array( + process.GetByteOrder(), process.GetAddressByteSize(), l) + self.assert_data(data2.GetUnsignedInt32, 0, 1) + self.assert_data(data2.GetUnsignedInt32, 4, 2) + self.assert_data(data2.GetUnsignedInt32, 8, 3) + self.assert_data(data2.GetUnsignedInt32, 12, 4) + self.assert_data(data2.GetUnsignedInt32, 16, 5) + + bool_list = [True, True, False, False, True, False] + + data2 = lldb.SBData.CreateDataFromSInt32Array( + process.GetByteOrder(), process.GetAddressByteSize(), bool_list) + self.assertTrue( + data2.sint32[ + 0:6] == [ + 1, + 1, + 0, + 0, + 1, + 0], + 'signed32 data2 = [1, 1, 0, 0, 1, 0]') + + data2 = lldb.SBData.CreateDataFromUInt32Array( + process.GetByteOrder(), process.GetAddressByteSize(), bool_list) + self.assertTrue( + data2.uint32[ + 0:6] == [ + 1, + 1, + 0, + 0, + 1, + 0], + 'unsigned32 data2 = [1, 1, 0, 0, 1, 0]') + + data2 = lldb.SBData.CreateDataFromSInt64Array( + process.GetByteOrder(), process.GetAddressByteSize(), bool_list) + self.assertTrue( + data2.sint64[ + 0:6] == [ + 1, + 1, + 0, + 0, + 1, + 0], + 'signed64 data2 = [1, 1, 0, 0, 1, 0]') + + data2 = lldb.SBData.CreateDataFromUInt64Array( + process.GetByteOrder(), process.GetAddressByteSize(), bool_list) + self.assertTrue( + data2.uint64[ + 0:6] == [ + 1, + 1, + 0, + 0, + 1, + 0], + 'signed64 data2 = [1, 1, 0, 0, 1, 0]') + + data2 = lldb.SBData.CreateDataFromDoubleArray( + process.GetByteOrder(), process.GetAddressByteSize(), [ + 3.14, 6.28, 2.71]) + self.assertTrue( + fabs( + data2.GetDouble( + error, + 0) - + 3.14) < 0.5, + 'double data2[0] = 3.14') + self.assertTrue(error.Success()) + self.assertTrue( + fabs( + data2.GetDouble( + error, + 8) - + 6.28) < 0.5, + 'double data2[1] = 6.28') + self.assertTrue(error.Success()) + self.assertTrue( + fabs( + data2.GetDouble( + error, + 16) - + 2.71) < 0.5, + 'double data2[2] = 2.71') + self.assertTrue(error.Success()) + + data2 = lldb.SBData() + + data2.SetDataFromCString(hello_str) + self.assertTrue(len(data2.uint8) == len(hello_str)) + self.assert_data(data2.GetUnsignedInt8, 0, 104) + self.assert_data(data2.GetUnsignedInt8, 1, 101) + self.assert_data(data2.GetUnsignedInt8, 2, 108) + self.assert_data(data2.GetUnsignedInt8, 3, 108) + self.assert_data(data2.GetUnsignedInt8, 4, 111) + self.assert_data(data2.GetUnsignedInt8, 5, 33) + + data2.SetDataFromUInt64Array([1, 2, 3, 4, 5]) + self.assert_data(data2.GetUnsignedInt64, 0, 1) + self.assert_data(data2.GetUnsignedInt64, 8, 2) + self.assert_data(data2.GetUnsignedInt64, 16, 3) + self.assert_data(data2.GetUnsignedInt64, 24, 4) + self.assert_data(data2.GetUnsignedInt64, 32, 5) + + self.assertTrue( + data2.uint64[0] == 1, + 'read_data_helper failure: set data2[0] = 1') + self.assertTrue( + data2.uint64[1] == 2, + 'read_data_helper failure: set data2[1] = 2') + self.assertTrue( + data2.uint64[2] == 3, + 'read_data_helper failure: set data2[2] = 3') + self.assertTrue( + data2.uint64[3] == 4, + 'read_data_helper failure: set data2[3] = 4') + self.assertTrue( + data2.uint64[4] == 5, + 'read_data_helper failure: set data2[4] = 5') + + self.assertTrue( + data2.uint64[ + 0:2] == [ + 1, + 2], + 'read_data_helper failure: set data2[0:2] = [1,2]') + + data2.SetDataFromSInt32Array([2, -2]) + self.assert_data(data2.GetSignedInt32, 0, 2) + self.assert_data(data2.GetSignedInt32, 4, -2) + + data2.SetDataFromSInt64Array([2, -2]) + self.assert_data(data2.GetSignedInt64, 0, 2) + self.assert_data(data2.GetSignedInt64, 8, -2) + + data2.SetDataFromUInt32Array([1, 2, 3, 4, 5]) + self.assert_data(data2.GetUnsignedInt32, 0, 1) + self.assert_data(data2.GetUnsignedInt32, 4, 2) + self.assert_data(data2.GetUnsignedInt32, 8, 3) + self.assert_data(data2.GetUnsignedInt32, 12, 4) + self.assert_data(data2.GetUnsignedInt32, 16, 5) + + self.assertTrue( + data2.uint32[0] == 1, + 'read_data_helper failure: set 32-bit data2[0] = 1') + self.assertTrue( + data2.uint32[1] == 2, + 'read_data_helper failure: set 32-bit data2[1] = 2') + self.assertTrue( + data2.uint32[2] == 3, + 'read_data_helper failure: set 32-bit data2[2] = 3') + self.assertTrue( + data2.uint32[3] == 4, + 'read_data_helper failure: set 32-bit data2[3] = 4') + self.assertTrue( + data2.uint32[4] == 5, + 'read_data_helper failure: set 32-bit data2[4] = 5') + + data2.SetDataFromDoubleArray([3.14, 6.28, 2.71]) + self.assertTrue(fabs(data2.GetDouble(error, 0) - 3.14) + < 0.5, 'set double data2[0] = 3.14') + self.assertTrue(fabs(data2.GetDouble(error, 8) - 6.28) + < 0.5, 'set double data2[1] = 6.28') + self.assertTrue(fabs(data2.GetDouble(error, 16) - 2.71) + < 0.5, 'set double data2[2] = 2.71') + + self.assertTrue( + fabs( + data2.double[0] - + 3.14) < 0.5, + 'read_data_helper failure: set double data2[0] = 3.14') + self.assertTrue( + fabs( + data2.double[1] - + 6.28) < 0.5, + 'read_data_helper failure: set double data2[1] = 6.28') + self.assertTrue( + fabs( + data2.double[2] - + 2.71) < 0.5, + 'read_data_helper failure: set double data2[2] = 2.71') + + def assert_data(self, func, arg, expected): + """ Asserts func(SBError error, arg) == expected. """ + error = lldb.SBError() + result = func(error, arg) + if not error.Success(): + stream = lldb.SBStream() + error.GetDescription(stream) + self.assertTrue( + error.Success(), "%s(error, %s) did not succeed: %s" % + (func.__name__, arg, stream.GetData())) + self.assertTrue( + expected == result, "%s(error, %s) == %s != %s" % + (func.__name__, arg, result, expected)) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbdata/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbdata/main.cpp new file mode 100644 index 00000000000..78e071c931e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbdata/main.cpp @@ -0,0 +1,42 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdint.h> + +struct foo +{ + uint32_t a; + uint32_t b; + float c; + foo() : a(0), b(1), c(3.14) {} + foo(uint32_t A, uint32_t B, float C) : + a(A), + b(B), + c(C) + {} +}; + +int main (int argc, char const *argv[]) +{ + foo* foobar = new foo[2]; + + foobar[0].a = 1; + foobar[0].b = 9; + + foobar[1].a = 8; + foobar[1].b = 5; + + foobar[1].b = 7; // set breakpoint here + + foobar[1].c = 6.28; + + foo barfoo[] = {foo(1,2,3), foo(4,5,6)}; + + delete[] foobar; + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sblaunchinfo/TestSBLaunchInfo.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sblaunchinfo/TestSBLaunchInfo.py new file mode 100644 index 00000000000..44a6362ce92 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sblaunchinfo/TestSBLaunchInfo.py @@ -0,0 +1,30 @@ +""" +Test SBLaunchInfo +""" + + + +from lldbsuite.test.lldbtest import * + + +def lookup(info, key): + for i in range(info.GetNumEnvironmentEntries()): + KeyEqValue = info.GetEnvironmentEntryAtIndex(i) + Key, Value = KeyEqValue.split("=") + if Key == key: + return Value + return "" + +class TestSBLaunchInfo(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def test_environment_getset(self): + info = lldb.SBLaunchInfo(None) + info.SetEnvironmentEntries(["FOO=BAR"], False) + self.assertEquals(1, info.GetNumEnvironmentEntries()) + info.SetEnvironmentEntries(["BAR=BAZ"], True) + self.assertEquals(2, info.GetNumEnvironmentEntries()) + self.assertEquals("BAR", lookup(info, "FOO")) + self.assertEquals("BAZ", lookup(info, "BAR")) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbstructureddata/TestStructuredDataAPI.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbstructureddata/TestStructuredDataAPI.py new file mode 100644 index 00000000000..f5efdfa8b37 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbstructureddata/TestStructuredDataAPI.py @@ -0,0 +1,199 @@ +""" +Test some SBStructuredData API. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestStructuredDataAPI(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def test(self): + self.structured_data_api_test() + + @add_test_categories(['pyapi']) + def structured_data_api_test(self): + error = lldb.SBError() + s = lldb.SBStream() + s.Print( + "{\"key_dict\":{\"key_string\":\"STRING\",\"key_int\":3,\"key_float\":2.99,\"key_bool\":true,\"key_array\":[\"23\",\"arr\"]}}") + example = lldb.SBStructuredData() + + # Check SetFromJSON API for dictionaries, integers, floating point + # values, strings and arrays + error = example.SetFromJSON(s) + if not error.Success(): + self.fail("FAILED: " + error.GetCString()) + + # Tests for invalid data type + self.invalid_struct_test(example) + + dict_struct = lldb.SBStructuredData() + dict_struct = example.GetValueForKey("key_dict") + + # Tests for dictionary data type + self.dictionary_struct_test(example) + + # Tests for string data type + self.string_struct_test(dict_struct) + + # Tests for integer data type + self.int_struct_test(dict_struct) + + # Tests for floating point data type + self.double_struct_test(dict_struct) + + # Tests for boolean data type + self.bool_struct_test(dict_struct) + + # Tests for array data type + self.array_struct_test(dict_struct) + + def invalid_struct_test(self, example): + invalid_struct = lldb.SBStructuredData() + invalid_struct = example.GetValueForKey("invalid_key") + if invalid_struct.IsValid(): + self.fail("An invalid object should have been returned") + + # Check Type API + if not invalid_struct.GetType() == lldb.eStructuredDataTypeInvalid: + self.fail("Wrong type returned: " + str(invalid_struct.GetType())) + + def dictionary_struct_test(self, example): + # Check API returning a valid SBStructuredData of 'dictionary' type + dict_struct = lldb.SBStructuredData() + dict_struct = example.GetValueForKey("key_dict") + if not dict_struct.IsValid(): + self.fail("A valid object should have been returned") + + # Check Type API + if not dict_struct.GetType() == lldb.eStructuredDataTypeDictionary: + self.fail("Wrong type returned: " + str(dict_struct.GetType())) + + # Check Size API for 'dictionary' type + if not dict_struct.GetSize() == 5: + self.fail("Wrong no of elements returned: " + + str(dict_struct.GetSize())) + + def string_struct_test(self, dict_struct): + string_struct = lldb.SBStructuredData() + string_struct = dict_struct.GetValueForKey("key_string") + if not string_struct.IsValid(): + self.fail("A valid object should have been returned") + + # Check Type API + if not string_struct.GetType() == lldb.eStructuredDataTypeString: + self.fail("Wrong type returned: " + str(string_struct.GetType())) + + # Check API returning 'string' value + output = string_struct.GetStringValue(25) + if not "STRING" in output: + self.fail("wrong output: " + output) + + # Calling wrong API on a SBStructuredData + # (e.g. getting an integer from a string type structure) + output = string_struct.GetIntegerValue() + if output: + self.fail( + "Valid integer value " + + str(output) + + " returned for a string object") + + def int_struct_test(self, dict_struct): + # Check a valid SBStructuredData containing an 'integer' by + int_struct = lldb.SBStructuredData() + int_struct = dict_struct.GetValueForKey("key_int") + if not int_struct.IsValid(): + self.fail("A valid object should have been returned") + + # Check Type API + if not int_struct.GetType() == lldb.eStructuredDataTypeInteger: + self.fail("Wrong type returned: " + str(int_struct.GetType())) + + # Check API returning 'integer' value + output = int_struct.GetIntegerValue() + if not output == 3: + self.fail("wrong output: " + str(output)) + + # Calling wrong API on a SBStructuredData + # (e.g. getting a string value from an integer type structure) + output = int_struct.GetStringValue(25) + if output: + self.fail( + "Valid string " + + output + + " returned for an integer object") + + def double_struct_test(self, dict_struct): + floating_point_struct = lldb.SBStructuredData() + floating_point_struct = dict_struct.GetValueForKey("key_float") + if not floating_point_struct.IsValid(): + self.fail("A valid object should have been returned") + + # Check Type API + if not floating_point_struct.GetType() == lldb.eStructuredDataTypeFloat: + self.fail("Wrong type returned: " + + str(floating_point_struct.GetType())) + + # Check API returning 'double' value + output = floating_point_struct.GetFloatValue() + if not output == 2.99: + self.fail("wrong output: " + str(output)) + + def bool_struct_test(self, dict_struct): + bool_struct = lldb.SBStructuredData() + bool_struct = dict_struct.GetValueForKey("key_bool") + if not bool_struct.IsValid(): + self.fail("A valid object should have been returned") + + # Check Type API + if not bool_struct.GetType() == lldb.eStructuredDataTypeBoolean: + self.fail("Wrong type returned: " + str(bool_struct.GetType())) + + # Check API returning 'bool' value + output = bool_struct.GetBooleanValue() + if not output: + self.fail("wrong output: " + str(output)) + + def array_struct_test(self, dict_struct): + # Check API returning a valid SBStructuredData of 'array' type + array_struct = lldb.SBStructuredData() + array_struct = dict_struct.GetValueForKey("key_array") + if not array_struct.IsValid(): + self.fail("A valid object should have been returned") + + # Check Type API + if not array_struct.GetType() == lldb.eStructuredDataTypeArray: + self.fail("Wrong type returned: " + str(array_struct.GetType())) + + # Check Size API for 'array' type + if not array_struct.GetSize() == 2: + self.fail("Wrong no of elements returned: " + + str(array_struct.GetSize())) + + # Check API returning a valid SBStructuredData for different 'array' + # indices + string_struct = array_struct.GetItemAtIndex(0) + if not string_struct.IsValid(): + self.fail("A valid object should have been returned") + if not string_struct.GetType() == lldb.eStructuredDataTypeString: + self.fail("Wrong type returned: " + str(string_struct.GetType())) + output = string_struct.GetStringValue(5) + if not output == "23": + self.fail("wrong output: " + str(output)) + + string_struct = array_struct.GetItemAtIndex(1) + if not string_struct.IsValid(): + self.fail("A valid object should have been returned") + if not string_struct.GetType() == lldb.eStructuredDataTypeString: + self.fail("Wrong type returned: " + str(string_struct.GetType())) + output = string_struct.GetStringValue(5) + if not output == "arr": + self.fail("wrong output: " + str(output)) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbtype_typeclass/TestSBTypeTypeClass.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbtype_typeclass/TestSBTypeTypeClass.py new file mode 100644 index 00000000000..a06dd7a1424 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbtype_typeclass/TestSBTypeTypeClass.py @@ -0,0 +1,10 @@ +from lldbsuite.test import decorators +from lldbsuite.test import lldbinline + +lldbinline.MakeInlineTest( + __file__, globals(), [ + decorators.skipIfFreeBSD, decorators.skipIfLinux, + decorators.skipIfWindows, decorators.skipIfNetBSD, + decorators.expectedFailureAll( + oslist=['macosx'], archs=['i386'], + bugnumber='rdar://28656677')]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbtype_typeclass/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbtype_typeclass/main.m new file mode 100644 index 00000000000..8e9601e42eb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbtype_typeclass/main.m @@ -0,0 +1,33 @@ +//===-- main.m --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#import <Foundation/Foundation.h> + +@interface ThisClassTestsThings : NSObject +@end + +@implementation ThisClassTestsThings +- (int)doSomething { + + id s = self; + NSLog(@"%@",s); //% s = self.frame().FindVariable("s"); s.SetPreferDynamicValue(lldb.eDynamicCanRunTarget) + //% s_type = s.GetType() + //% typeClass = s_type.GetTypeClass() + //% condition = (typeClass == lldb.eTypeClassClass) or (typeClass ==lldb.eTypeClassObjCObject) or (typeClass == lldb.eTypeClassObjCInterface) or (typeClass == lldb.eTypeClassObjCObjectPointer) or (typeClass == lldb.eTypeClassPointer) + //% self.assertTrue(condition, "s has the wrong TypeClass") + return 0; +} +- (id)init { + return (self = [super init]); +} +@end + + +int main (int argc, char const *argv[]) +{ + return [[[ThisClassTestsThings alloc] init] doSomething]; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbvalue_const_addrof/TestSBValueConstAddrOf.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbvalue_const_addrof/TestSBValueConstAddrOf.py new file mode 100644 index 00000000000..a3d43c1bdee --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbvalue_const_addrof/TestSBValueConstAddrOf.py @@ -0,0 +1,3 @@ +import lldbsuite.test.lldbinline as lldbinline + +lldbinline.MakeInlineTest(__file__, globals()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbvalue_const_addrof/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbvalue_const_addrof/main.cpp new file mode 100644 index 00000000000..318a45bc21a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbvalue_const_addrof/main.cpp @@ -0,0 +1,40 @@ +#include <stdio.h> +#include <stdint.h> + +struct RegisterContext +{ + uintptr_t r0; + uintptr_t r1; + uintptr_t r2; + uintptr_t r3; + uintptr_t r4; + uintptr_t pc; + uintptr_t fp; + uintptr_t sp; +}; + +struct ThreadInfo { + uint32_t tid; + const char *name; + RegisterContext regs; + ThreadInfo *next; +}; +int main (int argc, char const *argv[], char const *envp[]); + +ThreadInfo g_thread2 = { 0x2222, "thread2", { 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, (uintptr_t)&main, 0x2006, 0x2007 }, NULL }; +ThreadInfo g_thread1 = { 0x1111, "thread1", { 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, (uintptr_t)&main, 0x1006, 0x1007 }, &g_thread2 }; +ThreadInfo *g_thread_list_ptr = &g_thread1; + +int main (int argc, char const *argv[], char const *envp[]) +{ + printf ("g_thread_list is %p\n", g_thread_list_ptr); + return 0; //% v = self.dbg.GetSelectedTarget().FindFirstGlobalVariable('g_thread_list_ptr') + //% v_gla = v.GetChildMemberWithName('regs').GetLoadAddress() + //% v_aof = v.GetChildMemberWithName('regs').AddressOf().GetValueAsUnsigned(lldb.LLDB_INVALID_ADDRESS) + //% expr = '(%s)0x%x' % (v.GetType().GetName(), v.GetValueAsUnsigned(0)) + //% e = v.CreateValueFromExpression('e', expr) + //% e_gla = e.GetChildMemberWithName('regs').GetLoadAddress() + //% e_aof = e.GetChildMemberWithName('regs').AddressOf().GetValueAsUnsigned(lldb.LLDB_INVALID_ADDRESS) + //% self.assertTrue(v_gla == e_gla, "GetLoadAddress() differs") + //% self.assertTrue(v_aof == e_aof, "AddressOf() differs") +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbvalue_persist/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbvalue_persist/Makefile new file mode 100644 index 00000000000..b5256564c2f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbvalue_persist/Makefile @@ -0,0 +1,6 @@ +CXX_SOURCES := main.cpp + +# Clean renamed executable on 'make clean' +clean: OBJECTS+=no_synth + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbvalue_persist/TestSBValuePersist.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbvalue_persist/TestSBValuePersist.py new file mode 100644 index 00000000000..1662f69312d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbvalue_persist/TestSBValuePersist.py @@ -0,0 +1,82 @@ +"""Test SBValue::Persist""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class SBValuePersistTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + @add_test_categories(['pyapi']) + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24772") + def test(self): + """Test SBValue::Persist""" + self.build() + self.setTearDownCleanup() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + 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 synthetic clear', check=False) + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + + foo = self.frame().FindVariable("foo") + bar = self.frame().FindVariable("bar") + baz = self.frame().FindVariable("baz") + + self.assertTrue(foo.IsValid(), "foo is not valid") + self.assertTrue(bar.IsValid(), "bar is not valid") + self.assertTrue(baz.IsValid(), "baz is not valid") + + fooPersist = foo.Persist() + barPersist = bar.Persist() + bazPersist = baz.Persist() + + self.assertTrue(fooPersist.IsValid(), "fooPersist is not valid") + self.assertTrue(barPersist.IsValid(), "barPersist is not valid") + self.assertTrue(bazPersist.IsValid(), "bazPersist is not valid") + + self.assertTrue( + fooPersist.GetValueAsUnsigned(0) == 10, + "fooPersist != 10") + self.assertTrue( + barPersist.GetPointeeData().sint32[0] == 4, + "barPersist != 4") + self.assertTrue(bazPersist.GetSummary() == '"85"', "bazPersist != 85") + + self.runCmd("continue") + + self.assertTrue(fooPersist.IsValid(), "fooPersist is not valid") + self.assertTrue(barPersist.IsValid(), "barPersist is not valid") + self.assertTrue(bazPersist.IsValid(), "bazPersist is not valid") + + self.assertTrue( + fooPersist.GetValueAsUnsigned(0) == 10, + "fooPersist != 10") + self.assertTrue( + barPersist.GetPointeeData().sint32[0] == 4, + "barPersist != 4") + self.assertTrue(bazPersist.GetSummary() == '"85"', "bazPersist != 85") + + self.expect("expr *(%s)" % (barPersist.GetName()), substrs=['= 4']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbvalue_persist/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbvalue_persist/main.cpp new file mode 100644 index 00000000000..c54339f3bba --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/sbvalue_persist/main.cpp @@ -0,0 +1,14 @@ +#include <vector> +#include <string> + +void f() {} + +int main() { + int foo = 10; + int *bar = new int(4); + std::string baz = "85"; + + f(); // break here + f(); // break here + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/section/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/section/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/section/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/section/TestSectionAPI.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/section/TestSectionAPI.py new file mode 100644 index 00000000000..1513b98b772 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/section/TestSectionAPI.py @@ -0,0 +1,42 @@ +""" +Test SBSection APIs. +""" + + + +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class SectionAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @add_test_categories(['pyapi']) + def test_get_target_byte_size(self): + d = {'EXE': 'b.out'} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + exe = self.getBuildArtifact('b.out') + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # find the .data section of the main module + mod = target.GetModuleAtIndex(0) + data_section = None + for s in mod.sections: + sect_type = s.GetSectionType() + if sect_type == lldb.eSectionTypeData: + data_section = s + break + elif sect_type == lldb.eSectionTypeContainer: + for i in range(s.GetNumSubSections()): + ss = s.GetSubSectionAtIndex(i) + sect_type = ss.GetSectionType() + if sect_type == lldb.eSectionTypeData: + data_section = ss + break + + self.assertIsNotNone(data_section) + self.assertEqual(data_section.target_byte_size, 1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/section/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/section/main.c new file mode 100644 index 00000000000..f12ef5afb7a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/section/main.c @@ -0,0 +1,27 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> +#include <string.h> + +// This simple program is to test the lldb Python API SBSection. It includes +// somes global data, and so the build process produces a DATA section, which +// the test code can use to query for the target byte size + +char my_global_var_of_char_type = 'X'; + +int main (int argc, char const *argv[]) +{ + // this code just "does something" with the global so that it is not + // optimised away + if (argc > 1 && strlen(argv[1])) + { + my_global_var_of_char_type += argv[1][0]; + } + + return my_global_var_of_char_type; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/signals/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/signals/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/signals/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/signals/TestSignalsAPI.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/signals/TestSignalsAPI.py new file mode 100644 index 00000000000..602fee457c2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/signals/TestSignalsAPI.py @@ -0,0 +1,56 @@ +""" +Test SBProcess APIs, including ReadMemory(), WriteMemory(), and others. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil +from lldbsuite.test.lldbutil import get_stopped_thread, state_type_to_str + + +class SignalsAPITestCase(TestBase): + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + @add_test_categories(['pyapi']) + @skipIfWindows # Windows doesn't have signals + def test_ignore_signal(self): + """Test Python SBUnixSignals.Suppress/Stop/Notify() API.""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + line = line_number( + "main.cpp", + "// Set break point at this line and setup signal ignores.") + breakpoint = target.BreakpointCreateByLocation("main.cpp", line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + # Launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint") + + unix_signals = process.GetUnixSignals() + sigint = unix_signals.GetSignalNumberFromName("SIGINT") + unix_signals.SetShouldSuppress(sigint, True) + unix_signals.SetShouldStop(sigint, False) + unix_signals.SetShouldNotify(sigint, False) + + process.Continue() + self.assertTrue( + process.state == lldb.eStateExited, + "The process should have exited") + self.assertTrue( + process.GetExitStatus() == 0, + "The process should have returned 0") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/signals/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/signals/main.cpp new file mode 100644 index 00000000000..c4c5a00dd09 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/signals/main.cpp @@ -0,0 +1,27 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> +#include <sys/types.h> +#if defined(_WIN32) +#include <windows.h> +#else +#include <unistd.h> +#include <signal.h> +#endif + +// This simple program is to test the lldb Python API related to process. + +int main (int argc, char const *argv[]) +{ +#if defined(_WIN32) + ::ExitProcess(1); +#else + kill(getpid(), SIGINT); // Set break point at this line and setup signal ignores. +#endif + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/TestSymbolContext.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/TestSymbolContext.py new file mode 100644 index 00000000000..0c1ad83c84d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/TestSymbolContext.py @@ -0,0 +1,107 @@ +""" +Test SBSymbolContext APIs. +""" + +from __future__ import print_function + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class SymbolContextAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to of function 'c'. + self.line = line_number( + 'main.c', '// Find the line number of function "c" here.') + + @add_test_categories(['pyapi']) + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778") + def test(self): + """Exercise SBSymbolContext API extensively.""" + self.build() + exe = self.getBuildArtifact("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) + + # 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.line. + 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) + self.assertTrue(frame0.GetLineEntry().GetLine() == self.line) + + # Now get the SBSymbolContext from this frame. We want everything. :-) + context = frame0.GetSymbolContext(lldb.eSymbolContextEverything) + self.assertTrue(context) + + # Get the description of this module. + module = context.GetModule() + desc = lldbutil.get_description(module) + self.expect(desc, "The module should match", exe=False, + substrs=[self.getBuildArtifact("a.out")]) + + compileUnit = context.GetCompileUnit() + self.expect( + str(compileUnit), + "The compile unit should match", + exe=False, + substrs=[self.getSourcePath('main.c')]) + + function = context.GetFunction() + self.assertTrue(function) + #print("function:", function) + + block = context.GetBlock() + self.assertTrue(block) + #print("block:", block) + + lineEntry = context.GetLineEntry() + #print("line entry:", lineEntry) + self.expect( + lineEntry.GetFileSpec().GetDirectory(), + "The line entry should have the correct directory", + exe=False, + substrs=[self.mydir]) + self.expect( + lineEntry.GetFileSpec().GetFilename(), + "The line entry should have the correct filename", + exe=False, + substrs=['main.c']) + self.assertTrue(lineEntry.GetLine() == self.line, + "The line entry's line number should match ") + + symbol = context.GetSymbol() + self.assertTrue( + function.GetName() == symbol.GetName() and symbol.GetName() == 'c', + "The symbol name should be 'c'") + + sc_list = lldb.SBSymbolContextList() + sc_list.Append(context) + self.assertEqual(len(sc_list), 1) + for sc in sc_list: + self.assertEqual(lineEntry, sc.GetLineEntry()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/main.c new file mode 100644 index 00000000000..4e68fb764b8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/main.c @@ -0,0 +1,50 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +// This simple program is to test the lldb Python API SBSymbolContext. +// When stopped on a frame, we can get the symbol context using the SBFrame API +// SBFrame.GetSymbolContext(). + +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) +{ + 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); + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/Makefile new file mode 100644 index 00000000000..ccaa0edcf5f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := file1.cpp file2.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/TestSymbolContextTwoFiles.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/TestSymbolContextTwoFiles.py new file mode 100644 index 00000000000..27d1b60a507 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/TestSymbolContextTwoFiles.py @@ -0,0 +1,79 @@ +""" +Test SBSymbolContext APIs. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class SymbolContextTwoFilesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @add_test_categories(['pyapi']) + @expectedFailureAll(oslist=["windows"]) + def test_lookup_by_address(self): + """Test lookup by address in a module with multiple compilation units""" + self.build() + exe = self.getBuildArtifact("a.out") + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + module = target.GetModuleAtIndex(0) + self.assertTrue(module.IsValid()) + for symbol_name in ["struct1::f()", "struct2::f()"]: + sc_list = module.FindFunctions(symbol_name, lldb.eSymbolTypeCode) + self.assertTrue(1, sc_list.GetSize()) + symbol_address = sc_list.GetContextAtIndex( + 0).GetSymbol().GetStartAddress() + self.assertTrue(symbol_address.IsValid()) + sc_by_address = module.ResolveSymbolContextForAddress( + symbol_address, lldb.eSymbolContextFunction) + self.assertEqual(symbol_name, + sc_by_address.GetFunction().GetName()) + + @add_test_categories(['pyapi']) + def test_ranges_in_multiple_compile_unit(self): + """This test verifies that we correctly handle the case when multiple + compile unit contains DW_AT_ranges and DW_AT_ranges_base attributes.""" + self.build() + exe = self.getBuildArtifact("a.out") + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + source1 = "file1.cpp" + line1 = line_number(source1, '// Break1') + breakpoint1 = target.BreakpointCreateByLocation(source1, line1) + self.assertIsNotNone(breakpoint1) + self.assertTrue(breakpoint1.IsValid()) + + source2 = "file2.cpp" + line2 = line_number(source2, '// Break2') + breakpoint2 = target.BreakpointCreateByLocation(source2, line2) + self.assertIsNotNone(breakpoint2) + self.assertTrue(breakpoint2.IsValid()) + + process = target.LaunchSimple(None, None, self.get_process_working_directory()) + self.assertIsNotNone(process, PROCESS_IS_VALID) + + threads = lldbutil.get_threads_stopped_at_breakpoint( + process, breakpoint2) + self.assertEqual(len(threads), 1) + frame = threads[0].GetFrameAtIndex(0) + value = frame.FindVariable("x") + self.assertTrue(value.IsValid()) + + process.Continue() + + threads = lldbutil.get_threads_stopped_at_breakpoint( + process, breakpoint1) + self.assertEqual(len(threads), 1) + frame = threads[0].GetFrameAtIndex(0) + value = frame.FindVariable("x") + self.assertTrue(value.IsValid()) + + process.Continue() diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/decls.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/decls.h new file mode 100644 index 00000000000..7c804584206 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/decls.h @@ -0,0 +1,11 @@ +struct struct1 { + ~struct1(); + static void f(); +}; + +struct struct2 { + ~struct2(); + static void f(); +}; + +int g(); diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/file1.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/file1.cpp new file mode 100644 index 00000000000..327d0fb7718 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/file1.cpp @@ -0,0 +1,21 @@ +#include "decls.h" + +int g() { + return 1; +} + +struct1::~struct1() { + int x = g(); // Break1 +} + +void struct1::f() {} + +int main() { + struct1::f(); + struct2::f(); + + struct1 s1; + struct2 s2; + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/file2.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/file2.cpp new file mode 100644 index 00000000000..109e01572ed --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/file2.cpp @@ -0,0 +1,7 @@ +#include "decls.h" + +struct2::~struct2() { + int x = g(); // Break2 +} + +void struct2::f() {} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/target/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/target/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/target/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/target/TestTargetAPI.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/target/TestTargetAPI.py new file mode 100644 index 00000000000..6e5be6e8f17 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/target/TestTargetAPI.py @@ -0,0 +1,426 @@ +""" +Test SBTarget APIs. +""" + +from __future__ import print_function + + +import unittest2 +import os +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TargetAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + 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 for breakpoint 1 here.') + self.line2 = line_number( + 'main.c', '// Find the line number for breakpoint 2 here.') + self.line_main = line_number( + "main.c", "// Set a break at entry to main.") + + # rdar://problem/9700873 + # Find global variable value fails for dwarf if inferior not started + # (Was CrashTracer: [USER] 1 crash in Python at _lldb.so: lldb_private::MemoryCache::Read + 94) + # + # It does not segfaults now. But for dwarf, the variable value is None if + # the inferior process does not exist yet. The radar has been updated. + #@unittest232.skip("segmentation fault -- skipping") + @add_test_categories(['pyapi']) + def test_find_global_variables(self): + """Exercise SBTarget.FindGlobalVariables() API.""" + d = {'EXE': 'b.out'} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + self.find_global_variables('b.out') + + @add_test_categories(['pyapi']) + def test_find_compile_units(self): + """Exercise SBTarget.FindCompileUnits() API.""" + d = {'EXE': 'b.out'} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + self.find_compile_units(self.getBuildArtifact('b.out')) + + @add_test_categories(['pyapi']) + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778") + def test_find_functions(self): + """Exercise SBTarget.FindFunctions() API.""" + d = {'EXE': 'b.out'} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + self.find_functions('b.out') + + @add_test_categories(['pyapi']) + def test_get_description(self): + """Exercise SBTarget.GetDescription() API.""" + self.build() + self.get_description() + + @add_test_categories(['pyapi']) + @expectedFailureAll(oslist=["windows"], bugnumber='llvm.org/pr21765') + def test_resolve_symbol_context_with_address(self): + """Exercise SBTarget.ResolveSymbolContextForAddress() API.""" + self.build() + self.resolve_symbol_context_with_address() + + @add_test_categories(['pyapi']) + def test_get_platform(self): + d = {'EXE': 'b.out'} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + target = self.create_simple_target('b.out') + platform = target.platform + self.assertTrue(platform, VALID_PLATFORM) + + @add_test_categories(['pyapi']) + def test_get_data_byte_size(self): + d = {'EXE': 'b.out'} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + target = self.create_simple_target('b.out') + self.assertEqual(target.data_byte_size, 1) + + @add_test_categories(['pyapi']) + def test_get_code_byte_size(self): + d = {'EXE': 'b.out'} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + target = self.create_simple_target('b.out') + self.assertEqual(target.code_byte_size, 1) + + @add_test_categories(['pyapi']) + def test_resolve_file_address(self): + d = {'EXE': 'b.out'} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + target = self.create_simple_target('b.out') + + # find the file address in the .data section of the main + # module + data_section = self.find_data_section(target) + data_section_addr = data_section.file_addr + + # resolve the above address, and compare the address produced + # by the resolution against the original address/section + res_file_addr = target.ResolveFileAddress(data_section_addr) + self.assertTrue(res_file_addr.IsValid()) + + self.assertEqual(data_section_addr, res_file_addr.file_addr) + + data_section2 = res_file_addr.section + self.assertIsNotNone(data_section2) + self.assertEqual(data_section.name, data_section2.name) + + @add_test_categories(['pyapi']) + def test_read_memory(self): + d = {'EXE': 'b.out'} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + target = self.create_simple_target('b.out') + + breakpoint = target.BreakpointCreateByLocation( + "main.c", self.line_main) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + # Put debugger into synchronous mode so when we target.LaunchSimple returns + # it will guaranteed to be at the breakpoint + self.dbg.SetAsync(False) + + # Launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + # find the file address in the .data section of the main + # module + data_section = self.find_data_section(target) + sb_addr = lldb.SBAddress(data_section, 0) + error = lldb.SBError() + content = target.ReadMemory(sb_addr, 1, error) + self.assertTrue(error.Success(), "Make sure memory read succeeded") + self.assertEqual(len(content), 1) + + def create_simple_target(self, fn): + exe = self.getBuildArtifact(fn) + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + return target + + def find_data_section(self, target): + mod = target.GetModuleAtIndex(0) + data_section = None + for s in mod.sections: + sect_type = s.GetSectionType() + if sect_type == lldb.eSectionTypeData: + data_section = s + break + elif sect_type == lldb.eSectionTypeContainer: + for i in range(s.GetNumSubSections()): + ss = s.GetSubSectionAtIndex(i) + sect_type = ss.GetSectionType() + if sect_type == lldb.eSectionTypeData: + data_section = ss + break + + self.assertIsNotNone(data_section) + return data_section + + def find_global_variables(self, exe_name): + """Exercise SBTaget.FindGlobalVariables() API.""" + exe = self.getBuildArtifact(exe_name) + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # rdar://problem/9700873 + # Find global variable value fails for dwarf if inferior not started + # (Was CrashTracer: [USER] 1 crash in Python at _lldb.so: lldb_private::MemoryCache::Read + 94) + # + # Remove the lines to create a breakpoint and to start the inferior + # which are workarounds for the dwarf case. + + breakpoint = target.BreakpointCreateByLocation('main.c', self.line1) + 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) + # Make sure we hit our breakpoint: + thread_list = lldbutil.get_threads_stopped_at_breakpoint( + process, breakpoint) + self.assertTrue(len(thread_list) == 1) + + value_list = target.FindGlobalVariables( + 'my_global_var_of_char_type', 3) + self.assertTrue(value_list.GetSize() == 1) + my_global_var = value_list.GetValueAtIndex(0) + self.DebugSBValue(my_global_var) + self.assertTrue(my_global_var) + self.expect(my_global_var.GetName(), exe=False, + startstr="my_global_var_of_char_type") + self.expect(my_global_var.GetTypeName(), exe=False, + startstr="char") + self.expect(my_global_var.GetValue(), exe=False, + startstr="'X'") + + # While we are at it, let's also exercise the similar + # SBModule.FindGlobalVariables() API. + for m in target.module_iter(): + if os.path.normpath(m.GetFileSpec().GetDirectory()) == self.getBuildDir() and m.GetFileSpec().GetFilename() == exe_name: + value_list = m.FindGlobalVariables( + target, 'my_global_var_of_char_type', 3) + self.assertTrue(value_list.GetSize() == 1) + self.assertTrue( + value_list.GetValueAtIndex(0).GetValue() == "'X'") + break + + def find_compile_units(self, exe): + """Exercise SBTarget.FindCompileUnits() API.""" + source_name = "main.c" + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + list = target.FindCompileUnits(lldb.SBFileSpec(source_name, False)) + # Executable has been built just from one source file 'main.c', + # so we may check only the first element of list. + self.assertTrue( + list[0].GetCompileUnit().GetFileSpec().GetFilename() == source_name) + + def find_functions(self, exe_name): + """Exercise SBTaget.FindFunctions() API.""" + exe = self.getBuildArtifact(exe_name) + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + list = target.FindFunctions('c', lldb.eFunctionNameTypeAuto) + self.assertTrue(list.GetSize() == 1) + + for sc in list: + self.assertTrue( + sc.GetModule().GetFileSpec().GetFilename() == exe_name) + self.assertTrue(sc.GetSymbol().GetName() == 'c') + + def get_description(self): + """Exercise SBTaget.GetDescription() API.""" + exe = self.getBuildArtifact("a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + from lldbsuite.test.lldbutil import get_description + + # get_description() allows no option to mean + # lldb.eDescriptionLevelBrief. + desc = get_description(target) + #desc = get_description(target, option=lldb.eDescriptionLevelBrief) + if not desc: + self.fail("SBTarget.GetDescription() failed") + self.expect(desc, exe=False, + substrs=['a.out']) + self.expect(desc, exe=False, matching=False, + substrs=['Target', 'Module', 'Breakpoint']) + + desc = get_description(target, option=lldb.eDescriptionLevelFull) + if not desc: + self.fail("SBTarget.GetDescription() failed") + self.expect(desc, exe=False, + substrs=['a.out', 'Target', 'Module', 'Breakpoint']) + + @not_remote_testsuite_ready + @add_test_categories(['pyapi']) + @no_debug_info_test + def test_launch_new_process_and_redirect_stdout(self): + """Exercise SBTaget.Launch() API with redirected stdout.""" + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Add an extra twist of stopping the inferior in a breakpoint, and then continue till it's done. + # We should still see the entire stdout redirected once the process is + # finished. + line = line_number('main.c', '// a(3) -> c(3)') + breakpoint = target.BreakpointCreateByLocation('main.c', line) + + # Now launch the process, do not stop at entry point, and redirect stdout to "stdout.txt" file. + # The inferior should run to completion after "process.Continue()" + # call. + local_path = self.getBuildArtifact("stdout.txt") + if os.path.exists(local_path): + os.remove(local_path) + + if lldb.remote_platform: + stdout_path = lldbutil.append_to_process_working_directory(self, + "lldb-stdout-redirect.txt") + else: + stdout_path = local_path + error = lldb.SBError() + process = target.Launch( + self.dbg.GetListener(), + None, + None, + None, + stdout_path, + None, + None, + 0, + False, + error) + process.Continue() + #self.runCmd("process status") + if lldb.remote_platform: + # copy output file to host + lldb.remote_platform.Get( + lldb.SBFileSpec(stdout_path), + lldb.SBFileSpec(local_path)) + + # The 'stdout.txt' file should now exist. + self.assertTrue( + os.path.isfile(local_path), + "'stdout.txt' exists due to redirected stdout via SBTarget.Launch() API.") + + # Read the output file produced by running the program. + with open(local_path, 'r') as f: + output = f.read() + + self.expect(output, exe=False, + substrs=["a(1)", "b(2)", "a(3)"]) + + def resolve_symbol_context_with_address(self): + """Exercise SBTaget.ResolveSymbolContextForAddress() API.""" + exe = self.getBuildArtifact("a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Now create the two breakpoints inside function 'a'. + breakpoint1 = target.BreakpointCreateByLocation('main.c', self.line1) + breakpoint2 = target.BreakpointCreateByLocation('main.c', self.line2) + #print("breakpoint1:", breakpoint1) + #print("breakpoint2:", breakpoint2) + self.assertTrue(breakpoint1 and + breakpoint1.GetNumLocations() == 1, + VALID_BREAKPOINT) + self.assertTrue(breakpoint2 and + breakpoint2.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. + self.assertTrue(process.GetState() == lldb.eStateStopped) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint condition") + #self.runCmd("process status") + frame0 = thread.GetFrameAtIndex(0) + lineEntry = frame0.GetLineEntry() + self.assertTrue(lineEntry.GetLine() == self.line1) + + address1 = lineEntry.GetStartAddress() + + # Continue the inferior, the breakpoint 2 should be hit. + process.Continue() + self.assertTrue(process.GetState() == lldb.eStateStopped) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint condition") + #self.runCmd("process status") + frame0 = thread.GetFrameAtIndex(0) + lineEntry = frame0.GetLineEntry() + self.assertTrue(lineEntry.GetLine() == self.line2) + + address2 = lineEntry.GetStartAddress() + + #print("address1:", address1) + #print("address2:", address2) + + # Now call SBTarget.ResolveSymbolContextForAddress() with the addresses + # from our line entry. + context1 = target.ResolveSymbolContextForAddress( + address1, lldb.eSymbolContextEverything) + context2 = target.ResolveSymbolContextForAddress( + address2, lldb.eSymbolContextEverything) + + self.assertTrue(context1 and context2) + #print("context1:", context1) + #print("context2:", context2) + + # Verify that the context point to the same function 'a'. + symbol1 = context1.GetSymbol() + symbol2 = context2.GetSymbol() + self.assertTrue(symbol1 and symbol2) + #print("symbol1:", symbol1) + #print("symbol2:", symbol2) + + from lldbsuite.test.lldbutil import get_description + desc1 = get_description(symbol1) + desc2 = get_description(symbol2) + self.assertTrue(desc1 and desc2 and desc1 == desc2, + "The two addresses should resolve to the same symbol") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/target/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/target/main.c new file mode 100644 index 00000000000..d075f2cf2d3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/target/main.c @@ -0,0 +1,59 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +// This simple program is to test the lldb Python API SBTarget. +// +// When stopped on breakppint 1, and then 2, we can get the line entries using +// SBFrame API SBFrame.GetLineEntry(). We'll get the start addresses for the +// two line entries; with the start address (of SBAddress type), we can then +// resolve the symbol context using the SBTarget API +// SBTarget.ResolveSymbolContextForAddress(). +// +// The two symbol context should point to the same symbol, i.e., 'a' function. + +char my_global_var_of_char_type = 'X'; // Test SBTarget.FindGlobalVariables(...). + +int a(int); +int b(int); +int c(int); + +int a(int val) +{ + if (val <= 1) // Find the line number for breakpoint 1 here. + val = b(val); + else if (val >= 3) + val = c(val); + + return val; // Find the line number for breakpoint 2 here. +} + +int b(int val) +{ + return c(val); +} + +int c(int val) +{ + return val + 3; +} + +int main (int argc, char const *argv[]) +{ + // Set a break at entry to main. + 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/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/thread/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/thread/Makefile new file mode 100644 index 00000000000..30749db9a67 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/thread/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES ?= main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/thread/TestThreadAPI.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/thread/TestThreadAPI.py new file mode 100644 index 00000000000..91241385293 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/thread/TestThreadAPI.py @@ -0,0 +1,282 @@ +""" +Test SBThread APIs. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil +from lldbsuite.test.lldbutil import get_stopped_thread, get_caller_symbol + + +class ThreadAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @add_test_categories(['pyapi']) + def test_get_process(self): + """Test Python SBThread.GetProcess() API.""" + self.build() + self.get_process() + + @add_test_categories(['pyapi']) + def test_get_stop_description(self): + """Test Python SBThread.GetStopDescription() API.""" + self.build() + self.get_stop_description() + + @add_test_categories(['pyapi']) + def test_run_to_address(self): + """Test Python SBThread.RunToAddress() API.""" + # We build a different executable than the default build() does. + d = {'CXX_SOURCES': 'main2.cpp', 'EXE': self.exe_name} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + self.run_to_address(self.exe_name) + + @add_test_categories(['pyapi']) + @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr20476') + @expectedFailureAll(oslist=["windows"]) + @expectedFailureNetBSD + def test_step_out_of_malloc_into_function_b(self): + """Test Python SBThread.StepOut() API to step out of a malloc call where the call site is at function b().""" + # We build a different executable than the default build() does. + d = {'CXX_SOURCES': 'main2.cpp', 'EXE': self.exe_name} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + self.step_out_of_malloc_into_function_b(self.exe_name) + + @add_test_categories(['pyapi']) + def test_step_over_3_times(self): + """Test Python SBThread.StepOver() API.""" + # We build a different executable than the default build() does. + d = {'CXX_SOURCES': 'main2.cpp', 'EXE': self.exe_name} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + self.step_over_3_times(self.exe_name) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number within main.cpp to break inside main(). + self.break_line = line_number( + "main.cpp", "// Set break point at this line and check variable 'my_char'.") + # Find the line numbers within main2.cpp for + # step_out_of_malloc_into_function_b() and step_over_3_times(). + self.step_out_of_malloc = line_number( + "main2.cpp", "// thread step-out of malloc into function b.") + self.after_3_step_overs = line_number( + "main2.cpp", "// we should reach here after 3 step-over's.") + + # We'll use the test method name as the exe_name for executable + # comppiled from main2.cpp. + self.exe_name = self.testMethodName + + def get_process(self): + """Test Python SBThread.GetProcess() API.""" + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation( + "main.cpp", self.break_line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + self.runCmd("breakpoint list") + + # Launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint") + self.runCmd("process status") + + proc_of_thread = thread.GetProcess() + #print("proc_of_thread:", proc_of_thread) + self.assertTrue(proc_of_thread.GetProcessID() + == process.GetProcessID()) + + def get_stop_description(self): + """Test Python SBThread.GetStopDescription() API.""" + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation( + "main.cpp", self.break_line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + #self.runCmd("breakpoint list") + + # Launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint") + + # Get the stop reason. GetStopDescription expects that we pass in the size of the description + # we expect plus an additional byte for the null terminator. + + # Test with a buffer that is exactly as large as the expected stop reason. + self.assertEqual("breakpoint 1.1", thread.GetStopDescription(len('breakpoint 1.1') + 1)) + + # Test some smaller buffer sizes. + self.assertEqual("breakpoint", thread.GetStopDescription(len('breakpoint') + 1)) + self.assertEqual("break", thread.GetStopDescription(len('break') + 1)) + self.assertEqual("b", thread.GetStopDescription(len('b') + 1)) + + # Test that we can pass in a much larger size and still get the right output. + self.assertEqual("breakpoint 1.1", thread.GetStopDescription(len('breakpoint 1.1') + 100)) + + def step_out_of_malloc_into_function_b(self, exe_name): + """Test Python SBThread.StepOut() API to step out of a malloc call where the call site is at function b().""" + exe = self.getBuildArtifact(exe_name) + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByName('malloc') + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + # Launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + while True: + thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint") + caller_symbol = get_caller_symbol(thread) + if not caller_symbol: + self.fail( + "Test failed: could not locate the caller symbol of malloc") + + # Our top frame may be an inlined function in malloc() (e.g., on + # FreeBSD). Apply a simple heuristic of stepping out until we find + # a non-malloc caller + while caller_symbol.startswith("malloc"): + thread.StepOut() + self.assertTrue(thread.IsValid(), + "Thread valid after stepping to outer malloc") + caller_symbol = get_caller_symbol(thread) + + if caller_symbol == "b(int)": + break + process.Continue() + + # On Linux malloc calls itself in some case. Remove the breakpoint because we don't want + # to hit it during step-out. + target.BreakpointDelete(breakpoint.GetID()) + + thread.StepOut() + self.runCmd("thread backtrace") + self.assertTrue( + thread.GetFrameAtIndex(0).GetLineEntry().GetLine() == self.step_out_of_malloc, + "step out of malloc into function b is successful") + + def step_over_3_times(self, exe_name): + """Test Python SBThread.StepOver() API.""" + exe = self.getBuildArtifact(exe_name) + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation( + 'main2.cpp', self.step_out_of_malloc) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + self.runCmd("breakpoint list") + + # Launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # Frame #0 should be on self.step_out_of_malloc. + self.assertTrue(process.GetState() == lldb.eStateStopped) + thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint condition") + self.runCmd("thread backtrace") + frame0 = thread.GetFrameAtIndex(0) + lineEntry = frame0.GetLineEntry() + self.assertTrue(lineEntry.GetLine() == self.step_out_of_malloc) + + thread.StepOver() + thread.StepOver() + thread.StepOver() + self.runCmd("thread backtrace") + + # Verify that we are stopped at the correct source line number in + # main2.cpp. + frame0 = thread.GetFrameAtIndex(0) + lineEntry = frame0.GetLineEntry() + self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete) + # Expected failure with clang as the compiler. + # rdar://problem/9223880 + # + # Which has been fixed on the lldb by compensating for inaccurate line + # table information with r140416. + self.assertTrue(lineEntry.GetLine() == self.after_3_step_overs) + + def run_to_address(self, exe_name): + """Test Python SBThread.RunToAddress() API.""" + exe = self.getBuildArtifact(exe_name) + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation( + 'main2.cpp', self.step_out_of_malloc) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + self.runCmd("breakpoint list") + + # Launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # Frame #0 should be on self.step_out_of_malloc. + self.assertTrue(process.GetState() == lldb.eStateStopped) + thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint condition") + self.runCmd("thread backtrace") + frame0 = thread.GetFrameAtIndex(0) + lineEntry = frame0.GetLineEntry() + self.assertTrue(lineEntry.GetLine() == self.step_out_of_malloc) + + # Get the start/end addresses for this line entry. + start_addr = lineEntry.GetStartAddress().GetLoadAddress(target) + end_addr = lineEntry.GetEndAddress().GetLoadAddress(target) + if self.TraceOn(): + print("start addr:", hex(start_addr)) + print("end addr:", hex(end_addr)) + + # Disable the breakpoint. + self.assertTrue(target.DisableAllBreakpoints()) + self.runCmd("breakpoint list") + + thread.StepOver() + thread.StepOver() + thread.StepOver() + self.runCmd("thread backtrace") + + # Now ask SBThread to run to the address 'start_addr' we got earlier, which + # corresponds to self.step_out_of_malloc line entry's start address. + thread.RunToAddress(start_addr) + self.runCmd("process status") + #self.runCmd("thread backtrace") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/thread/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/thread/main.cpp new file mode 100644 index 00000000000..01c8404a387 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/thread/main.cpp @@ -0,0 +1,25 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +// This simple program is to test the lldb Python API related to thread. + +char my_char = 'u'; +int my_int = 0; + +int main (int argc, char const *argv[]) +{ + for (int i = 0; i < 3; ++i) { + printf("my_char='%c'\n", my_char); + ++my_char; + } + + printf("after the loop: my_char='%c'\n", my_char); // 'my_char' should print out as 'x'. + + return 0; // Set break point at this line and check variable 'my_char'. +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/thread/main2.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/thread/main2.cpp new file mode 100644 index 00000000000..57c485c08c6 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/thread/main2.cpp @@ -0,0 +1,53 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#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); // thread step-out of malloc into function b. + if (!ptr) + return -1; + else + printf("ptr=%p\n", ptr); + return rc; // we should reach here after 3 step-over's. +} + +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 B2 = b(2); + printf("b(2) returns %d\n", B2); + + int A3 = a(3); + printf("a(3) returns %d\n", A3); + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/type/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/type/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/type/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/type/TestTypeList.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/type/TestTypeList.py new file mode 100644 index 00000000000..75a793a95b2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/type/TestTypeList.py @@ -0,0 +1,133 @@ +""" +Test SBType and SBTypeList API. +""" + +from __future__ import print_function + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TypeAndTypeListTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # We'll use the test method name as the exe_name. + self.exe_name = self.testMethodName + # Find the line number to break at. + self.source = 'main.cpp' + self.line = line_number(self.source, '// Break at this line') + + @add_test_categories(['pyapi']) + def test(self): + """Exercise SBType and SBTypeList API.""" + d = {'EXE': self.exe_name} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + exe = self.getBuildArtifact(self.exe_name) + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Create the breakpoint inside function 'main'. + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + 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) + + # Get Frame #0. + self.assertTrue(process.GetState() == lldb.eStateStopped) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint condition") + frame0 = thread.GetFrameAtIndex(0) + + # Get the type 'Task'. + type_list = target.FindTypes('Task') + if self.TraceOn(): + print( + "Size of type_list from target.FindTypes('Task') query: %d" % + type_list.GetSize()) + # a second Task make be scared up by the Objective-C runtime + self.assertTrue(len(type_list) >= 1) + for type in type_list: + self.assertTrue(type) + self.DebugSBType(type) + self.assertFalse(type.IsAnonymousType(), "Task is not anonymous") + for field in type.fields: + if field.name == "type": + for enum_member in field.type.enum_members: + self.assertTrue(enum_member) + self.DebugSBType(enum_member.type) + elif field.name == "my_type_is_nameless": + self.assertFalse( + field.type.IsAnonymousType(), + "my_type_is_nameless is not an anonymous type") + elif field.name == "my_type_is_named": + self.assertFalse( + field.type.IsAnonymousType(), + "my_type_is_named has a named type") + elif field.name == None: + self.assertTrue( + field.type.IsAnonymousType(), + "Nameless type is not anonymous") + + # Pass an empty string. LLDB should not crash. :-) + fuzz_types = target.FindTypes(None) + fuzz_type = target.FindFirstType(None) + + # Now use the SBTarget.FindFirstType() API to find 'Task'. + task_type = target.FindFirstType('Task') + self.assertTrue(task_type) + self.DebugSBType(task_type) + + # Get the reference type of 'Task', just for fun. + task_ref_type = task_type.GetReferenceType() + self.assertTrue(task_ref_type) + self.DebugSBType(task_ref_type) + + # Get the pointer type of 'Task', which is the same as task_head's + # type. + task_pointer_type = task_type.GetPointerType() + self.assertTrue(task_pointer_type) + self.DebugSBType(task_pointer_type) + + # Get variable 'task_head'. + task_head = frame0.FindVariable('task_head') + self.assertTrue(task_head, VALID_VARIABLE) + self.DebugSBValue(task_head) + task_head_type = task_head.GetType() + self.DebugSBType(task_head_type) + self.assertTrue(task_head_type.IsPointerType()) + + self.assertTrue(task_head_type == task_pointer_type) + + # Get the pointee type of 'task_head'. + task_head_pointee_type = task_head_type.GetPointeeType() + self.DebugSBType(task_head_pointee_type) + + self.assertTrue(task_type == task_head_pointee_type) + + # We'll now get the child member 'id' from 'task_head'. + id = task_head.GetChildMemberWithName('id') + self.DebugSBValue(id) + id_type = id.GetType() + self.DebugSBType(id_type) + + # SBType.GetBasicType() takes an enum 'BasicType' + # (lldb-enumerations.h). + int_type = id_type.GetBasicType(lldb.eBasicTypeInt) + self.assertTrue(id_type == int_type) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/type/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/type/main.cpp new file mode 100644 index 00000000000..b43b617b0f9 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/type/main.cpp @@ -0,0 +1,67 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +class Task { +public: + int id; + Task *next; + enum { + TASK_TYPE_1, + TASK_TYPE_2 + } type; + // This struct is anonymous b/c it does not have a name + // and it is not unnamed class. + // Anonymous classes are a GNU extension. + struct { + int y; + }; + // This struct is an unnamed class see [class.pre]p1 + // http://eel.is/c++draft/class#pre-1.sentence-6 + struct { + int x; + } my_type_is_nameless; + struct name { + int x; + } my_type_is_named; + Task(int i, Task *n): + id(i), + next(n), + type(TASK_TYPE_1) + {} +}; + + +int main (int argc, char const *argv[]) +{ + Task *task_head = new Task(-1, NULL); + Task *task1 = new Task(1, NULL); + Task *task2 = new Task(2, NULL); + Task *task3 = new Task(3, NULL); // Orphaned. + Task *task4 = new Task(4, NULL); + Task *task5 = new Task(5, NULL); + + task_head->next = task1; + task1->next = task2; + task2->next = task4; + task4->next = task5; + + int total = 0; + Task *t = task_head; + while (t != NULL) { + if (t->id >= 0) + ++total; + t = t->next; + } + printf("We have a total number of %d tasks\n", total); + + // This corresponds to an empty task list. + Task *empty_task_head = new Task(-1, NULL); + + return 0; // Break at this line +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/TestValueAPI.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/TestValueAPI.py new file mode 100644 index 00000000000..bf8cbe34320 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/TestValueAPI.py @@ -0,0 +1,193 @@ +""" +Test some SBValue APIs. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ValueAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # We'll use the test method name as the exe_name. + self.exe_name = self.testMethodName + # Find the line number to of function 'c'. + self.line = line_number('main.c', '// Break at this line') + + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24772") + @add_test_categories(['pyapi']) + def test(self): + """Exercise some SBValue APIs.""" + d = {'EXE': self.exe_name} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + exe = self.getBuildArtifact(self.exe_name) + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Create the breakpoint inside function 'main'. + breakpoint = target.BreakpointCreateByLocation('main.c', self.line) + 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) + + # Get Frame #0. + self.assertTrue(process.GetState() == lldb.eStateStopped) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint condition") + frame0 = thread.GetFrameAtIndex(0) + + # Get global variable 'days_of_week'. + list = target.FindGlobalVariables('days_of_week', 1) + days_of_week = list.GetValueAtIndex(0) + self.assertTrue(days_of_week, VALID_VARIABLE) + self.assertEqual(days_of_week.GetNumChildren(), 7, VALID_VARIABLE) + self.DebugSBValue(days_of_week) + + # Use this to test the "child" and "children" accessors: + children = days_of_week.children + self.assertEqual(len(children), 7, VALID_VARIABLE) + for i in range(0, len(children)): + day = days_of_week.child[i] + list_day = children[i] + self.assertNotEqual(day, None) + self.assertNotEqual(list_day, None) + self.assertEqual(day.GetSummary(), list_day.GetSummary(), VALID_VARIABLE) + + # Spot check the actual value: + first_day = days_of_week.child[1] + self.assertEqual(first_day.GetSummary(), '"Monday"', VALID_VARIABLE) + + # Get global variable 'weekdays'. + list = target.FindGlobalVariables('weekdays', 1) + weekdays = list.GetValueAtIndex(0) + self.assertTrue(weekdays, VALID_VARIABLE) + self.assertTrue(weekdays.GetNumChildren() == 5, VALID_VARIABLE) + self.DebugSBValue(weekdays) + + # Get global variable 'g_table'. + list = target.FindGlobalVariables('g_table', 1) + g_table = list.GetValueAtIndex(0) + self.assertTrue(g_table, VALID_VARIABLE) + self.assertTrue(g_table.GetNumChildren() == 2, VALID_VARIABLE) + self.DebugSBValue(g_table) + + fmt = lldbutil.BasicFormatter() + cvf = lldbutil.ChildVisitingFormatter(indent_child=2) + rdf = lldbutil.RecursiveDecentFormatter(indent_child=2) + if self.TraceOn(): + print(fmt.format(days_of_week)) + print(cvf.format(days_of_week)) + print(cvf.format(weekdays)) + print(rdf.format(g_table)) + + # Get variable 'my_int_ptr'. + value = frame0.FindVariable('my_int_ptr') + self.assertTrue(value, VALID_VARIABLE) + self.DebugSBValue(value) + + # Get what 'my_int_ptr' points to. + pointed = value.GetChildAtIndex(0) + self.assertTrue(pointed, VALID_VARIABLE) + self.DebugSBValue(pointed) + + # While we are at it, verify that 'my_int_ptr' points to 'g_my_int'. + symbol = target.ResolveLoadAddress( + int(pointed.GetLocation(), 0)).GetSymbol() + self.assertTrue(symbol) + self.expect(symbol.GetName(), exe=False, + startstr='g_my_int') + + # Get variable 'str_ptr'. + value = frame0.FindVariable('str_ptr') + self.assertTrue(value, VALID_VARIABLE) + self.DebugSBValue(value) + + # SBValue::TypeIsPointerType() should return true. + self.assertTrue(value.TypeIsPointerType()) + + # Verify the SBValue::GetByteSize() API is working correctly. + arch = self.getArchitecture() + if arch == 'i386': + self.assertTrue(value.GetByteSize() == 4) + elif arch == 'x86_64': + self.assertTrue(value.GetByteSize() == 8) + + # Get child at index 5 => 'Friday'. + child = value.GetChildAtIndex(5, lldb.eNoDynamicValues, True) + self.assertTrue(child, VALID_VARIABLE) + self.DebugSBValue(child) + + self.expect(child.GetSummary(), exe=False, + substrs=['Friday']) + + # Now try to get at the same variable using GetValueForExpressionPath(). + # These two SBValue objects should have the same value. + val2 = value.GetValueForExpressionPath('[5]') + self.assertTrue(val2, VALID_VARIABLE) + self.DebugSBValue(val2) + self.assertTrue(child.GetValue() == val2.GetValue() and + child.GetSummary() == val2.GetSummary()) + + val_i = target.EvaluateExpression('i') + val_s = target.EvaluateExpression('s') + val_a = target.EvaluateExpression('a') + self.assertTrue( + val_s.GetChildMemberWithName('a').GetAddress().IsValid(), + VALID_VARIABLE) + self.assertTrue( + val_s.GetChildMemberWithName('a').AddressOf(), + VALID_VARIABLE) + self.assertTrue( + val_a.Cast( + val_i.GetType()).AddressOf(), + VALID_VARIABLE) + + # Check that lldb.value implements truth testing. + self.assertFalse(lldb.value(frame0.FindVariable('bogus'))) + self.assertTrue(lldb.value(frame0.FindVariable('uinthex'))) + + self.assertTrue(int(lldb.value(frame0.FindVariable('uinthex'))) + == 3768803088, 'uinthex == 3768803088') + self.assertTrue(int(lldb.value(frame0.FindVariable('sinthex'))) + == -526164208, 'sinthex == -526164208') + + # Check value_iter works correctly. + for v in [ + lldb.value(frame0.FindVariable('uinthex')), + lldb.value(frame0.FindVariable('sinthex')) + ]: + self.assertTrue(v) + + self.assertTrue( + frame0.FindVariable('uinthex').GetValueAsUnsigned() == 3768803088, + 'unsigned uinthex == 3768803088') + self.assertTrue( + frame0.FindVariable('sinthex').GetValueAsUnsigned() == 3768803088, + 'unsigned sinthex == 3768803088') + + self.assertTrue( + frame0.FindVariable('uinthex').GetValueAsSigned() == - + 526164208, + 'signed uinthex == -526164208') + self.assertTrue( + frame0.FindVariable('sinthex').GetValueAsSigned() == - + 526164208, + 'signed sinthex == -526164208') diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/change_values/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/change_values/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/change_values/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/change_values/TestChangeValueAPI.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/change_values/TestChangeValueAPI.py new file mode 100644 index 00000000000..6f0dee21af6 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/change_values/TestChangeValueAPI.py @@ -0,0 +1,181 @@ +""" +Test some SBValue APIs. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ChangeValueAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # We'll use the test method name as the exe_name. + self.exe_name = self.testMethodName + # Find the line number to of function 'c'. + self.line = line_number('main.c', '// Stop here and set values') + self.check_line = line_number( + 'main.c', '// Stop here and check values') + self.end_line = line_number( + 'main.c', '// Set a breakpoint here at the end') + + @add_test_categories(['pyapi']) + @expectedFlakeyLinux("llvm.org/pr25652") + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24772") + def test_change_value(self): + """Exercise the SBValue::SetValueFromCString API.""" + d = {'EXE': self.exe_name} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + exe = self.getBuildArtifact(self.exe_name) + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Create the breakpoint inside function 'main'. + breakpoint = target.BreakpointCreateByLocation('main.c', self.line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + # Create the breakpoint inside the function 'main' + check_breakpoint = target.BreakpointCreateByLocation( + 'main.c', self.check_line) + self.assertTrue(check_breakpoint, VALID_BREAKPOINT) + + # Create the breakpoint inside function 'main'. + end_breakpoint = target.BreakpointCreateByLocation( + 'main.c', self.end_line) + self.assertTrue(end_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) + + # Get Frame #0. + self.assertTrue(process.GetState() == lldb.eStateStopped) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint condition") + frame0 = thread.GetFrameAtIndex(0) + self.assertTrue(frame0.IsValid(), "Got a valid frame.") + + # Get the val variable and change it: + error = lldb.SBError() + + val_value = frame0.FindVariable("val") + self.assertTrue(val_value.IsValid(), "Got the SBValue for val") + actual_value = val_value.GetValueAsSigned(error, 0) + self.assertTrue(error.Success(), "Got a value from val") + self.assertTrue(actual_value == 100, "Got the right value from val") + + result = val_value.SetValueFromCString("12345") + self.assertTrue(result, "Setting val returned True.") + actual_value = val_value.GetValueAsSigned(error, 0) + self.assertTrue(error.Success(), "Got a changed value from val") + self.assertTrue( + actual_value == 12345, + "Got the right changed value from val") + + # Now check that we can set a structure element: + + mine_value = frame0.FindVariable("mine") + self.assertTrue(mine_value.IsValid(), "Got the SBValue for mine") + + mine_second_value = mine_value.GetChildMemberWithName("second_val") + self.assertTrue( + mine_second_value.IsValid(), + "Got second_val from mine") + actual_value = mine_second_value.GetValueAsUnsigned(error, 0) + self.assertTrue( + error.Success(), + "Got an unsigned value for second_val") + self.assertTrue(actual_value == 5555) + + result = mine_second_value.SetValueFromCString("98765") + self.assertTrue(result, "Success setting mine.second_value.") + actual_value = mine_second_value.GetValueAsSigned(error, 0) + self.assertTrue( + error.Success(), + "Got a changed value from mine.second_val") + self.assertTrue(actual_value == 98765, + "Got the right changed value from mine.second_val") + + # Next do the same thing with the pointer version. + ptr_value = frame0.FindVariable("ptr") + self.assertTrue(ptr_value.IsValid(), "Got the SBValue for ptr") + + ptr_second_value = ptr_value.GetChildMemberWithName("second_val") + self.assertTrue(ptr_second_value.IsValid(), "Got second_val from ptr") + actual_value = ptr_second_value.GetValueAsUnsigned(error, 0) + self.assertTrue( + error.Success(), + "Got an unsigned value for ptr->second_val") + self.assertTrue(actual_value == 6666) + + result = ptr_second_value.SetValueFromCString("98765") + self.assertTrue(result, "Success setting ptr->second_value.") + actual_value = ptr_second_value.GetValueAsSigned(error, 0) + self.assertTrue( + error.Success(), + "Got a changed value from ptr->second_val") + self.assertTrue(actual_value == 98765, + "Got the right changed value from ptr->second_val") + + # gcc may set multiple locations for breakpoint + breakpoint.SetEnabled(False) + + # Now continue, grab the stdout and make sure we changed the real + # values as well... + process.Continue() + + self.assertTrue(process.GetState() == lldb.eStateStopped) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint condition") + + expected_value = "Val - 12345 Mine - 55, 98765, 55555555. Ptr - 66, 98765, 66666666" + stdout = process.GetSTDOUT(1000) + self.assertTrue( + expected_value in stdout, + "STDOUT showed changed values.") + + # Finally, change the stack pointer to 0, and we should not make it to + # our end breakpoint. + frame0 = thread.GetFrameAtIndex(0) + self.assertTrue(frame0.IsValid(), "Second time: got a valid frame.") + sp_value = frame0.FindValue("sp", lldb.eValueTypeRegister) + self.assertTrue(sp_value.IsValid(), "Got a stack pointer value") + result = sp_value.SetValueFromCString("1") + self.assertTrue(result, "Setting sp returned true.") + actual_value = sp_value.GetValueAsUnsigned(error, 0) + self.assertTrue(error.Success(), "Got a changed value for sp") + self.assertTrue( + actual_value == 1, + "Got the right changed value for sp.") + + # Boundary condition test the SBValue.CreateValueFromExpression() API. + # LLDB should not crash! + nosuchval = mine_value.CreateValueFromExpression(None, None) + + process.Continue() + + self.assertTrue(process.GetState() == lldb.eStateStopped) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread is None, + "We should not have managed to hit our second breakpoint with sp == 1") + + process.Kill() diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/change_values/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/change_values/main.c new file mode 100644 index 00000000000..01455c01964 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/change_values/main.c @@ -0,0 +1,29 @@ +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> + +struct foo +{ + uint8_t first_val; + uint32_t second_val; + uint64_t third_val; +}; + +int main () +{ + int val = 100; + struct foo mine = {55, 5555, 55555555}; + struct foo *ptr = (struct foo *) malloc (sizeof (struct foo)); + ptr->first_val = 66; + ptr->second_val = 6666; + ptr->third_val = 66666666; + + // Stop here and set values + printf ("Val - %d Mine - %d, %d, %llu. Ptr - %d, %d, %llu\n", val, + mine.first_val, mine.second_val, mine.third_val, + ptr->first_val, ptr->second_val, ptr->third_val); + + // Stop here and check values + printf ("This is just another call which we won't make it over %d.", val); + return 0; // Set a breakpoint here at the end +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/empty_class/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/empty_class/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/empty_class/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/empty_class/TestValueAPIEmptyClass.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/empty_class/TestValueAPIEmptyClass.py new file mode 100644 index 00000000000..c7197e51c23 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/empty_class/TestValueAPIEmptyClass.py @@ -0,0 +1,56 @@ + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class ValueAPIEmptyClassTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @add_test_categories(['pyapi']) + def test(self): + self.build() + exe = self.getBuildArtifact("a.out") + line = line_number('main.cpp', '// Break at this line') + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Create the breakpoint inside function 'main'. + breakpoint = target.BreakpointCreateByLocation('main.cpp', line) + 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) + + # Get Frame #0. + self.assertTrue(process.GetState() == lldb.eStateStopped) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint condition") + frame0 = thread.GetFrameAtIndex(0) + + # Verify that we can access to a frame variable with an empty class type + e = frame0.FindVariable('e') + self.assertTrue(e.IsValid(), VALID_VARIABLE) + self.DebugSBValue(e) + self.assertEqual(e.GetNumChildren(), 0) + + # Verify that we can acces to a frame variable what is a pointer to an + # empty class + ep = frame0.FindVariable('ep') + self.assertTrue(ep.IsValid(), VALID_VARIABLE) + self.DebugSBValue(ep) + + # Verify that we can dereference a pointer to an empty class + epd = ep.Dereference() + self.assertTrue(epd.IsValid(), VALID_VARIABLE) + self.DebugSBValue(epd) + self.assertEqual(epd.GetNumChildren(), 0) + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/empty_class/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/empty_class/main.cpp new file mode 100644 index 00000000000..483a57ee5c0 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/empty_class/main.cpp @@ -0,0 +1,15 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +class Empty {}; + +int main (int argc, char const *argv[]) { + Empty e; + Empty* ep = new Empty; + return 0; // Break at this line +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/linked_list/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/linked_list/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/linked_list/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/linked_list/TestValueAPILinkedList.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/linked_list/TestValueAPILinkedList.py new file mode 100644 index 00000000000..b45186a3150 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/linked_list/TestValueAPILinkedList.py @@ -0,0 +1,142 @@ +""" +Test SBValue API linked_list_iter which treats the SBValue as a linked list and +supports iteration till the end of list is reached. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ValueAsLinkedListTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # We'll use the test method name as the exe_name. + self.exe_name = self.testMethodName + # Find the line number to break at. + self.line = line_number('main.cpp', '// Break at this line') + + # Py3 asserts due to a bug in SWIG. A fix for this was upstreamed into + # SWIG 3.0.8. + @skipIf(py_version=['>=', (3, 0)], swig_version=['<', (3, 0, 8)]) + @add_test_categories(['pyapi']) + def test(self): + """Exercise SBValue API linked_list_iter.""" + d = {'EXE': self.exe_name} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + exe = self.getBuildArtifact(self.exe_name) + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Create the breakpoint inside function 'main'. + breakpoint = target.BreakpointCreateByLocation('main.cpp', self.line) + 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) + + # Get Frame #0. + self.assertTrue(process.GetState() == lldb.eStateStopped) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint condition") + frame0 = thread.GetFrameAtIndex(0) + + # Get variable 'task_head'. + task_head = frame0.FindVariable('task_head') + self.assertTrue(task_head, VALID_VARIABLE) + self.DebugSBValue(task_head) + + # By design (see main.cpp), the visited id's are: [1, 2, 4, 5]. + visitedIDs = [1, 2, 4, 5] + list = [] + + cvf = lldbutil.ChildVisitingFormatter(indent_child=2) + for t in task_head.linked_list_iter('next'): + self.assertTrue(t, VALID_VARIABLE) + # Make sure that 'next' corresponds to an SBValue with pointer + # type. + self.assertTrue(t.TypeIsPointerType()) + if self.TraceOn(): + print(cvf.format(t)) + list.append(int(t.GetChildMemberWithName("id").GetValue())) + + # Sanity checks that the we visited all the items (no more, no less). + if self.TraceOn(): + print("visited IDs:", list) + self.assertTrue(visitedIDs == list) + + # Let's exercise the linked_list_iter() API again, this time supplying + # our end of list test function. + def eol(val): + """Test function to determine end of list.""" + # End of list is reached if either the value object is invalid + # or it corresponds to a null pointer. + if not val or int(val.GetValue(), 16) == 0: + return True + # Also check the "id" for correct semantics. If id <= 0, the item + # is corrupted, let's return True to signify end of list. + if int(val.GetChildMemberWithName("id").GetValue(), 0) <= 0: + return True + + # Otherwise, return False. + return False + + list = [] + for t in task_head.linked_list_iter('next', eol): + self.assertTrue(t, VALID_VARIABLE) + # Make sure that 'next' corresponds to an SBValue with pointer + # type. + self.assertTrue(t.TypeIsPointerType()) + if self.TraceOn(): + print(cvf.format(t)) + list.append(int(t.GetChildMemberWithName("id").GetValue())) + + # Sanity checks that the we visited all the items (no more, no less). + if self.TraceOn(): + print("visited IDs:", list) + self.assertTrue(visitedIDs == list) + + # Get variable 'empty_task_head'. + empty_task_head = frame0.FindVariable('empty_task_head') + self.assertTrue(empty_task_head, VALID_VARIABLE) + self.DebugSBValue(empty_task_head) + + list = [] + # There is no iterable item from empty_task_head.linked_list_iter(). + for t in empty_task_head.linked_list_iter('next', eol): + if self.TraceOn(): + print(cvf.format(t)) + list.append(int(t.GetChildMemberWithName("id").GetValue())) + + self.assertTrue(len(list) == 0) + + # Get variable 'task_evil'. + task_evil = frame0.FindVariable('task_evil') + self.assertTrue(task_evil, VALID_VARIABLE) + self.DebugSBValue(task_evil) + + list = [] + # There 3 iterable items from task_evil.linked_list_iter(). :-) + for t in task_evil.linked_list_iter('next'): + if self.TraceOn(): + print(cvf.format(t)) + list.append(int(t.GetChildMemberWithName("id").GetValue())) + + self.assertTrue(len(list) == 3) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/linked_list/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/linked_list/main.cpp new file mode 100644 index 00000000000..edd175ae266 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/linked_list/main.cpp @@ -0,0 +1,55 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +class Task { +public: + int id; + Task *next; + Task(int i, Task *n): + id(i), + next(n) + {} +}; + + +int main (int argc, char const *argv[]) +{ + Task *task_head = NULL; + Task *task1 = new Task(1, NULL); + Task *task2 = new Task(2, NULL); + Task *task3 = new Task(3, NULL); // Orphaned. + Task *task4 = new Task(4, NULL); + Task *task5 = new Task(5, NULL); + + task_head = task1; + task1->next = task2; + task2->next = task4; + task4->next = task5; + + int total = 0; + Task *t = task_head; + while (t != NULL) { + if (t->id >= 0) + ++total; + t = t->next; + } + printf("We have a total number of %d tasks\n", total); + + // This corresponds to an empty task list. + Task *empty_task_head = NULL; + + Task *task_evil = new Task(1, NULL); + Task *task_2 = new Task(2, NULL); + Task *task_3 = new Task(3, NULL); + task_evil->next = task_2; + task_2->next = task_3; + task_3->next = task_evil; // In order to cause inifinite loop. :-) + + return 0; // Break at this line +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/main.c new file mode 100644 index 00000000000..68b3c12cce4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value/main.c @@ -0,0 +1,55 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> +#include <stdint.h> + +// This simple program is to test the lldb Python API SBValue.GetChildAtIndex(). + +int g_my_int = 100; + +const char *days_of_week[7] = { "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" }; + +const char *weekdays[5] = { "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday" }; + +const char **g_table[2] = { days_of_week, weekdays }; + +typedef int MyInt; + +struct MyStruct +{ + int a; + int b; +}; + +int main (int argc, char const *argv[]) +{ + uint32_t uinthex = 0xE0A35F10; + int32_t sinthex = 0xE0A35F10; + + int i; + MyInt a = 12345; + struct MyStruct s = { 11, 22 }; + int *my_int_ptr = &g_my_int; + printf("my_int_ptr points to location %p\n", my_int_ptr); + const char **str_ptr = days_of_week; + for (i = 0; i < 7; ++i) + printf("%s\n", str_ptr[i]); // Break at this line + // and do str_ptr_val.GetChildAtIndex(5, lldb.eNoDynamicValues, True). + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value_var_update/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value_var_update/Makefile new file mode 100644 index 00000000000..3716c6e29e9 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value_var_update/Makefile @@ -0,0 +1,6 @@ +C_SOURCES := main.c +CFLAGS_EXTRAS := -std=c99 +# See TestHelloWorld.py, which specifies the executable name with a dictionary. +EXE := hello_world + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value_var_update/TestValueVarUpdate.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value_var_update/TestValueVarUpdate.py new file mode 100644 index 00000000000..b425cef6e1e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value_var_update/TestValueVarUpdate.py @@ -0,0 +1,62 @@ +"""Test SBValue::GetValueDidChange""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ValueVarUpdateTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @add_test_categories(['pyapi']) + def test_with_process_launch_api(self): + """Test SBValue::GetValueDidChange""" + # Get the full path to our executable to be attached/debugged. + exe = self.getBuildArtifact(self.testMethodName) + d = {'EXE': exe} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + target = self.dbg.CreateTarget(exe) + + breakpoint = target.BreakpointCreateBySourceRegex( + "break here", lldb.SBFileSpec("main.c")) + + 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']) + + i = self.frame().FindVariable("i") + i_val = i.GetValueAsUnsigned(0) + c = self.frame().FindVariable("c") + + # Update any values from the SBValue objects so we can ask them if they + # changed after a continue + i.GetValueDidChange() + c.GetChildAtIndex(1).GetValueDidChange() + c.GetChildAtIndex(0).GetChildAtIndex(0).GetValueDidChange() + + if self.TraceOn(): + self.runCmd("frame variable") + + self.runCmd("continue") + + if self.TraceOn(): + self.runCmd("frame variable") + + self.assertTrue( + i_val != i.GetValueAsUnsigned(0), + "GetValue() is saying a lie") + self.assertTrue( + i.GetValueDidChange(), + "GetValueDidChange() is saying a lie") + + # Check complex type + self.assertTrue(c.GetChildAtIndex(0).GetChildAtIndex(0).GetValueDidChange( + ) and not c.GetChildAtIndex(1).GetValueDidChange(), "GetValueDidChange() is saying a lie") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value_var_update/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value_var_update/main.c new file mode 100644 index 00000000000..9ffca5cbb9f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/value_var_update/main.c @@ -0,0 +1,15 @@ +struct complex_type { + struct { long l; } inner; + struct complex_type *complex_ptr; +}; + +int main() { + int i = 0; + struct complex_type c = { { 1L }, &c }; + for (int j = 3; j < 20; j++) + { + c.inner.l += (i += j); + i = i - 1; // break here + } + return i; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/.categories b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/.categories new file mode 100644 index 00000000000..50c1613cda7 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/.categories @@ -0,0 +1 @@ +watchpoint diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/TestSetWatchpoint.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/TestSetWatchpoint.py new file mode 100644 index 00000000000..a34806d1657 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/TestSetWatchpoint.py @@ -0,0 +1,106 @@ +""" +Use lldb Python SBValue API to create a watchpoint for read_write of 'globl' var. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class SetWatchpointAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + 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.') + + @add_test_categories(['pyapi']) + # Read-write watchpoints not supported on SystemZ + @expectedFailureAll(archs=['s390x']) + def test_watch_val(self): + """Exercise SBValue.Watch() API to set a watchpoint.""" + self.build() + exe = self.getBuildArtifact("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. + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint and + breakpoint.GetNumLocations() == 1, + VALID_BREAKPOINT) + + # Now launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + # We should be stopped due to the breakpoint. Get frame #0. + process = target.GetProcess() + self.assertTrue(process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + frame0 = thread.GetFrameAtIndex(0) + + # Watch 'global' for read and write. + value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal) + error = lldb.SBError() + watchpoint = value.Watch(True, True, True, error) + self.assertTrue(value and watchpoint, + "Successfully found the variable and set a watchpoint") + self.DebugSBValue(value) + + # Hide stdout if not running with '-t' option. + if not self.TraceOn(): + self.HideStdout() + + print(watchpoint) + + # Continue. Expect the program to stop due to the variable being + # written to. + process.Continue() + + if (self.TraceOn()): + lldbutil.print_stacktraces(process) + + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonWatchpoint) + self.assertTrue(thread, "The thread stopped due to watchpoint") + self.DebugSBValue(value) + + # Continue. Expect the program to stop due to the variable being read + # from. + process.Continue() + + if (self.TraceOn()): + lldbutil.print_stacktraces(process) + + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonWatchpoint) + self.assertTrue(thread, "The thread stopped due to watchpoint") + self.DebugSBValue(value) + + # Continue the process. We don't expect the program to be stopped + # again. + process.Continue() + + # At this point, the inferior process should have exited. + self.assertTrue( + process.GetState() == lldb.eStateExited, + PROCESS_EXITED) + + self.dbg.DeleteTarget(target) + self.assertFalse(watchpoint.IsValid()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIgnoreCount.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIgnoreCount.py new file mode 100644 index 00000000000..83a11d42346 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIgnoreCount.py @@ -0,0 +1,92 @@ +""" +Use lldb Python SBWatchpoint API to set the ignore count. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class WatchpointIgnoreCountTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + 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.') + + @add_test_categories(['pyapi']) + # Read-write watchpoints not supported on SystemZ + @expectedFailureAll(archs=['s390x']) + def test_set_watch_ignore_count(self): + """Test SBWatchpoint.SetIgnoreCount() API.""" + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Create a breakpoint on main.c in order to set our watchpoint later. + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint and + breakpoint.GetNumLocations() == 1, + VALID_BREAKPOINT) + + # Now launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + # We should be stopped due to the breakpoint. Get frame #0. + process = target.GetProcess() + self.assertEqual(process.GetState(), lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + frame0 = thread.GetFrameAtIndex(0) + + # Watch 'global' for read and write. + value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal) + error = lldb.SBError() + watchpoint = value.Watch(True, True, True, error) + self.assertTrue(value and watchpoint, + "Successfully found the variable and set a watchpoint") + self.DebugSBValue(value) + + # Hide stdout if not running with '-t' option. + if not self.TraceOn(): + self.HideStdout() + + # There should be only 1 watchpoint location under the target. + self.assertEqual(target.GetNumWatchpoints(), 1) + watchpoint = target.GetWatchpointAtIndex(0) + self.assertTrue(watchpoint.IsEnabled()) + self.assertEqual(watchpoint.GetIgnoreCount(), 0) + watch_id = watchpoint.GetID() + self.assertNotEqual(watch_id, 0) + print(watchpoint) + + # Now immediately set the ignore count to 2. When we continue, expect the + # inferior to run to its completion without stopping due to watchpoint. + watchpoint.SetIgnoreCount(2) + print(watchpoint) + process.Continue() + + # At this point, the inferior process should have exited. + self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED) + + # Verify some vital statistics. + self.assertTrue(watchpoint) + self.assertEqual(watchpoint.GetWatchSize(), 4) + self.assertEqual(watchpoint.GetHitCount(), 2) + print(watchpoint) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIter.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIter.py new file mode 100644 index 00000000000..44df96bae5e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIter.py @@ -0,0 +1,125 @@ +""" +Use lldb Python SBTarget API to iterate on the watchpoint(s) for the target. +""" + +from __future__ import print_function + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class WatchpointIteratorTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + # hardware watchpoints are not reported with a hardware index # on armv7 on ios devices + def affected_by_radar_34564183(self): + return (self.getArchitecture() in ['armv7', 'armv7k', 'arm64_32']) and self.platformIsDarwin() + + 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.') + + @add_test_categories(['pyapi']) + def test_watch_iter(self): + """Exercise SBTarget.watchpoint_iter() API to iterate on the available watchpoints.""" + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Create a breakpoint on main.c in order to set our watchpoint later. + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint and + breakpoint.GetNumLocations() == 1, + VALID_BREAKPOINT) + + # Now launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + # We should be stopped due to the breakpoint. Get frame #0. + process = target.GetProcess() + self.assertTrue(process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + frame0 = thread.GetFrameAtIndex(0) + + # Watch 'global' for read and write. + value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal) + error = lldb.SBError() + watchpoint = value.Watch(True, False, True, error) + self.assertTrue(value and watchpoint, + "Successfully found the variable and set a watchpoint") + self.DebugSBValue(value) + + # Hide stdout if not running with '-t' option. + if not self.TraceOn(): + self.HideStdout() + + # There should be only 1 watchpoint location under the target. + self.assertTrue(target.GetNumWatchpoints() == 1) + self.assertTrue(watchpoint.IsEnabled()) + watch_id = watchpoint.GetID() + self.assertTrue(watch_id != 0) + + # Continue. Expect the program to stop due to the variable being + # written to. + process.Continue() + + # Hide stdout if not running with '-t' option. + if not self.TraceOn(): + self.HideStdout() + + # Print the stack traces. + lldbutil.print_stacktraces(process) + + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonWatchpoint) + self.assertTrue(thread, "The thread stopped due to watchpoint") + self.DebugSBValue(value) + + # We currently only support hardware watchpoint. Verify that we have a + # meaningful hardware index at this point. Exercise the printed repr of + # SBWatchpointLocation. + print(watchpoint) + if not self.affected_by_radar_34564183(): + self.assertTrue(watchpoint.GetHardwareIndex() != -1) + + # SBWatchpoint.GetDescription() takes a description level arg. + print(lldbutil.get_description(watchpoint, lldb.eDescriptionLevelFull)) + + # Now disable the 'rw' watchpoint. The program won't stop when it reads + # 'global' next. + watchpoint.SetEnabled(False) + self.assertTrue(watchpoint.GetHardwareIndex() == -1) + self.assertFalse(watchpoint.IsEnabled()) + + # Continue. The program does not stop again when the variable is being + # read from because the watchpoint location has been disabled. + process.Continue() + + # At this point, the inferior process should have exited. + self.assertTrue( + process.GetState() == lldb.eStateExited, + PROCESS_EXITED) + + # Verify some vital statistics and exercise the iterator API. + for watchpoint in target.watchpoint_iter(): + self.assertTrue(watchpoint) + self.assertTrue(watchpoint.GetWatchSize() == 4) + self.assertTrue(watchpoint.GetHitCount() == 1) + print(watchpoint) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/condition/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/condition/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/condition/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py new file mode 100644 index 00000000000..733473411ac --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py @@ -0,0 +1,95 @@ +""" +Test watchpoint condition API. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class WatchpointConditionAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + 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} + + def test_watchpoint_cond_api(self): + """Test watchpoint condition API.""" + self.build(dictionary=self.d) + self.setTearDownCleanup(dictionary=self.d) + exe = self.getBuildArtifact(self.exe_name) + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Now create a breakpoint on main.c. + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint and + breakpoint.GetNumLocations() == 1, + VALID_BREAKPOINT) + + # Now launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + # We should be stopped due to the breakpoint. Get frame #0. + process = target.GetProcess() + self.assertTrue(process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + frame0 = thread.GetFrameAtIndex(0) + + # Watch 'global' for write. + value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal) + error = lldb.SBError() + watchpoint = value.Watch(True, False, True, error) + self.assertTrue(value and watchpoint, + "Successfully found the variable and set a watchpoint") + self.DebugSBValue(value) + + # Now set the condition as "global==5". + watchpoint.SetCondition('global==5') + self.expect(watchpoint.GetCondition(), exe=False, + startstr='global==5') + + # Hide stdout if not running with '-t' option. + if not self.TraceOn(): + self.HideStdout() + + print(watchpoint) + + # Continue. Expect the program to stop due to the variable being + # written to. + process.Continue() + + if (self.TraceOn()): + lldbutil.print_stacktraces(process) + + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonWatchpoint) + self.assertTrue(thread, "The thread stopped due to watchpoint") + self.DebugSBValue(value) + + # Verify that the condition is met. + self.assertTrue(value.GetValueAsUnsigned() == 5) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/condition/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/condition/main.cpp new file mode 100644 index 00000000000..3f7c5f5be96 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/condition/main.cpp @@ -0,0 +1,27 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#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/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/main.c new file mode 100644 index 00000000000..6cda6d7c886 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/main.c @@ -0,0 +1,23 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#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' for read&write. + global = 20; + local += argc; + ++local; + printf("local: %d\n", local); + printf("global=%d\n", global); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/Makefile new file mode 100644 index 00000000000..de4ec12b13c --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/Makefile @@ -0,0 +1,4 @@ +ENABLE_THREADS := YES +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py new file mode 100644 index 00000000000..9cbc396e7a5 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py @@ -0,0 +1,100 @@ +""" +Use lldb Python SBValue.WatchPointee() API to create a watchpoint for write of '*g_char_ptr'. +""" + +from __future__ import print_function + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class SetWatchlocationAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + 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" + + @add_test_categories(['pyapi']) + def test_watch_location(self): + """Exercise SBValue.WatchPointee() API to set a watchpoint.""" + self.build() + exe = self.getBuildArtifact("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. + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint and + breakpoint.GetNumLocations() == 1, + VALID_BREAKPOINT) + + # Now launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + # We should be stopped due to the breakpoint. Get frame #0. + process = target.GetProcess() + self.assertTrue(process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + frame0 = thread.GetFrameAtIndex(0) + + value = frame0.FindValue('g_char_ptr', + lldb.eValueTypeVariableGlobal) + pointee = value.CreateValueFromAddress( + "pointee", + value.GetValueAsUnsigned(0), + value.GetType().GetPointeeType()) + # Watch for write to *g_char_ptr. + error = lldb.SBError() + watchpoint = value.WatchPointee(True, False, True, error) + self.assertTrue(value and watchpoint, + "Successfully found the pointer and set a watchpoint") + self.DebugSBValue(value) + self.DebugSBValue(pointee) + + # Hide stdout if not running with '-t' option. + if not self.TraceOn(): + self.HideStdout() + + print(watchpoint) + + # Continue. Expect the program to stop due to the variable being + # written to. + process.Continue() + + if (self.TraceOn()): + lldbutil.print_stacktraces(process) + + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonWatchpoint) + self.assertTrue(thread, "The thread stopped due to watchpoint") + self.DebugSBValue(value) + self.DebugSBValue(pointee) + + self.expect( + lldbutil.print_stacktrace( + thread, + string_buffer=True), + exe=False, + substrs=[ + self.violating_func]) + + # This finishes our test. diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py new file mode 100644 index 00000000000..53e794db03f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py @@ -0,0 +1,145 @@ +""" +Use lldb Python SBtarget.WatchAddress() API to create a watchpoint for write of '*g_char_ptr'. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TargetWatchAddressAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + 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" + + @add_test_categories(['pyapi']) + def test_watch_address(self): + """Exercise SBTarget.WatchAddress() API to set a watchpoint.""" + self.build() + exe = self.getBuildArtifact("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. + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint and + breakpoint.GetNumLocations() == 1, + VALID_BREAKPOINT) + + # Now launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + # We should be stopped due to the breakpoint. Get frame #0. + process = target.GetProcess() + self.assertTrue(process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + frame0 = thread.GetFrameAtIndex(0) + + value = frame0.FindValue('g_char_ptr', + lldb.eValueTypeVariableGlobal) + pointee = value.CreateValueFromAddress( + "pointee", + value.GetValueAsUnsigned(0), + value.GetType().GetPointeeType()) + # Watch for write to *g_char_ptr. + error = lldb.SBError() + watchpoint = target.WatchAddress( + value.GetValueAsUnsigned(), 1, False, True, error) + self.assertTrue(value and watchpoint, + "Successfully found the pointer and set a watchpoint") + self.DebugSBValue(value) + self.DebugSBValue(pointee) + + # Hide stdout if not running with '-t' option. + if not self.TraceOn(): + self.HideStdout() + + print(watchpoint) + + # Continue. Expect the program to stop due to the variable being + # written to. + process.Continue() + + if (self.TraceOn()): + lldbutil.print_stacktraces(process) + + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonWatchpoint) + self.assertTrue(thread, "The thread stopped due to watchpoint") + self.DebugSBValue(value) + self.DebugSBValue(pointee) + + self.expect( + lldbutil.print_stacktrace( + thread, + string_buffer=True), + exe=False, + substrs=[ + self.violating_func]) + + # This finishes our test. + + @add_test_categories(['pyapi']) + # No size constraint on MIPS for watches + @skipIf(archs=['mips', 'mipsel', 'mips64', 'mips64el']) + @skipIf(archs=['s390x']) # Likewise on SystemZ + def test_watch_address_with_invalid_watch_size(self): + """Exercise SBTarget.WatchAddress() API but pass an invalid watch_size.""" + self.build() + exe = self.getBuildArtifact("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. + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint and + breakpoint.GetNumLocations() == 1, + VALID_BREAKPOINT) + + # Now launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + # We should be stopped due to the breakpoint. Get frame #0. + process = target.GetProcess() + self.assertTrue(process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + frame0 = thread.GetFrameAtIndex(0) + + value = frame0.FindValue('g_char_ptr', + lldb.eValueTypeVariableGlobal) + pointee = value.CreateValueFromAddress( + "pointee", + value.GetValueAsUnsigned(0), + value.GetType().GetPointeeType()) + # Watch for write to *g_char_ptr. + error = lldb.SBError() + watchpoint = target.WatchAddress( + value.GetValueAsUnsigned(), 365, False, True, error) + self.assertFalse(watchpoint) + self.expect(error.GetCString(), exe=False, + substrs=['watch size of %d is not supported' % 365]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/main.cpp new file mode 100644 index 00000000000..e455331bc16 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/main.cpp @@ -0,0 +1,103 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#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) +{ + *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; +} |