voltron/tests/lldb_api_tests.py

165 lines
4.7 KiB
Python

"""
Tests that exercise the LLDB backend directly by loading an inferior and then
poking at it with the LLDBAdaptor class.
Tests:
LLDBAdaptor
"""
import tempfile
import sys
import json
import time
import logging
import subprocess
import threading
from mock import Mock
from nose.tools import *
import voltron
from voltron.core import *
from voltron.api import *
from voltron.plugin import PluginManager, DebuggerAdaptorPlugin
import platform
if platform.system() == 'Darwin':
sys.path.append("/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python")
try:
import lldb
from common import *
voltron.setup_env()
log = logging.getLogger('tests')
def setup():
global adaptor, dbg, target
log.info("setting up LLDB API tests")
# create an LLDBAdaptor
pm = PluginManager()
plugin = pm.debugger_plugin_for_host('lldb')
adaptor = plugin.adaptor_class()
# compile and load the test inferior
subprocess.call("cc -o tests/inferior tests/inferior.c", shell=True)
target = adaptor.host.CreateTargetWithFileAndArch("tests/inferior", lldb.LLDB_ARCH_DEFAULT)
main_bp = target.BreakpointCreateByName("main", target.GetExecutable().GetFilename())
def teardown():
time.sleep(2)
def test_version():
assert 'lldb' in adaptor.version()
def test_state_invalid():
try:
adaptor.state()
exception = False
except NoSuchTargetException:
exception = True
except:
exception = False
assert exception
def test_targets_not_running():
t = adaptor.targets()[0]
assert t["state"] == "invalid"
assert t["arch"] == "x86_64"
assert t["id"] == 0
assert len(t["file"]) > 0
assert 'inferior' in t["file"]
def test_targets_stopped():
process = target.LaunchSimple(None, None, os.getcwd())
t = adaptor.targets()[0]
assert t["state"] == "stopped"
process.Destroy()
def test_registers():
process = target.LaunchSimple(None, None, os.getcwd())
regs = adaptor.registers()
assert regs is not None
assert len(regs) > 0
assert regs['rip'] != 0
process.Destroy()
def test_stack_pointer():
process = target.LaunchSimple(None, None, os.getcwd())
sp = adaptor.stack_pointer()
assert sp != 0
process.Destroy()
def test_program_counter():
process = target.LaunchSimple(None, None, os.getcwd())
pc_name, pc = adaptor.program_counter()
assert pc != 0
process.Destroy()
def test_memory():
process = target.LaunchSimple(None, None, os.getcwd())
regs = adaptor.registers()
mem = adaptor.memory(address=regs['rip'], length=0x40)
assert len(mem) == 0x40
process.Destroy()
def test_stack():
process = target.LaunchSimple(None, None, os.getcwd())
stack = adaptor.stack(length=0x40)
assert len(stack) == 0x40
process.Destroy()
def test_disassemble():
process = target.LaunchSimple(None, None, os.getcwd())
output = adaptor.disassemble(count=0x20)
assert len(output) > 0
process.Destroy()
def test_command():
process = target.LaunchSimple(None, None, os.getcwd())
output = adaptor.command("reg read")
assert len(output) > 0
assert 'rax' in output
process.Destroy()
def test_dereference_main():
process = target.LaunchSimple(None, None, os.getcwd())
regs = adaptor.registers()
output = adaptor.dereference(regs['rip'])
assert ('symbol', 'main + 0x0') in output
process.Destroy()
def test_dereference_rsp():
process = target.LaunchSimple(None, None, os.getcwd())
regs = adaptor.registers()
output = adaptor.dereference(regs['rsp'])
assert ('symbol', 'start + 0x1') in output
process.Destroy()
def test_dereference_string():
process = target.LaunchSimple(None, None, os.getcwd())
regs = adaptor.registers()
output = adaptor.dereference(regs['rsp'] + 0x20)
assert 'inferior' in list(output[-1])[-1]
process.Destroy()
def test_breakpoints():
process = target.LaunchSimple(None, None, os.getcwd())
bps = adaptor.breakpoints()
assert len(bps) == 1
assert bps[0]['one_shot'] == False
assert bps[0]['enabled']
assert bps[0]['id'] == 1
assert bps[0]['hit_count'] > 0
assert bps[0]['locations'][0]['name'] == "inferior`main"
process.Destroy()
def test_capabilities():
assert adaptor.capabilities() == ['async']
except:
print("No LLDB")