Initial import of lldb
Change-Id: Ib244e837bee349effa12b2ff6ffffbe3d730e929
This commit is contained in:
5
external/bsd/llvm/dist/lldb/test/python_api/process/Makefile
vendored
Normal file
5
external/bsd/llvm/dist/lldb/test/python_api/process/Makefile
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
LEVEL = ../../make
|
||||
|
||||
CXX_SOURCES := main.cpp
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
339
external/bsd/llvm/dist/lldb/test/python_api/process/TestProcessAPI.py
vendored
Normal file
339
external/bsd/llvm/dist/lldb/test/python_api/process/TestProcessAPI.py
vendored
Normal 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()
|
||||
6
external/bsd/llvm/dist/lldb/test/python_api/process/io/Makefile
vendored
Normal file
6
external/bsd/llvm/dist/lldb/test/python_api/process/io/Makefile
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
LEVEL = ../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
EXE := process_io
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
70
external/bsd/llvm/dist/lldb/test/python_api/process/io/TestProcessIO.py
vendored
Normal file
70
external/bsd/llvm/dist/lldb/test/python_api/process/io/TestProcessIO.py
vendored
Normal 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()
|
||||
14
external/bsd/llvm/dist/lldb/test/python_api/process/io/main.c
vendored
Normal file
14
external/bsd/llvm/dist/lldb/test/python_api/process/io/main.c
vendored
Normal 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");
|
||||
}
|
||||
31
external/bsd/llvm/dist/lldb/test/python_api/process/main.cpp
vendored
Normal file
31
external/bsd/llvm/dist/lldb/test/python_api/process/main.cpp
vendored
Normal 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.
|
||||
}
|
||||
Reference in New Issue
Block a user