Initial import of lldb

Change-Id: Ib244e837bee349effa12b2ff6ffffbe3d730e929
This commit is contained in:
2014-09-29 14:52:42 +02:00
committed by Lionel Sambuc
parent 35b65c5af1
commit 41f05bd8d7
3541 changed files with 875157 additions and 0 deletions

View File

@@ -0,0 +1 @@
pyapi

View File

@@ -0,0 +1,39 @@
"""
Test Debugger APIs.
"""
import os
import lldb
from lldbtest import TestBase, python_api_test
class DebuggerAPITestCase(TestBase):
mydir = os.path.join("python_api", "debugger")
@python_api_test
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)
@python_api_test
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)

View File

@@ -0,0 +1,373 @@
"""
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.
"""
import os, time
import re
import unittest2
import lldb, lldbutil
from lldbtest import *
class APIDefaultConstructorTestCase(TestBase):
mydir = os.path.join("python_api", "default-constructor")
@python_api_test
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)
@python_api_test
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)
@python_api_test
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)
@python_api_test
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)
@python_api_test
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)
@python_api_test
def test_SBCommandReturnObject(self):
"""SBCommandReturnObject object is valid after default construction."""
obj = lldb.SBCommandReturnObject()
if self.TraceOn():
print obj
self.assertTrue(obj)
@python_api_test
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)
@python_api_test
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)
@python_api_test
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)
@python_api_test
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)
@python_api_test
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)
@python_api_test
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)
@python_api_test
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)
@python_api_test
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)
@python_api_test
def test_SBInputReader(self):
obj = lldb.SBInputReader()
if self.TraceOn():
print obj
self.assertFalse(obj)
# Do fuzz testing on the invalid obj, it should not crash lldb.
import sb_inputreader
sb_inputreader.fuzz_obj(obj)
@python_api_test
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)
@python_api_test
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)
@python_api_test
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)
@python_api_test
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)
@python_api_test
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)
@python_api_test
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)
@python_api_test
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)
@python_api_test
def test_SBStream(self):
"""SBStream object is valid after default construction."""
obj = lldb.SBStream()
if self.TraceOn():
print obj
self.assertTrue(obj)
@python_api_test
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)
@python_api_test
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)
@python_api_test
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)
@python_api_test
def test_SBSymbolContextList(self):
"""SBSymbolContextList object is valid after default construction."""
obj = lldb.SBSymbolContextList()
if self.TraceOn():
print obj
self.assertTrue(obj)
@python_api_test
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)
@python_api_test
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)
@python_api_test
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)
@python_api_test
def test_SBTypeList(self):
"""SBTypeList object is valid after default construction."""
obj = lldb.SBTypeList()
if self.TraceOn():
print obj
self.assertTrue(obj)
@python_api_test
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)
@python_api_test
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)
@python_api_test
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)
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,22 @@
"""
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.maxint)
obj.GetDescription(lldb.SBStream())
obj.GetSection()
obj.GetSymbolContext(lldb.eSymbolContextEverything)
obj.GetModule()
obj.GetCompileUnit()
obj.GetFunction()
obj.GetBlock()
obj.GetSymbol()
obj.GetLineEntry()
obj.Clear()

View File

@@ -0,0 +1,17 @@
"""
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.IsInlined()
obj.GetInlinedName()
obj.GetInlinedCallSiteFile()
obj.GetInlinedCallSiteLine()
obj.GetInlinedCallSiteColumn()
obj.GetParent()
obj.GetSibling()
obj.GetFirstChild()
obj.GetDescription(lldb.SBStream())

View File

@@ -0,0 +1,35 @@
"""
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.maxint)
obj.FindLocationIDByAddress(sys.maxint)
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.SetCallback(None, None)
obj.GetNumResolvedLocations()
obj.GetNumLocations()
obj.GetDescription(lldb.SBStream())
for bp_loc in obj:
s = str(bp_loc)

View File

@@ -0,0 +1,28 @@
"""
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.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)

View File

@@ -0,0 +1,20 @@
"""
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.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()

View File

@@ -0,0 +1,28 @@
"""
Fuzz tests an object after the default construction to make sure it does not crash lldb.
"""
import sys
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)

View File

@@ -0,0 +1,15 @@
"""
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.GetNumLineEntries()
obj.GetLineEntryAtIndex(0xffffffff)
obj.FindLineEntryIndex(0, 0xffffffff, None)
obj.GetDescription(lldb.SBStream())
for line_entry in obj:
s = str(line_entry)

View File

@@ -0,0 +1,59 @@
"""
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.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()
obj.HandleProcessEvent(lldb.SBProcess(), lldb.SBEvent(), None, None)
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.GetSourceManager()
obj.SetSelectedTarget(lldb.SBTarget())
obj.SetCurrentPlatformSDKRoot("tmp/sdk-root")
try:
obj.DispatchInput(None)
except Exception:
pass
obj.DispatchInputInterrupt()
obj.DispatchInputEndOfFile()
obj.PushInputReader(lldb.SBInputReader())
obj.NotifyTopInputReader(lldb.eInputReaderActivate)
obj.InputReaderIsTopReader(lldb.SBInputReader())
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)

View File

@@ -0,0 +1,22 @@
"""
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.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.GetDescription(lldb.SBStream())
obj.Clear()

View File

@@ -0,0 +1,17 @@
"""
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.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()

View File

@@ -0,0 +1,14 @@
"""
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.Exists()
obj.ResolveExecutableLocation()
obj.GetFilename()
obj.GetDirectory()
obj.GetPath(None, 0)
obj.GetDescription(lldb.SBStream())

View File

@@ -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.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()

View File

@@ -0,0 +1,19 @@
"""
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.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())

View File

@@ -0,0 +1,16 @@
"""
Fuzz tests an object after the default construction to make sure it does not crash lldb.
"""
import sys
import lldb
def fuzz_obj(obj):
try:
obj.Initialize(lldb.SBDebugger.Create(), None, 0, "$", "^", True)
except Exception:
pass
obj.IsActive()
obj.IsDone()
obj.SetIsDone(True)
obj.GetGranularity()

View File

@@ -0,0 +1,16 @@
"""
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.GetAddress()
obj.GetByteSize()
obj.DoesBranch()
obj.Print(None)
obj.GetDescription(lldb.SBStream())
obj.EmulateWithFrame(lldb.SBFrame(), 0)
obj.DumpEmulation("armv7")
obj.TestEmulation(lldb.SBStream(), "my-file")

View File

@@ -0,0 +1,17 @@
"""
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.GetSize()
obj.GetInstructionAtIndex(0xffffffff)
obj.AppendInstruction(lldb.SBInstruction())
obj.Print(None)
obj.GetDescription(lldb.SBStream())
obj.DumpEmulationForAllInstructions("armv7")
obj.Clear()
for inst in obj:
s = str(inst)

View File

@@ -0,0 +1,14 @@
"""
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.GetStartAddress()
obj.GetEndAddress()
obj.GetFileSpec()
obj.GetLine()
obj.GetColumn()
obj.GetDescription(lldb.SBStream())

View File

@@ -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.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)

View File

@@ -0,0 +1,29 @@
"""
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.maxint)
obj.ResolveSymbolContextForAddress(lldb.SBAddress(), 0)
obj.GetDescription(lldb.SBStream())
obj.GetNumSymbols()
obj.GetSymbolAtIndex(sys.maxint)
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()

View File

@@ -0,0 +1,49 @@
"""
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.GetTarget()
obj.GetByteOrder()
obj.PutSTDIN("my data")
obj.GetSTDOUT(6)
obj.GetSTDERR(6)
event = lldb.SBEvent()
obj.ReportEventState(event, None)
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)

View File

@@ -0,0 +1,22 @@
"""
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.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)

View File

@@ -0,0 +1,17 @@
"""
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.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)

View File

@@ -0,0 +1,16 @@
"""
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.GetName()
obj.GetMangledName()
obj.GetInstructions(lldb.SBTarget())
obj.GetStartAddress()
obj.GetEndAddress()
obj.GetPrologueByteSize()
obj.GetType()
obj.GetDescription(lldb.SBStream())

View File

@@ -0,0 +1,15 @@
"""
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.GetModule()
obj.GetCompileUnit()
obj.GetFunction()
obj.GetBlock()
obj.GetLineEntry()
obj.GetSymbol()
obj.GetDescription(lldb.SBStream())

View File

@@ -0,0 +1,65 @@
"""
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.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)

View File

@@ -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.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)

View File

@@ -0,0 +1,22 @@
"""
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.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)

View File

@@ -0,0 +1,67 @@
"""
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.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()

View File

@@ -0,0 +1,14 @@
"""
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.Append(lldb.SBValue())
obj.GetSize()
obj.GetValueAtIndex(100)
obj.FindValueObjectByUID(200)
for val in obj:
s = str(val)

View File

@@ -0,0 +1,21 @@
"""
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.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()

View File

@@ -0,0 +1,45 @@
"""
Use lldb Python API to disassemble raw machine code bytes
"""
import os, time
import re
import unittest2
import lldb, lldbutil
from lldbtest import *
class DisassembleRawDataTestCase(TestBase):
mydir = os.path.join("python_api", "disassemble-raw-data")
@python_api_test
def test_disassemble_raw_data(self):
"""Test disassembling raw bytes with the API."""
self.disassemble_raw_data()
def disassemble_raw_data(self):
"""Test disassembling raw bytes with the API."""
# Create a target from the debugger.
target = self.dbg.CreateTargetWithFileAndTargetTriple ("", "x86_64")
self.assertTrue(target, VALID_TARGET)
raw_bytes = bytearray([0x48, 0x89, 0xe5])
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) == "movq")
self.assertTrue (inst.GetOperands(target) == '%' + "rsp, " + '%' + "rbp")
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,64 @@
"""
Use lldb Python API to disassemble raw machine code bytes
"""
import os, time
import re
import unittest2
import lldb, lldbutil
from lldbtest import *
class Disassemble_VST1_64(TestBase):
mydir = os.path.join("python_api", "disassemble-raw-data")
@python_api_test
def test_disassemble_invalid_vst_1_64_raw_data(self):
"""Test disassembling invalid vst1.64 raw bytes with the API."""
self.disassemble_invalid_vst_1_64_raw_data()
def 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")
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])
insts = target.GetInstructions(lldb.SBAddress(), raw_bytes)
if self.TraceOn():
print
for i in insts:
print "Disassembled%s" % str(i)
# Remove the following return statement when the radar is fixed.
return
# rdar://problem/11034702
# VST1 (multiple single elements) encoding?
# The disassembler should not crash!
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")
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,5 @@
LEVEL = ../../make
C_SOURCES := main.c
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,306 @@
"""
Test lldb Python event APIs.
"""
import os, time
import re
import unittest2
import lldb, lldbutil
from lldbtest import *
class EventAPITestCase(TestBase):
mydir = os.path.join("python_api", "event")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_listen_for_and_print_event_with_dsym(self):
"""Exercise SBEvent API."""
self.buildDsym()
self.do_listen_for_and_print_event()
@python_api_test
@dwarf_test
def test_listen_for_and_print_event_with_dwarf(self):
"""Exercise SBEvent API."""
self.buildDwarf()
self.do_listen_for_and_print_event()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_wait_for_event_with_dsym(self):
"""Exercise SBListener.WaitForEvent() API."""
self.buildDsym()
self.do_wait_for_event()
@python_api_test
@dwarf_test
def test_wait_for_event_with_dwarf(self):
"""Exercise SBListener.WaitForEvent() API."""
self.buildDwarf()
self.do_wait_for_event()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_add_listener_to_broadcaster_with_dsym(self):
"""Exercise some SBBroadcaster APIs."""
self.buildDsym()
self.do_add_listener_to_broadcaster()
@python_api_test
@dwarf_test
def test_add_listener_to_broadcaster_with_dwarf(self):
"""Exercise some SBBroadcaster APIs."""
self.buildDwarf()
self.do_add_listener_to_broadcaster()
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.')
def do_listen_for_and_print_event(self):
"""Create a listener and use SBEvent API to print the events received."""
exe = os.path.join(os.getcwd(), "a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# Now create a breakpoint on main.c by name 'c'.
breakpoint = target.BreakpointCreateByName('c', 'a.out')
# Now launch the process, and do not stop at the entry point.
process = target.LaunchSimple(None, None, os.getcwd())
self.assertTrue(process.GetState() == lldb.eStateStopped,
PROCESS_STOPPED)
# Get a handle on the process's broadcaster.
broadcaster = process.GetBroadcaster()
# Create an empty event object.
event = lldb.SBEvent()
# Create a listener object and register with the broadcaster.
listener = lldb.SBListener("my listener")
rc = broadcaster.AddListener(listener, lldb.SBProcess.eBroadcastBitStateChanged)
self.assertTrue(rc, "AddListener successfully retruns")
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.WaitForEventForBroadcasterWithType(5,
broadcaster,
lldb.SBProcess.eBroadcastBitStateChanged,
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
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()
def do_wait_for_event(self):
"""Get the listener associated with the debugger and exercise WaitForEvent API."""
exe = os.path.join(os.getcwd(), "a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# Now create a breakpoint on main.c by name 'c'.
breakpoint = target.BreakpointCreateByName('c', 'a.out')
#print "breakpoint:", breakpoint
self.assertTrue(breakpoint and
breakpoint.GetNumLocations() == 1,
VALID_BREAKPOINT)
# 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, None, None, None, None, None, 0, False, error)
self.assertTrue(error.Success() and process, PROCESS_IS_VALID)
# Get a handle on the process's broadcaster.
broadcaster = process.GetBroadcaster()
self.assertTrue(broadcaster, "Process with valid broadcaster")
# 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())
return
count = count + 1
print "Timeout: listener.WaitForEvent"
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")
def do_add_listener_to_broadcaster(self):
"""Get the broadcaster associated with the process and wait for broadcaster events."""
exe = os.path.join(os.getcwd(), "a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# Now create a breakpoint on main.c by name 'c'.
breakpoint = target.BreakpointCreateByName('c', 'a.out')
#print "breakpoint:", breakpoint
self.assertTrue(breakpoint and
breakpoint.GetNumLocations() == 1,
VALID_BREAKPOINT)
# Now launch the process, and do not stop at the entry point.
process = target.LaunchSimple(None, None, os.getcwd())
self.assertTrue(process.GetState() == lldb.eStateStopped,
PROCESS_STOPPED)
# Get a handle on the process's broadcaster.
broadcaster = process.GetBroadcaster()
self.assertTrue(broadcaster, "Process with valid broadcaster")
# Create an empty event object.
event = lldb.SBEvent()
self.assertFalse(event, "Event should not be valid initially")
# Create a listener object and register with the broadcaster.
listener = lldb.SBListener("TestEvents.listener")
rc = broadcaster.AddListener(listener, lldb.SBProcess.eBroadcastBitStateChanged)
self.assertTrue(rc, "AddListener successfully retruns")
# The finite state machine for our custom listening thread, with an
# initail state of 0, which means a "running" event is expected.
# It changes to 1 after "running" is received.
# It cahnges to 2 after "stopped" is received.
# 2 will be our final state and the test is complete.
self.state = 0
# 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.WaitForEventForBroadcasterWithType(5,
broadcaster,
lldb.SBProcess.eBroadcastBitStateChanged,
event):
desc = lldbutil.get_description(event)
#print "Event description:", desc
match = pattern.search(desc)
if not match:
break;
if self.context.state == 0 and match.group(1) == 'running':
self.context.state = 1
continue
elif self.context.state == 1 and match.group(1) == 'stopped':
# Whoopee, both events have been received!
self.context.state = 2
break
else:
break
print "Timeout: listener.WaitForEvent"
count = count + 1
if count > 6:
break
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()
# We are no longer interested in receiving state changed events.
# Remove our custom listener before the inferior is killed.
broadcaster.RemoveListener(listener, lldb.SBProcess.eBroadcastBitStateChanged)
# The final judgement. :-)
self.assertTrue(self.state == 2,
"Both expected state changed events received")
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,49 @@
//===-- main.c --------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
// This simple program is to 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;
}

View File

@@ -0,0 +1,8 @@
LEVEL = ../../make
CXX_SOURCES := main.cpp
# Clean renamed executable on 'make clean'
clean: OBJECTS+=no_synth
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,354 @@
"""Test Python APIs for working with formatters"""
import os, sys, time
import unittest2
import lldb
from lldbtest import *
import lldbutil
class SBFormattersAPITestCase(TestBase):
mydir = os.path.join("python_api", "formatters")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_with_dsym_formatters_api(self):
"""Test Python APIs for working with formatters"""
self.buildDsym()
self.setTearDownCleanup()
self.formatters()
@python_api_test
@dwarf_test
def test_with_dwarf_formatters_api(self):
"""Test Python APIs for working with formatters"""
self.buildDwarf()
self.setTearDownCleanup()
self.formatters()
@python_api_test
def test_force_synth_off(self):
"""Test that one can have the public API return non-synthetic SBValues if desired"""
self.buildDwarf(dictionary={'EXE':'no_synth'})
self.setTearDownCleanup()
self.force_synth_off()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
self.line = line_number('main.cpp', '// Set break point at this line.')
def formatters(self):
"""Test Python APIs for working with formatters"""
self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
self.runCmd("run", RUN_SUCCEEDED)
# The stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
substrs = ['stopped',
'stop reason = breakpoint'])
# This is the function to remove the custom formats in order to have a
# clean slate for the next test case.
def cleanup():
self.runCmd('type format clear', check=False)
self.runCmd('type summary clear', check=False)
self.runCmd('type filter clear', check=False)
self.runCmd('type 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.format = 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.enabled = True
new_category.AddTypeSummary(lldb.SBTypeNameSpecifier("^.*t$",True),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.enabled = 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 ./jas_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'])
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 (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.enabled = 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*")
def force_synth_off(self):
"""Test that one can have the public API return non-synthetic SBValues if desired"""
self.runCmd("file 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')
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,24 @@
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 __lldb_init_module(debugger,dict):
debugger.CreateCategory("JASSynth").AddTypeSynthetic(lldb.SBTypeNameSpecifier("JustAStruct"),
lldb.SBTypeSynthetic.CreateWithClassName("jas_synth.jasSynthProvider"))

View File

@@ -0,0 +1,42 @@
#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;
};
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;
return 0; // Set break point at this line.
}

View File

@@ -0,0 +1,5 @@
LEVEL = ../../make
C_SOURCES := main.c
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,226 @@
"""
Use lldb Python SBFrame API to get the argument values of the call stacks.
And other SBFrame API tests.
"""
import os, time
import re
import unittest2
import lldb, lldbutil
from lldbtest import *
class FrameAPITestCase(TestBase):
mydir = os.path.join("python_api", "frame")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_get_arg_vals_for_call_stack_with_dsym(self):
"""Exercise SBFrame.GetVariables() API to get argument vals."""
self.buildDsym()
self.do_get_arg_vals()
@python_api_test
@dwarf_test
def test_get_arg_vals_for_call_stack_with_dwarf(self):
"""Exercise SBFrame.GetVariables() API to get argument vals."""
self.buildDwarf()
self.do_get_arg_vals()
@python_api_test
def test_frame_api_boundary_condition(self):
"""Exercise SBFrame APIs with boundary condition inputs."""
self.buildDefault()
self.frame_api_boundary_condition()
@python_api_test
def test_frame_api_IsEqual(self):
"""Exercise SBFrame API IsEqual."""
self.buildDefault()
self.frame_api_IsEqual()
def do_get_arg_vals(self):
"""Get argument vals for the call stack when stopped on a breakpoint."""
exe = os.path.join(os.getcwd(), "a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# Now create a breakpoint on main.c by name 'c'.
breakpoint = target.BreakpointCreateByName('c', 'a.out')
#print "breakpoint:", breakpoint
self.assertTrue(breakpoint and
breakpoint.GetNumLocations() == 1,
VALID_BREAKPOINT)
# Now launch the process, and do not stop at the entry point.
process = target.LaunchSimple(None, None, os.getcwd())
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
import StringIO
session = StringIO.StringIO()
while process.GetState() == lldb.eStateStopped:
thread = process.GetThreadAtIndex(0)
# 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 >> session, "%s(%s)" % (name, ", ".join(argList))
# 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_str = pc_value.GetValue()
self.assertTrue (pc_value_str, "We should have a valid PC string.")
self.assertTrue (int(pc_value_str, 0) == 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 >> 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')"])
def frame_api_boundary_condition(self):
exe = os.path.join(os.getcwd(), "a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# 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, os.getcwd())
process = target.GetProcess()
self.assertTrue(process.GetState() == lldb.eStateStopped,
PROCESS_STOPPED)
thread = process.GetThreadAtIndex(0)
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)
def frame_api_IsEqual(self):
"""Exercise SBFrame API IsEqual."""
exe = os.path.join(os.getcwd(), "a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# Now create a breakpoint on main.c by name 'c'.
breakpoint = target.BreakpointCreateByName('c', 'a.out')
#print "breakpoint:", breakpoint
self.assertTrue(breakpoint and
breakpoint.GetNumLocations() == 1,
VALID_BREAKPOINT)
# Now launch the process, and do not stop at the entry point.
process = target.LaunchSimple(None, None, os.getcwd())
process = target.GetProcess()
self.assertTrue(process.GetState() == lldb.eStateStopped,
PROCESS_STOPPED)
thread = process.GetThreadAtIndex(0)
self.assertTrue(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))
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,9 @@
LEVEL = ../../../make
C_SOURCES := inlines.c
ifneq (,$(findstring icc,$(CC)))
CFLAGS += -debug inline-debug-info
endif
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,95 @@
"""
Testlldb Python SBFrame APIs IsInlined() and GetFunctionName().
"""
import os, time
import re
import unittest2
import lldb, lldbutil
from lldbtest import *
class InlinedFrameAPITestCase(TestBase):
mydir = os.path.join("python_api", "frame", "inlines")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_stop_at_outer_inline_with_dsym(self):
"""Exercise SBFrame.IsInlined() and SBFrame.GetFunctionName()."""
self.buildDsym()
self.do_stop_at_outer_inline()
@python_api_test
@dwarf_test
def test_stop_at_outer_inline_with_dwarf(self):
"""Exercise SBFrame.IsInlined() and SBFrame.GetFunctionName()."""
self.buildDwarf()
self.do_stop_at_outer_inline()
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.')
def do_stop_at_outer_inline(self):
"""Exercise SBFrame.IsInlined() and SBFrame.GetFunctionName()."""
exe = os.path.join(os.getcwd(), "a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# Now create a breakpoint on main.c by 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, os.getcwd())
process = target.GetProcess()
self.assertTrue(process.GetState() == lldb.eStateStopped,
PROCESS_STOPPED)
import 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);
#
frame0 = process.GetThreadAtIndex(0).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)])
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -0,0 +1,58 @@
//===-- main.c --------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
// This simple program is to 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;
}

View File

@@ -0,0 +1,5 @@
LEVEL = ../../make
C_SOURCES := main.c
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,127 @@
"""
Test retrieval of SBAddress from function/symbol, disassembly, and SBAddress APIs.
"""
import os, time
import re
import unittest2
import lldb, lldbutil
from lldbtest import *
class DisasmAPITestCase(TestBase):
mydir = os.path.join("python_api", "function_symbol")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_with_dsym(self):
"""Exercise getting SBAddress objects, disassembly, and SBAddress APIs."""
self.buildDsym()
self.disasm_and_address_api()
@python_api_test
@dwarf_test
def test_with_dwarf(self):
"""Exercise getting SBAddress objects, disassembly, and SBAddress APIs."""
self.buildDwarf()
self.disasm_and_address_api()
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.')
def disasm_and_address_api(self):
"""Exercise getting SBAddress objects, disassembly, and SBAddress APIs."""
exe = os.path.join(os.getcwd(), "a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# Now create 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, os.getcwd())
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 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")
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,96 @@
"""
Test newly added SBSymbol and SBAddress APIs.
"""
import os, time
import re
import unittest2
import lldb, lldbutil
from lldbtest import *
class SymbolAPITestCase(TestBase):
mydir = os.path.join("python_api", "function_symbol")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_with_dsym(self):
"""Exercise some SBSymbol and SBAddress APIs."""
self.buildDsym()
self.symbol_and_address_api()
@python_api_test
@dwarf_test
def test_with_dwarf(self):
"""Exercise some SBSymbol and SBAddress APIs."""
self.buildDwarf()
self.symbol_and_address_api()
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.')
def symbol_and_address_api(self):
"""Exercise some SBSymbol and SBAddress APIs."""
exe = os.path.join(os.getcwd(), "a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# Now create 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, os.getcwd())
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())
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,60 @@
//===-- main.c --------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
// This simple program is to 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 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 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;
}

View File

@@ -0,0 +1,7 @@
LEVEL = ../../make
C_SOURCES := main.c
# See TestHelloWorld.py, which specifies the executable name with a dictionary.
EXE := hello_world
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,207 @@
"""Test Python APIs for target (launch and attach), breakpoint, and process."""
import os, sys, time
import unittest2
import lldb
import time
from lldbtest import *
class HelloWorldTestCase(TestBase):
mydir = os.path.join("python_api", "hello_world")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_with_dsym_and_process_launch_api(self):
"""Create target, breakpoint, launch a process, and then kill it.
Use dsym info and process launch API.
"""
self.buildDsym(dictionary=self.d)
self.setTearDownCleanup(dictionary=self.d)
self.hello_world_python()
@python_api_test
@dwarf_test
def test_with_dwarf_and_process_launch_api(self):
"""Create target, breakpoint, launch a process, and then kill it.
Use dwarf debug map and process launch API.
"""
self.buildDwarf(dictionary=self.d)
self.setTearDownCleanup(dictionary=self.d)
self.hello_world_python()
@not_remote_testsuite_ready
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_with_dsym_and_attach_to_process_with_id_api(self):
"""Create target, spawn a process, and attach to it with process id.
Use dsym info and attach to process with id API.
"""
self.buildDsym(dictionary=self.d)
self.setTearDownCleanup(dictionary=self.d)
self.hello_world_attach_with_id_api()
@not_remote_testsuite_ready
@python_api_test
@dwarf_test
@expectedFailurei386 # llvm.org/pr17384: lldb needs to be aware of linux-vdso.so to unwind stacks properly
def test_with_dwarf_and_attach_to_process_with_id_api(self):
"""Create target, spawn a process, and attach to it with process id.
Use dwarf map (no dsym) and attach to process with id API.
"""
self.buildDwarf(dictionary=self.d)
self.setTearDownCleanup(dictionary=self.d)
self.hello_world_attach_with_id_api()
@not_remote_testsuite_ready
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_with_dsym_and_attach_to_process_with_name_api(self):
"""Create target, spawn a process, and attach to it with process name.
Use dsym info and attach to process with name API.
"""
self.buildDsym(dictionary=self.d)
self.setTearDownCleanup(dictionary=self.d)
self.hello_world_attach_with_name_api()
@not_remote_testsuite_ready
@python_api_test
@dwarf_test
@expectedFailurei386 # llvm.org/pr17384: lldb needs to be aware of linux-vdso.so to unwind stacks properly
def test_with_dwarf_and_attach_to_process_with_name_api(self):
"""Create target, spawn a process, and attach to it with process name.
Use dwarf map (no dsym) and attach to process with name API.
"""
self.buildDwarf(dictionary=self.d)
self.setTearDownCleanup(dictionary=self.d)
self.hello_world_attach_with_name_api()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Get the full path to our executable to be attached/debugged.
self.exe = os.path.join(os.getcwd(), self.testMethodName)
self.d = {'EXE': self.testMethodName}
# 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 hello_world_python(self):
"""Create target, breakpoint, launch a process, and then kill it."""
target = self.dbg.CreateTarget(self.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, os.getcwd())
# 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 = process.GetThreadAtIndex(0)
if thread.GetStopReason() != lldb.eStopReasonBreakpoint:
from lldbutil import stop_reason_to_str
self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS %
stop_reason_to_str(thread.GetStopReason()))
# The breakpoint should have a hit count of 1.
self.assertTrue(breakpoint.GetHitCount() == 1, BREAKPOINT_HIT_ONCE)
def hello_world_attach_with_id_api(self):
"""Create target, spawn a process, and attach to it by id."""
target = self.dbg.CreateTarget(self.exe)
# Spawn a new process
popen = self.spawnSubprocess(self.exe, ["abc", "xyz"])
self.addTearDownHook(self.cleanupSubprocesses)
# Give the subprocess time to start and wait for user input
time.sleep(0.25)
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.
import lldbutil
stacktraces = lldbutil.print_stacktraces(process, string_buffer=True)
self.expect(stacktraces, exe=False,
substrs = ['main.c:%d' % self.line2,
'(int)argc=3'])
def hello_world_attach_with_name_api(self):
"""Create target, spawn a process, and attach to it by name."""
target = self.dbg.CreateTarget(self.exe)
# Spawn a new process
popen = self.spawnSubprocess(self.exe, ["abc", "xyz"])
self.addTearDownHook(self.cleanupSubprocesses)
# Give the subprocess time to start and wait for user input
time.sleep(0.25)
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(self.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.
import lldbutil
stacktraces = lldbutil.print_stacktraces(process, string_buffer=True)
self.expect(stacktraces, exe=False,
substrs = ['main.c:%d' % self.line2,
'(int)argc=3'])
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,15 @@
#include <stdio.h>
int main(int argc, char const *argv[]) {
printf("Hello world.\n"); // Set break point at this line.
if (argc == 1)
return 0;
// Waiting to be attached by the debugger, otherwise.
char line[100];
while (fgets(line, sizeof(line), stdin)) { // Waiting to be attached...
printf("input line=>%s\n", line);
}
printf("Exiting now\n");
}

View File

@@ -0,0 +1,5 @@
LEVEL = ../../make
C_SOURCES := main.c
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,46 @@
"""Test the SBInputReader callbacks."""
import os
import unittest2
import lldb
from lldbtest import TestBase, python_api_test, dwarf_test
class InputReaderCallbackCase(TestBase):
mydir = os.path.join("python_api", "input_reader")
@python_api_test
@dwarf_test
def test_with_dwarf_and_good_callback(self):
"""Test the SBInputReader callbacks."""
def callback(reader, notification, content):
global succeeded
if (notification == lldb.eInputReaderGotToken):
self.succeeded = True
return len(content)
self.buildDwarf()
self.input_reader_callback(callback)
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
def input_reader_callback(self, callback):
"""Test the SBInputReader callbacks."""
self.succeeded = False
input_reader = lldb.SBInputReader()
input_reader.Initialize(self.dbg, callback, lldb.eInputReaderGranularityByte, "$", "^", False)
self.dbg.PushInputReader(input_reader)
self.dbg.DispatchInput("Hello!$")
self.assertFalse(self.dbg.InputReaderIsTopReader(input_reader))
self.assertTrue(self.succeeded)
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,6 @@
#include <stdio.h>
int main(int argc, char const *argv[]) {
printf("Hello world.\n");
return 0;
}

View File

@@ -0,0 +1,5 @@
LEVEL = ../../make
C_SOURCES := main.c
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,91 @@
"""Test the SBCommandInterpreter APIs."""
import os
import unittest2
import lldb
import pexpect
from lldbtest import *
class CommandInterpreterAPICase(TestBase):
mydir = os.path.join("python_api", "interpreter")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_with_dsym_and_process_launch_api(self):
"""Test the SBCommandInterpreter APIs."""
self.buildDsym()
self.command_interpreter_api()
@python_api_test
@dwarf_test
def test_with_dwarf_and_process_launch_api(self):
"""Test the SBCommandInterpreter APIs."""
self.buildDwarf()
self.command_interpreter_api()
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.')
def command_interpreter_api(self):
"""Test the SBCommandInterpreter APIs."""
exe = os.path.join(os.getcwd(), "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 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)
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,6 @@
#include <stdio.h>
int main(int argc, char const *argv[]) {
printf("Hello world.\n");
return 0;
}

View File

@@ -0,0 +1,6 @@
LEVEL = ../../../make
C_SOURCES := main.c
MAKE_DSYM :=NO
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,66 @@
"""
Test utility functions for the frame object.
"""
import os
import unittest2
import lldb
from lldbtest import *
class FrameUtilsTestCase(TestBase):
mydir = os.path.join("python_api", "lldbutil", "frame")
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.")
@python_api_test
def test_frame_utils(self):
"""Test utility functions for the frame object."""
self.buildDefault()
self.frame_utils()
def frame_utils(self):
exe = os.path.join(os.getcwd(), "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, os.getcwd())
if not process:
self.fail("SBTarget.LaunchProcess() failed")
self.assertTrue(process.GetState() == lldb.eStateStopped,
PROCESS_STOPPED)
import 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
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,47 @@
//===-- main.c --------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
int 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;
}

View File

@@ -0,0 +1,8 @@
LEVEL = ../../../make
CFLAGS_EXTRAS := -D__STDC_LIMIT_MACROS
LD_EXTRAS := -lpthread
CXX_SOURCES := main.cpp
MAKE_DSYM :=NO
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,134 @@
"""
Test the iteration protocol for some lldb container objects.
"""
import os, time
import re
import unittest2
import lldb
from lldbtest import *
class LLDBIteratorTestCase(TestBase):
mydir = os.path.join("python_api", "lldbutil", "iter")
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.')
@python_api_test
def test_lldb_iter_module(self):
"""Test module_iter works correctly for SBTarget -> SBModule."""
self.buildDefault()
self.lldb_iter_module()
@python_api_test
def test_lldb_iter_breakpoint(self):
"""Test breakpoint_iter works correctly for SBTarget -> SBBreakpoint."""
self.buildDefault()
self.lldb_iter_breakpoint()
@python_api_test
def test_lldb_iter_frame(self):
"""Test iterator works correctly for SBProcess->SBThread->SBFrame."""
self.buildDefault()
self.lldb_iter_frame()
def lldb_iter_module(self):
exe = os.path.join(os.getcwd(), "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, os.getcwd())
if not process:
self.fail("SBTarget.LaunchProcess() failed")
from 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))
def lldb_iter_breakpoint(self):
exe = os.path.join(os.getcwd(), "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 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))
def lldb_iter_frame(self):
exe = os.path.join(os.getcwd(), "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, os.getcwd())
if not process:
self.fail("SBTarget.LaunchProcess() failed")
from 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)
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,94 @@
"""
Test the iteration protocol for frame registers.
"""
import os, time
import re
import unittest2
import lldb
from lldbtest import *
class RegistersIteratorTestCase(TestBase):
mydir = os.path.join("python_api", "lldbutil", "iter")
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.')
@expectedFailureFreeBSD # llvm.org/pr14600 - Exception state registers not supported on FreeBSD
@expectedFailureLinux # llvm.org/pr14600 - Exception state registers not supported on Linux
@python_api_test
def test_iter_registers(self):
"""Test iterator works correctly for lldbutil.iter_registers()."""
self.buildDefault()
self.iter_registers()
def iter_registers(self):
exe = os.path.join(os.getcwd(), "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, os.getcwd())
if not process:
self.fail("SBTarget.LaunchProcess() failed")
import 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)
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())
# And these should also work.
for kind in ["General Purpose Registers",
"Floating Point Registers",
"Exception State Registers"]:
REGs = lldbutil.get_registers(frame, kind)
self.assertTrue(REGs)
# We've finished dumping the registers for frame #0.
break
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,128 @@
//===-- main.cpp ------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// C includes
#include <pthread.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
pthread_t g_thread_1 = NULL;
pthread_t g_thread_2 = NULL;
pthread_t g_thread_3 = NULL;
typedef enum {
eGet,
eAssign,
eClearBits
} MaskAction;
uint32_t mask_access (MaskAction action, uint32_t mask = 0);
uint32_t
mask_access (MaskAction action, uint32_t mask)
{
static pthread_mutex_t g_mask_mutex = PTHREAD_MUTEX_INITIALIZER;
static uint32_t g_mask = 0;
::pthread_mutex_lock (&g_mask_mutex);
switch (action)
{
case eGet:
break;
case eAssign:
g_mask |= mask;
break;
case eClearBits:
g_mask &= ~mask;
break;
}
uint32_t new_mask = g_mask;
::pthread_mutex_unlock (&g_mask_mutex);
return new_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);
while (mask_access(eGet) & thread_mask)
{
// random micro second sleep from zero to 3 seconds
int usec = ::rand() % 3000000;
printf ("%s (thread = %u) doing a usleep (%d)...\n", __FUNCTION__, thread_index, usec);
::usleep (usec);
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[])
{
int err;
void *thread_result = NULL;
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
err = ::pthread_create (&g_thread_1, NULL, thread_func, &thread_index_1);
err = ::pthread_create (&g_thread_2, NULL, thread_func, &thread_index_2);
err = ::pthread_create (&g_thread_3, NULL, thread_func, &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
err = ::pthread_join (g_thread_1, &thread_result);
err = ::pthread_join (g_thread_2, &thread_result);
err = ::pthread_join (g_thread_3, &thread_result);
return 0;
}

View File

@@ -0,0 +1,8 @@
LEVEL = ../../../make
CFLAGS_EXTRAS := -D__STDC_LIMIT_MACROS
LD_EXTRAS := -lpthread
CXX_SOURCES := main.cpp
MAKE_DSYM :=NO
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,60 @@
"""
Test SBprocess and SBThread APIs with printing of the stack traces using lldbutil.
"""
import os, time
import re
import unittest2
import lldb
from lldbtest import *
class ThreadsStackTracesTestCase(TestBase):
mydir = "python_api/lldbutil/process"
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.')
@expectedFailureFreeBSD("llvm.org/pr16696") # live debugging lacks threaded inferior support
@expectedFailureLinux # llvm.org/pr15415 -- partial stack trace in thread 1 (while stopped inside a read() call)
@python_api_test
def test_stack_traces(self):
"""Test SBprocess and SBThread APIs with printing of the stack traces."""
self.buildDefault()
self.break_and_print_stacktraces()
def break_and_print_stacktraces(self):
"""Break at main.cpp:68 and do a threads dump"""
exe = os.path.join(os.getcwd(), "a.out")
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
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(["abc", "xyz"], None, os.getcwd())
if not process:
self.fail("SBTarget.LaunchProcess() failed")
import 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()))
stacktraces = lldbutil.print_stacktraces(process, string_buffer=True)
self.expect(stacktraces, exe=False,
substrs = ['(int)argc=3'])
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,128 @@
//===-- main.cpp ------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// C includes
#include <pthread.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
pthread_t g_thread_1 = NULL;
pthread_t g_thread_2 = NULL;
pthread_t g_thread_3 = NULL;
typedef enum {
eGet,
eAssign,
eClearBits
} MaskAction;
uint32_t mask_access (MaskAction action, uint32_t mask = 0);
uint32_t
mask_access (MaskAction action, uint32_t mask)
{
static pthread_mutex_t g_mask_mutex = PTHREAD_MUTEX_INITIALIZER;
static uint32_t g_mask = 0;
::pthread_mutex_lock (&g_mask_mutex);
switch (action)
{
case eGet:
break;
case eAssign:
g_mask |= mask;
break;
case eClearBits:
g_mask &= ~mask;
break;
}
uint32_t new_mask = g_mask;
::pthread_mutex_unlock (&g_mask_mutex);
return new_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);
while (mask_access(eGet) & thread_mask)
{
// random micro second sleep from zero to 3 seconds
int usec = ::rand() % 3000000;
printf ("%s (thread = %u) doing a usleep (%d)...\n", __FUNCTION__, thread_index, usec);
::usleep (usec);
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[])
{
int err;
void *thread_result = NULL;
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
err = ::pthread_create (&g_thread_1, NULL, thread_func, &thread_index_1);
err = ::pthread_create (&g_thread_2, NULL, thread_func, &thread_index_2);
err = ::pthread_create (&g_thread_3, NULL, thread_func, &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
err = ::pthread_join (g_thread_1, &thread_result);
err = ::pthread_join (g_thread_2, &thread_result);
err = ::pthread_join (g_thread_3, &thread_result);
return 0;
}

View File

@@ -0,0 +1,8 @@
LEVEL = ../../make
CFLAGS_EXTRAS := -D__STDC_LIMIT_MACROS
LD_EXTRAS := -lpthread
CXX_SOURCES := main.cpp b.cpp c.cpp
MAKE_DSYM :=NO
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,139 @@
"""
Test some SBModule and SBSection APIs.
"""
import os, time
import re
import unittest2
import lldb
from lldbtest import *
from lldbutil import symbol_type_to_str
class ModuleAndSectionAPIsTestCase(TestBase):
mydir = os.path.join("python_api", "module_section")
@python_api_test
def test_module_and_section(self):
"""Test module and section APIs."""
self.buildDefault()
self.module_and_section()
@python_api_test
def test_module_and_section_boundary_condition(self):
"""Test module and section APIs by passing None when it expects a Python string."""
self.buildDefault()
self.module_and_section_boundary_condition()
@python_api_test
def test_module_compile_unit_iter(self):
"""Test module's compile unit iterator APIs."""
self.buildDefault()
self.module_compile_unit_iter()
def module_and_section(self):
exe = os.path.join(os.getcwd(), "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()
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())
def module_and_section_boundary_condition(self):
exe = os.path.join(os.getcwd(), "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)
def module_compile_unit_iter(self):
exe = os.path.join(os.getcwd(), "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
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,3 @@
int b_function(int input) {
return input * 2;
}

View File

@@ -0,0 +1,3 @@
int c_function(int input) {
return input * 3;
}

View File

@@ -0,0 +1,128 @@
//===-- main.cpp ------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// C includes
#include <pthread.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
pthread_t g_thread_1 = NULL;
pthread_t g_thread_2 = NULL;
pthread_t g_thread_3 = NULL;
typedef enum {
eGet,
eAssign,
eClearBits
} MaskAction;
uint32_t mask_access (MaskAction action, uint32_t mask = 0);
uint32_t
mask_access (MaskAction action, uint32_t mask)
{
static pthread_mutex_t g_mask_mutex = PTHREAD_MUTEX_INITIALIZER;
static uint32_t g_mask = 0;
::pthread_mutex_lock (&g_mask_mutex);
switch (action)
{
case eGet:
break;
case eAssign:
g_mask |= mask;
break;
case eClearBits:
g_mask &= ~mask;
break;
}
uint32_t new_mask = g_mask;
::pthread_mutex_unlock (&g_mask_mutex);
return new_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);
while (mask_access(eGet) & thread_mask)
{
// random micro second sleep from zero to 3 seconds
int usec = ::rand() % 3000000;
printf ("%s (thread = %u) doing a usleep (%d)...\n", __FUNCTION__, thread_index, usec);
::usleep (usec);
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[])
{
int err;
void *thread_result = NULL;
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
err = ::pthread_create (&g_thread_1, NULL, thread_func, &thread_index_1);
err = ::pthread_create (&g_thread_2, NULL, thread_func, &thread_index_2);
err = ::pthread_create (&g_thread_3, NULL, thread_func, &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
err = ::pthread_join (g_thread_1, &thread_result);
err = ::pthread_join (g_thread_2, &thread_result);
err = ::pthread_join (g_thread_3, &thread_result);
return 0;
}

View File

@@ -0,0 +1,9 @@
LEVEL = ../../make
OBJC_SOURCES := main.m
CFLAGS_EXTRAS += -w
include $(LEVEL)/Makefile.rules
LDFLAGS += -framework Cocoa

View File

@@ -0,0 +1,79 @@
"""
Test SBType for ObjC classes.
"""
import os, time
import re
import unittest2
import lldb, lldbutil
from lldbtest import *
class ObjCSBTypeTestCase(TestBase):
mydir = os.path.join("python_api", "objc_type")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_with_dsym(self):
"""Test SBType for ObjC classes."""
self.buildDsym()
self.objc_sbtype_test()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dwarf_test
def test_with_dwarf(self):
"""Test SBType for ObjC classes."""
self.buildDwarf()
self.objc_sbtype_test()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
self.line = line_number("main.m", '// Break at this line')
def objc_sbtype_test(self):
"""Exercise SBType and SBTypeList API."""
exe = os.path.join(os.getcwd(), "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, os.getcwd())
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")
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,52 @@
//===-- main.m ------------------------------------------------*- ObjC -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#import <Cocoa/Cocoa.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;
}

View File

@@ -0,0 +1,5 @@
LEVEL = ../../make
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,339 @@
"""
Test SBProcess APIs, including ReadMemory(), WriteMemory(), and others.
"""
import os, time
import unittest2
import lldb
from lldbutil import get_stopped_thread, state_type_to_str
from lldbtest import *
class ProcessAPITestCase(TestBase):
mydir = os.path.join("python_api", "process")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_read_memory_with_dsym(self):
"""Test Python SBProcess.ReadMemory() API."""
self.buildDsym()
self.read_memory()
@python_api_test
@dwarf_test
def test_read_memory_with_dwarf(self):
"""Test Python SBProcess.ReadMemory() API."""
self.buildDwarf()
self.read_memory()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_write_memory_with_dsym(self):
"""Test Python SBProcess.WriteMemory() API."""
self.buildDsym()
self.write_memory()
@python_api_test
@dwarf_test
def test_write_memory_with_dwarf(self):
"""Test Python SBProcess.WriteMemory() API."""
self.buildDwarf()
self.write_memory()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_access_my_int_with_dsym(self):
"""Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs."""
self.buildDsym()
self.access_my_int()
@python_api_test
@dwarf_test
def test_access_my_int_with_dwarf(self):
"""Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs."""
self.buildDwarf()
self.access_my_int()
@python_api_test
def test_remote_launch(self):
"""Test SBProcess.RemoteLaunch() API with a process not in eStateConnected, and it should fail."""
self.buildDefault()
self.remote_launch_should_fail()
@python_api_test
def test_get_num_supported_hardware_watchpoints(self):
"""Test SBProcess.GetNumSupportedHardwareWatchpoints() API with a process."""
self.buildDefault()
self.get_num_supported_hardware_watchpoints()
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'.")
def read_memory(self):
"""Test Python SBProcess.ReadMemory() API."""
exe = os.path.join(os.getcwd(), "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, os.getcwd())
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 = '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")
def write_memory(self):
"""Test Python SBProcess.WriteMemory() API."""
exe = os.path.join(os.getcwd(), "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, os.getcwd())
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 = 'a')
def access_my_int(self):
"""Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs."""
exe = os.path.join(os.getcwd(), "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, os.getcwd())
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 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.
new_value = str(bytes)
error = lldb.SBError()
result = process.WriteMemory(location, new_value, 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")
# Use "ascii" as the encoding because each element of 'content' is in the range [0..255].
new_bytes = bytearray(content, "ascii")
# The bytearray_to_int utility function expects a little endian bytearray.
if byteOrder == lldb.eByteOrderBig:
new_bytes.reverse()
new_value = bytearray_to_int(new_bytes, 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 new_bytes:
print "byte:", i
def remote_launch_should_fail(self):
"""Test SBProcess.RemoteLaunch() API with a process not in eStateConnected, and it should fail."""
exe = os.path.join(os.getcwd(), "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, os.getcwd())
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")
def get_num_supported_hardware_watchpoints(self):
"""Test SBProcess.GetNumSupportedHardwareWatchpoints() API with a process."""
exe = os.path.join(os.getcwd(), "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, os.getcwd())
error = lldb.SBError();
num = process.GetNumSupportedHardwareWatchpoints(error)
if self.TraceOn() and error.Success():
print "Number of supported hardware watchpoints: %d" % num
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,6 @@
LEVEL = ../../../make
C_SOURCES := main.c
EXE := process_io
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,70 @@
"""Test Python APIs for process IO."""
import os, sys, time
import unittest2
import lldb
from lldbtest import *
class ProcessIOTestCase(TestBase):
mydir = os.path.join("python_api", "process", "io")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_put_stdin_with_dsym(self):
"""Exercise SBProcess.PutSTDIN()."""
self.buildDsym()
self.put_stdin()
@python_api_test
@dwarf_test
def test_put_stdin_with_dwarf(self):
"""Exercise SBProcess.PutSTDIN()."""
self.buildDwarf()
self.put_stdin()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Get the full path to our executable to be debugged.
self.exe = os.path.join(os.getcwd(), "process_io")
def put_stdin(self):
"""Launch a process and use SBProcess.PutSTDIN() to write data to it."""
target = self.dbg.CreateTarget(self.exe)
# Perform synchronous interaction with the debugger.
self.setAsync(True)
process = target.LaunchSimple(None, None, os.getcwd())
if self.TraceOn():
print "process launched."
self.assertTrue(process, PROCESS_IS_VALID)
process.PutSTDIN("Line 1 Entered.\n")
process.PutSTDIN("Line 2 Entered.\n")
process.PutSTDIN("Line 3 Entered.\n")
for i in range(5):
output = process.GetSTDOUT(500)
error = process.GetSTDERR(500)
if self.TraceOn():
print "output->|%s|" % output
# 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 "input line=>1" in output:
return
time.sleep(5)
self.fail("Expected output form launched process did not appear?")
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,14 @@
#include <stdio.h>
int main(int argc, char const *argv[]) {
printf("Hello world.\n");
char line[100];
int count = 1;
while (fgets(line, sizeof(line), stdin)) { // Reading from stdin...
fprintf(stderr, "input line=>%d\n", count++);
if (count > 3)
break;
}
printf("Exiting now\n");
}

View File

@@ -0,0 +1,31 @@
//===-- main.c --------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <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.
}

View File

@@ -0,0 +1,5 @@
LEVEL = ../../make
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,69 @@
"""
Check that SBValue.GetValueAsSigned() does the right thing for a 32-bit -1.
"""
import os, time
import unittest2
import lldb
from lldbtest import *
import lldbutil
class Radar12481949DataFormatterTestCase(TestBase):
# test for rdar://problem/12481949
mydir = os.path.join("python_api", "rdar-12481949")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dsym_test
def test_with_dsym_and_run_command(self):
"""Check that SBValue.GetValueAsSigned() does the right thing for a 32-bit -1."""
self.buildDsym()
self.rdar12481949_commands()
@dwarf_test
def test_with_dwarf_and_run_command(self):
"""Check that SBValue.GetValueAsSigned() does the right thing for a 32-bit -1."""
self.buildDwarf()
self.rdar12481949_commands()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break at.
self.line = line_number('main.cpp', '// Set break point at this line.')
def rdar12481949_commands(self):
"""Check that SBValue.GetValueAsSigned() does the right thing for a 32-bit -1."""
self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
self.runCmd("run", RUN_SUCCEEDED)
# The stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
substrs = ['stopped',
'stop reason = breakpoint'])
# This is the function to remove the custom formats in order to have a
# clean slate for the next test case.
def cleanup():
self.runCmd('type format delete hex', check=False)
self.runCmd('type summary clear', check=False)
# Execute the cleanup function during test case tear down.
self.addTearDownHook(cleanup)
self.assertTrue(self.frame().FindVariable("myvar").GetValueAsSigned() == -1, "GetValueAsSigned() says -1")
self.assertTrue(self.frame().FindVariable("myvar").GetValueAsSigned() != 0xFFFFFFFF, "GetValueAsSigned() does not say 0xFFFFFFFF")
self.assertTrue(self.frame().FindVariable("myvar").GetValueAsSigned() != 0xFFFFFFFFFFFFFFFF, "GetValueAsSigned() does not say 0xFFFFFFFFFFFFFFFF")
self.assertTrue(self.frame().FindVariable("myvar").GetValueAsUnsigned() != -1, "GetValueAsUnsigned() does not say -1")
self.assertTrue(self.frame().FindVariable("myvar").GetValueAsUnsigned() == 0xFFFFFFFFFFFFFFFF, "GetValueAsUnsigned() says 0xFFFFFFFFFFFFFFFF")
self.assertTrue(self.frame().FindVariable("myvar").GetValueAsSigned() != 0xFFFFFFFF, "GetValueAsUnsigned() does not say 0xFFFFFFFF")
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,17 @@
//===-- main.cpp ------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
#include <stdint.h>
int main ()
{
int32_t myvar = -1;
printf ("%d\n", myvar); // Set break point at this line.
return myvar+1;
}

View File

@@ -0,0 +1,5 @@
LEVEL = ../../make
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,343 @@
"""Test the SBData APIs."""
import os
import unittest2
import lldb
import pexpect
from lldbtest import *
from math import fabs
import lldbutil
class SBDataAPICase(TestBase):
mydir = os.path.join("python_api", "sbdata")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_with_dsym_and_run_command(self):
"""Test the SBData APIs."""
self.buildDsym()
self.data_api()
@python_api_test
@dwarf_test
def test_with_dwarf_and_run_command(self):
"""Test the SBData APIs."""
self.buildDwarf()
self.data_api()
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')
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))
def data_api(self):
"""Test the SBData APIs."""
self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
self.runCmd("run", RUN_SUCCEEDED)
# The stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
substrs = ['stopped',
'stop reason = breakpoint'])
target = self.dbg.GetSelectedTarget()
process = target.GetProcess()
thread = process.GetThreadAtIndex(0)
frame = thread.GetSelectedFrame()
if self.TraceOn():
print frame
foobar = frame.FindVariable('foobar')
self.assertTrue(foobar.IsValid())
if self.TraceOn():
print foobar
data = foobar.GetPointeeData(0, 2)
if self.TraceOn():
print data
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()
if self.TraceOn():
print data
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())
if self.TraceOn():
print new_foobar
data = new_foobar.GetData()
if self.TraceOn():
print data
self.assertTrue(data.uint32[0] == 8, 'then foo[1].a == 8')
self.assertTrue(data.uint32[1] == 7, 'then foo[1].b == 7')
self.assertTrue(fabs(data.float[2] - 3.14) < 1, 'foo[1].c == 3.14') # exploiting that sizeof(uint32) == sizeof(float)
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()
if self.TraceOn():
print data
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()
if self.TraceOn():
print barfoo
if self.TraceOn():
print data
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))
if self.TraceOn():
print new_object
self.assertTrue(new_object.GetLoadAddress() == 0xFFFFFFFFFFFFFFFF, 'GetLoadAddress() == invalid')
self.assertTrue(new_object.AddressOf().IsValid() == False, 'AddressOf() == invalid')
self.assertTrue(new_object.GetAddress().IsValid() == False, 'GetAddress() == invalid')
self.assertTrue(new_object.GetValue() == "1", 'new_object == 1')
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)
if self.TraceOn():
print data
# 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) # !
data2 = lldb.SBData.CreateDataFromUInt64Array(process.GetByteOrder(),process.GetAddressByteSize(),[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.uint64s == [1,2,3,4,5], 'read_data_helper failure: data2 == [1,2,3,4,5]')
data2 = lldb.SBData.CreateDataFromSInt32Array(process.GetByteOrder(),process.GetAddressByteSize(),[2, -2])
self.assertTrue(data2.sint32[0:2] == [2,-2], 'signed32 data2 = [2,-2]')
data2.Append(lldb.SBData.CreateDataFromSInt64Array(process.GetByteOrder(),process.GetAddressByteSize(),[2, -2]))
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]')
data2 = lldb.SBData.CreateDataFromUInt32Array(process.GetByteOrder(),process.GetAddressByteSize(),[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)
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.GetSignedInt32, 0, 2)
self.assert_data(data2.GetSignedInt32, 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')
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,43 @@
//===-- main.c --------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <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;
}

View File

@@ -0,0 +1,5 @@
LEVEL = ../../make
C_SOURCES := main.c
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,104 @@
"""
Test SBSymbolContext APIs.
"""
import os, time
import re
import unittest2
import lldb, lldbutil
from lldbtest import *
class SymbolContextAPITestCase(TestBase):
mydir = os.path.join("python_api", "symbol-context")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_with_dsym(self):
"""Exercise SBSymbolContext API extensively."""
self.buildDsym()
self.symbol_context()
@python_api_test
@dwarf_test
def test_with_dwarf(self):
"""Exercise SBSymbolContext API extensively."""
self.buildDwarf()
self.symbol_context()
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.')
def symbol_context(self):
"""Get an SBSymbolContext object and call its many methods."""
exe = os.path.join(os.getcwd(), "a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# Now create a breakpoint on main.c by name 'c'.
breakpoint = target.BreakpointCreateByName('c', 'a.out')
#print "breakpoint:", breakpoint
self.assertTrue(breakpoint and
breakpoint.GetNumLocations() == 1,
VALID_BREAKPOINT)
# Now launch the process, and do not stop at entry point.
process = target.LaunchSimple(None, None, os.getcwd())
self.assertTrue(process, PROCESS_IS_VALID)
# Frame #0 should be on self.line.
from 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 = [os.path.join(self.mydir, 'a.out')])
compileUnit = context.GetCompileUnit()
self.expect(str(compileUnit), "The compile unit should match", exe=False,
substrs = [os.path.join(self.mydir, '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'")
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,51 @@
//===-- main.c --------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
// This simple program is to 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;
}

View File

@@ -0,0 +1,5 @@
LEVEL = ../../make
C_SOURCES := main.c
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,314 @@
"""
Test SBTarget APIs.
"""
import os, time
import re
import unittest2
import lldb, lldbutil
from lldbtest import *
class TargetAPITestCase(TestBase):
mydir = os.path.join("python_api", "target")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_find_global_variables_with_dsym(self):
"""Exercise SBTaget.FindGlobalVariables() API."""
d = {'EXE': 'a.out'}
self.buildDsym(dictionary=d)
self.setTearDownCleanup(dictionary=d)
self.find_global_variables('a.out')
#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")
@python_api_test
@dwarf_test
def test_find_global_variables_with_dwarf(self):
"""Exercise SBTarget.FindGlobalVariables() API."""
d = {'EXE': 'b.out'}
self.buildDwarf(dictionary=d)
self.setTearDownCleanup(dictionary=d)
self.find_global_variables('b.out')
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_find_functions_with_dsym(self):
"""Exercise SBTaget.FindFunctions() API."""
d = {'EXE': 'a.out'}
self.buildDsym(dictionary=d)
self.setTearDownCleanup(dictionary=d)
self.find_functions('a.out')
@python_api_test
@dwarf_test
def test_find_functions_with_dwarf(self):
"""Exercise SBTarget.FindFunctions() API."""
d = {'EXE': 'b.out'}
self.buildDwarf(dictionary=d)
self.setTearDownCleanup(dictionary=d)
self.find_functions('b.out')
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_get_description_with_dsym(self):
"""Exercise SBTaget.GetDescription() API."""
self.buildDsym()
self.get_description()
@python_api_test
@dwarf_test
def test_get_description_with_dwarf(self):
"""Exercise SBTarget.GetDescription() API."""
self.buildDwarf()
self.get_description()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_launch_new_process_and_redirect_stdout_with_dsym(self):
"""Exercise SBTaget.Launch() API."""
self.buildDsym()
self.launch_new_process_and_redirect_stdout()
@python_api_test
@dwarf_test
def test_launch_new_process_and_redirect_stdout_with_dwarf(self):
"""Exercise SBTarget.Launch() API."""
self.buildDwarf()
self.launch_new_process_and_redirect_stdout()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_resolve_symbol_context_with_address_with_dsym(self):
"""Exercise SBTaget.ResolveSymbolContextForAddress() API."""
self.buildDsym()
self.resolve_symbol_context_with_address()
@python_api_test
@dwarf_test
def test_resolve_symbol_context_with_address_with_dwarf(self):
"""Exercise SBTarget.ResolveSymbolContextForAddress() API."""
self.buildDwarf()
self.resolve_symbol_context_with_address()
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.')
def find_global_variables(self, exe_name):
"""Exercise SBTaget.FindGlobalVariables() API."""
exe = os.path.join(os.getcwd(), 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, os.getcwd())
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 m.GetFileSpec().GetDirectory() == os.getcwd() 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_functions(self, exe_name):
"""Exercise SBTaget.FindFunctions() API."""
exe = os.path.join(os.getcwd(), 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 = os.path.join(os.getcwd(), "a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
from 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
def launch_new_process_and_redirect_stdout(self):
"""Exercise SBTaget.Launch() API with redirected stdout."""
exe = os.path.join(os.getcwd(), "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.
error = lldb.SBError()
process = target.Launch (self.dbg.GetListener(), None, None, None, "stdout.txt", None, None, 0, False, error)
process.Continue()
#self.runCmd("process status")
# The 'stdout.txt' file should now exist.
self.assertTrue(os.path.isfile("stdout.txt"),
"'stdout.txt' exists due to redirected stdout via SBTarget.Launch() API.")
# Read the output file produced by running the program.
with open('stdout.txt', 'r') as f:
output = f.read()
# Let's delete the 'stdout.txt' file as a cleanup step.
try:
os.remove("stdout.txt")
pass
except OSError:
pass
self.expect(output, exe=False,
substrs = ["a(1)", "b(2)", "a(3)"])
def resolve_symbol_context_with_address(self):
"""Exercise SBTaget.ResolveSymbolContextForAddress() API."""
exe = os.path.join(os.getcwd(), "a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# Now create 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, os.getcwd())
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 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")
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,59 @@
//===-- main.c --------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
// This simple program is to 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[])
{
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;
}

View File

@@ -0,0 +1,5 @@
LEVEL = ../../make
CXX_SOURCES ?= main.cpp
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,294 @@
"""
Test SBThread APIs.
"""
import os, time
import unittest2
import lldb
from lldbutil import get_stopped_thread, get_caller_symbol
from lldbtest import *
class ThreadAPITestCase(TestBase):
mydir = os.path.join("python_api", "thread")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_get_process_with_dsym(self):
"""Test Python SBThread.GetProcess() API."""
self.buildDsym()
self.get_process()
@python_api_test
@dwarf_test
def test_get_process_with_dwarf(self):
"""Test Python SBThread.GetProcess() API."""
self.buildDwarf()
self.get_process()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_get_stop_description_with_dsym(self):
"""Test Python SBThread.GetStopDescription() API."""
self.buildDsym()
self.get_stop_description()
@python_api_test
@dwarf_test
def test_get_stop_description_with_dwarf(self):
"""Test Python SBThread.GetStopDescription() API."""
self.buildDwarf()
self.get_stop_description()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_run_to_address_with_dsym(self):
"""Test Python SBThread.RunToAddress() API."""
# We build a different executable than the default buildDwarf() does.
d = {'CXX_SOURCES': 'main2.cpp', 'EXE': self.exe_name}
self.buildDsym(dictionary=d)
self.setTearDownCleanup(dictionary=d)
self.run_to_address(self.exe_name)
@python_api_test
@dwarf_test
def test_run_to_address_with_dwarf(self):
"""Test Python SBThread.RunToAddress() API."""
# We build a different executable than the default buildDwarf() does.
d = {'CXX_SOURCES': 'main2.cpp', 'EXE': self.exe_name}
self.buildDwarf(dictionary=d)
self.setTearDownCleanup(dictionary=d)
self.run_to_address(self.exe_name)
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_step_out_of_malloc_into_function_b_with_dsym(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 buildDsym() does.
d = {'CXX_SOURCES': 'main2.cpp', 'EXE': self.exe_name}
self.buildDsym(dictionary=d)
self.setTearDownCleanup(dictionary=d)
self.step_out_of_malloc_into_function_b(self.exe_name)
@expectedFailureLinux # llvm.org/pr14416
@python_api_test
@dwarf_test
def test_step_out_of_malloc_into_function_b_with_dwarf(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 buildDwarf() does.
d = {'CXX_SOURCES': 'main2.cpp', 'EXE': self.exe_name}
self.buildDwarf(dictionary=d)
self.setTearDownCleanup(dictionary=d)
self.step_out_of_malloc_into_function_b(self.exe_name)
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_step_over_3_times_with_dsym(self):
"""Test Python SBThread.StepOver() API."""
# We build a different executable than the default buildDsym() does.
d = {'CXX_SOURCES': 'main2.cpp', 'EXE': self.exe_name}
self.buildDsym(dictionary=d)
self.setTearDownCleanup(dictionary=d)
self.step_over_3_times(self.exe_name)
@python_api_test
@dwarf_test
def test_step_over_3_times_with_dwarf(self):
"""Test Python SBThread.StepOver() API."""
# We build a different executable than the default buildDwarf() does.
d = {'CXX_SOURCES': 'main2.cpp', 'EXE': self.exe_name}
self.buildDwarf(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 = os.path.join(os.getcwd(), "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, os.getcwd())
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 = os.path.join(os.getcwd(), "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, os.getcwd())
thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint")
#self.runCmd("process status")
# Due to the typemap magic (see lldb.swig), we pass in an (int)length to GetStopDescription
# and expect to get a Python string as the return object!
# The 100 is just an arbitrary number specifying the buffer size.
stop_description = thread.GetStopDescription(100)
self.expect(stop_description, exe=False,
startstr = 'breakpoint')
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 = os.path.join(os.getcwd(), exe_name)
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
breakpoint = target.BreakpointCreateByName('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, os.getcwd())
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)
#print "caller symbol of malloc:", caller_symbol
if not caller_symbol:
self.fail("Test failed: could not locate the caller symbol of malloc")
if caller_symbol == "b(int)":
break
#self.runCmd("thread backtrace")
#self.runCmd("process status")
process.Continue()
thread.StepOut()
self.runCmd("thread backtrace")
#self.runCmd("process status")
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 = os.path.join(os.getcwd(), 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, os.getcwd())
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 = os.path.join(os.getcwd(), 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, os.getcwd())
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")
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

Some files were not shown because too many files have changed in this diff Show More