Fixes for remote test suite execution of the "lldb/test/lang" directory.

Fixes include:
- Add a new lldbtest.TestBase function named registerSharedLibrariesWithTarget. This function can be called using the shared libraries for your test suite either as shared library basename ("foo"), path basename ("libfoo.dylib") or full path ("/tmp/lldb/test/lang/c/carp/libfoo.dylib"). These shared libraries are then registered with the target so they will be downloaded when the test is run remotely. 
- Changed a lot of tests over to use SBDebugger::CreateTarget(...) calls instead of using "file a.out" commands.
- Cleaned up some tests to add new locations for breakpoints that all compilers should be able to abide by. Some tests and constants being loaded into values of structs and some compilers like arm64 will often combine two constant data loads into a single source line so some breakpoint locations were not being set correctly. Adding lines like 'puts("")' allow us to lock onto a source line that will have code.

llvm-svn: 222156
This commit is contained in:
Greg Clayton 2014-11-17 18:40:27 +00:00
parent cb29c1ae25
commit 35c91347e6
16 changed files with 207 additions and 72 deletions

View File

@ -80,18 +80,27 @@ class AnonymousTestCase(TestBase):
# Call super's setUp().
TestBase.setUp(self)
# Find the line numbers to break in main.c.
self.line0 = line_number('main.c', '// Set breakpoint 0 here.')
self.line1 = line_number('main.c', '// Set breakpoint 1 here.')
self.line2 = line_number('main.c', '// Set breakpoint 2 here.')
self.source = 'main.c'
self.line0 = line_number(self.source, '// Set breakpoint 0 here.')
self.line1 = line_number(self.source, '// Set breakpoint 1 here.')
self.line2 = line_number(self.source, '// Set breakpoint 2 here.')
def common_setup(self, line):
# Set debugger into synchronous mode
self.dbg.SetAsync(False)
# Create a target
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)
# Set breakpoints inside and outside methods that take pointers to the containing struct.
lldbutil.run_break_set_by_file_and_line (self, "main.c", line, num_expected_locations=1, loc_exact=True)
lldbutil.run_break_set_by_file_and_line (self, self.source, line, num_expected_locations=1, loc_exact=True)
self.runCmd("run", RUN_SUCCEEDED)
# Now launch the process, and do not stop at entry point.
process = target.LaunchSimple (None, None, self.get_process_working_directory())
self.assertTrue(process, PROCESS_IS_VALID)
# The stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
@ -153,11 +162,16 @@ class AnonymousTestCase(TestBase):
self.expect("expression *(type_z *)pz", error = True)
def child_by_name(self):
# Set debugger into synchronous mode
self.dbg.SetAsync(False)
# Create a target
exe = os.path.join (os.getcwd(), "a.out")
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
break_in_main = target.BreakpointCreateBySourceRegex ('// Set breakpoint 2 here.', lldb.SBFileSpec("main.c"))
break_in_main = target.BreakpointCreateBySourceRegex ('// Set breakpoint 2 here.', lldb.SBFileSpec(self.source))
self.assertTrue(break_in_main, VALID_BREAKPOINT)
process = target.LaunchSimple (None, None, self.get_process_working_directory())

View File

@ -27,7 +27,9 @@ class GlobalVariablesTestCase(TestBase):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break inside main().
self.line = line_number('main.c', '// Set break point at this line.')
self.source = 'main.c'
self.line = line_number(self.source, '// Set break point at this line.')
self.shlib_names = ["a"]
if sys.platform.startswith("freebsd") or sys.platform.startswith("linux"):
# LD_LIBRARY_PATH must be set so the shared libraries are found on startup
if "LD_LIBRARY_PATH" in os.environ:
@ -38,16 +40,20 @@ class GlobalVariablesTestCase(TestBase):
def global_variables(self):
"""Test 'frame variable --scope --no-args' which omits args and shows scopes."""
exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# Create a target by the debugger.
target = self.dbg.CreateTarget("a.out")
self.assertTrue(target, VALID_TARGET)
# Break inside the main.
lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
lldbutil.run_break_set_by_file_and_line (self, self.source, self.line, num_expected_locations=1, loc_exact=True)
self.runCmd("run", RUN_SUCCEEDED)
self.runCmd("process status", "Get process status")
# Register our shared libraries for remote targets so they get automatically uploaded
environment = self.registerSharedLibrariesWithTarget(target, self.shlib_names)
# Now launch the process, and do not stop at entry point.
process = target.LaunchSimple (None, environment, self.get_process_working_directory())
self.assertTrue(process, PROCESS_IS_VALID)
# The stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
substrs = ['stopped',

View File

@ -1,6 +1,6 @@
LEVEL = ../../../make
DYLIB_NAME := libfoo
DYLIB_NAME := foo
DYLIB_C_SOURCES := foo.c
C_SOURCES := main.c
CFLAGS_EXTRAS += -fPIC

View File

@ -38,22 +38,33 @@ class SharedLibTestCase(TestBase):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break inside main().
self.line = line_number('main.c', '// Set breakpoint 0 here.')
self.source = 'main.c'
self.line = line_number(self.source, '// Set breakpoint 0 here.')
if sys.platform.startswith("freebsd") or sys.platform.startswith("linux"):
if "LD_LIBRARY_PATH" in os.environ:
self.runCmd("settings set target.env-vars " + self.dylibPath + "=" + os.environ["LD_LIBRARY_PATH"] + ":" + os.getcwd())
else:
self.runCmd("settings set target.env-vars " + self.dylibPath + "=" + os.getcwd())
self.addTearDownHook(lambda: self.runCmd("settings remove target.env-vars " + self.dylibPath))
self.shlib_names = ["foo"]
def common_setup(self):
exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# Run in synchronous mode
self.dbg.SetAsync(False)
# Create a target by the debugger.
target = self.dbg.CreateTarget("a.out")
self.assertTrue(target, VALID_TARGET)
# Break inside the foo function which takes a bar_ptr argument.
lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
lldbutil.run_break_set_by_file_and_line (self, self.source, self.line, num_expected_locations=1, loc_exact=True)
self.runCmd("run", RUN_SUCCEEDED)
# Register our shared libraries for remote targets so they get automatically uploaded
environment = self.registerSharedLibrariesWithTarget(target, self.shlib_names)
# Now launch the process, and do not stop at entry point.
process = target.LaunchSimple (None, environment, self.get_process_working_directory())
self.assertTrue(process, PROCESS_IS_VALID)
# The stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
@ -70,16 +81,16 @@ class SharedLibTestCase(TestBase):
if "clang" in self.getCompiler() and "3.4" in self.getCompilerVersion():
self.skipTest("llvm.org/pr16214 -- clang emits partial DWARF for structures referenced via typedef")
self.common_setup()
self.common_setup()
# This should display correctly.
self.expect("expression --show-types -- *my_foo_ptr", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["(foo)", "(sub_foo)", "other_element = 3"])
@unittest2.expectedFailure("rdar://problem/10381325")
@unittest2.expectedFailure("rdar://problem/10704639")
def frame_var(self):
"""Test that types work when defined in a shared library and forward-declared in the main executable"""
self.common_setup()
self.common_setup()
# This should display correctly.
self.expect("frame variable --show-types -- *my_foo_ptr", VARIABLES_DISPLAYED_CORRECTLY,

View File

@ -1,6 +1,6 @@
LEVEL = ../../../make
DYLIB_NAME := libfoo
DYLIB_NAME := foo
DYLIB_C_SOURCES := foo.c
C_SOURCES := main.c
CFLAGS_EXTRAS += -fPIC

View File

@ -6,7 +6,7 @@ import lldb
from lldbtest import *
import lldbutil
class SharedLibTestCase(TestBase):
class SharedLibStrippedTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@ -38,22 +38,33 @@ class SharedLibTestCase(TestBase):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break inside main().
self.line = line_number('main.c', '// Set breakpoint 0 here.')
self.source = 'main.c'
self.line = line_number(self.source, '// Set breakpoint 0 here.')
if sys.platform.startswith("freebsd") or sys.platform.startswith("linux"):
if "LD_LIBRARY_PATH" in os.environ:
self.runCmd("settings set target.env-vars " + self.dylibPath + "=" + os.environ["LD_LIBRARY_PATH"] + ":" + os.getcwd())
else:
self.runCmd("settings set target.env-vars " + self.dylibPath + "=" + os.getcwd())
self.addTearDownHook(lambda: self.runCmd("settings remove target.env-vars " + self.dylibPath))
self.shlib_names = ["foo"]
def common_setup(self):
exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# Run in synchronous mode
self.dbg.SetAsync(False)
# Create a target by the debugger.
target = self.dbg.CreateTarget("a.out")
self.assertTrue(target, VALID_TARGET)
# Break inside the foo function which takes a bar_ptr argument.
lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
lldbutil.run_break_set_by_file_and_line (self, self.source, self.line, num_expected_locations=1, loc_exact=True)
self.runCmd("run", RUN_SUCCEEDED)
# Register our shared libraries for remote targets so they get automatically uploaded
environment = self.registerSharedLibrariesWithTarget(target, self.shlib_names)
# Now launch the process, and do not stop at entry point.
process = target.LaunchSimple (None, environment, self.get_process_working_directory())
self.assertTrue(process, PROCESS_IS_VALID)
# The stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,

View File

@ -32,8 +32,8 @@ class Char1632TestCase(TestBase):
TestBase.setUp(self)
# Find the line number to break for main.cpp.
self.source = 'main.cpp'
self.line = line_number(self.source, '// Set break point at this line.')
self.lines = [ line_number(self.source, '// breakpoint1'),
line_number(self.source, '// breakpoint2') ]
def char1632(self):
"""Test that the C++11 support for char16_t and char32_t works correctly."""
exe = os.path.join(os.getcwd(), "a.out")
@ -42,10 +42,11 @@ class Char1632TestCase(TestBase):
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# Break on the struct declration statement in main.cpp.
lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line)
# Set breakpoints
for line in self.lines:
lldbutil.run_break_set_by_file_and_line (self, "main.cpp", line)
# Now launch the process, and do not stop at entry point.
# Now launch the process, and do not stop at entry point and stop at breakpoint1
process = target.LaunchSimple (None, None, self.get_process_working_directory())
if not process:
@ -68,8 +69,8 @@ class Char1632TestCase(TestBase):
self.expect("frame variable s32",
substrs = ['(char32_t *) s32 = 0x00000000'])
self.runCmd("next")
self.runCmd("next")
# continue and hit breakpoint2
self.runCmd("continue")
# check that the new strings show
self.expect("frame variable s16 s32",

View File

@ -14,8 +14,9 @@ int main (int argc, char const *argv[])
auto cs32 = U"hello world ྒྙྐ";
char16_t *s16 = (char16_t *)u"ﺸﺵۻ";
char32_t *s32 = (char32_t *)U"ЕЙРГЖО";
s32 = nullptr; // Set break point at this line.
s32 = nullptr; // breakpoint1
s32 = (char32_t *)U"";
s16 = (char16_t *)u"色ハ匂ヘト散リヌルヲ";
s32 = nullptr; // breakpoint2
return 0;
}

View File

@ -30,17 +30,22 @@ class UnsignedTypesTestCase(TestBase):
# 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.')
self.source = 'main.cpp'
self.line = line_number(self.source, '// Set break point at this line.')
def signed_types(self):
"""Test that variables with signed types display correctly."""
exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# Run in synchronous mode
self.dbg.SetAsync(False)
# Break on line 22 in main() aftre the variables are assigned values.
lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
# Create a target by the debugger.
target = self.dbg.CreateTarget("a.out")
self.assertTrue(target, VALID_TARGET)
self.runCmd("run", RUN_SUCCEEDED)
lldbutil.run_break_set_by_file_and_line (self, self.source, self.line, num_expected_locations=1, loc_exact=True)
# Now launch the process, and do not stop at entry point.
process = target.LaunchSimple (None, None, self.get_process_working_directory())
self.assertTrue(process, PROCESS_IS_VALID)
# The stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,

View File

@ -6,6 +6,8 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
int main (int argc, char const *argv[])
{
char the_char = 'c';
@ -19,8 +21,8 @@ int main (int argc, char const *argv[])
signed short the_signed_short = 'c';
signed int the_signed_int = 'c';
signed long the_signed_long = 'c';
signed long long the_signed_long_long = 'c'; // Set break point at this line.
signed long long the_signed_long_long = 'c';
puts(""); // Set break point at this line.
return the_char - the_signed_char +
the_short - the_signed_short +
the_int - the_signed_int +

View File

@ -1,6 +1,6 @@
LEVEL = ../../../make
DYLIB_NAME := libContainer
DYLIB_NAME := Container
DYLIB_OBJC_SOURCES := Container.m
OBJC_SOURCES := main.m

View File

@ -26,16 +26,25 @@ class ForwardDeclTestCase(TestBase):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break inside main().
self.line = line_number('main.m', '// Set breakpoint 0 here.')
self.source = 'main.m'
self.line = line_number(self.source, '// Set breakpoint 0 here.')
self.shlib_names = ["Container"]
def common_setup(self):
exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# Create a target by the debugger.
target = self.dbg.CreateTarget("a.out")
self.assertTrue(target, VALID_TARGET)
# Break inside the foo function which takes a bar_ptr argument.
lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
# Create the breakpoint inside function 'main'.
breakpoint = target.BreakpointCreateByLocation(self.source, self.line)
self.assertTrue(breakpoint, VALID_BREAKPOINT)
# Register our shared libraries for remote targets so they get automatically uploaded
environment = self.registerSharedLibrariesWithTarget(target, self.shlib_names)
self.runCmd("run", RUN_SUCCEEDED)
# Now launch the process, and do not stop at entry point.
process = target.LaunchSimple (None, environment, self.get_process_working_directory())
self.assertTrue(process, PROCESS_IS_VALID)
# The stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,

View File

@ -19,17 +19,21 @@ class FoundationDisassembleTestCase(TestBase):
def test_foundation_disasm(self):
"""Do 'disassemble -n func' on each and every 'Code' symbol entry from the Foundation.framework."""
self.buildDefault()
exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
self.runCmd("run", RUN_SUCCEEDED)
# Enable synchronous mode
self.dbg.SetAsync(False)
# Create a target by the debugger.
target = self.dbg.CreateTarget("a.out")
self.assertTrue(target, VALID_TARGET)
self.runCmd("image list")
raw_output = self.res.GetOutput()
# Grok the full path to the foundation framework.
for line in raw_output.split(os.linesep):
match = re.search(" (/.*/Foundation.framework/.*)$", line)
if match:
foundation_framework = match.group(1)
# Now launch the process, and do not stop at entry point.
process = target.LaunchSimple (None, environment, self.get_process_working_directory())
self.assertTrue(process, PROCESS_IS_VALID)
for module in target.modules:
if module.file.basename == "Foundation":
foundation_framework = module.file.fullpath
break
self.assertTrue(match, "Foundation.framework path located")
@ -69,12 +73,19 @@ class FoundationDisassembleTestCase(TestBase):
def do_simple_disasm(self):
"""Do a bunch of simple disassemble commands."""
exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# Create a target by the debugger.
target = self.dbg.CreateTarget("a.out")
self.assertTrue(target, VALID_TARGET)
print target
for module in target.modules:
print module
# Stop at +[NSString stringWithFormat:].
symbol_name = "+[NSString stringWithFormat:]"
break_results = lldbutil.run_break_set_command (self, "_regexp-break %s"%(symbol_name))
lldbutil.check_breakpoint_result (self, break_results, symbol_name=symbol_name, num_locations=1)
# Stop at -[MyString initWithNSString:].

View File

@ -48,9 +48,29 @@ class HiddenIvarsTestCase(TestBase):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break inside main().
self.line = line_number('main.m', '// Set breakpoint 0 here.')
self.source = 'main.m'
self.line = line_number(self.source, '// breakpoint1')
# The makefile names of the shared libraries as they appear in DYLIB_NAME.
# The names should have no loading "lib" or extension as they will be localized
self.shlib_names = ["InternalDefiner"]
def common_setup(self):
# Create a target by the debugger.
target = self.dbg.CreateTarget("a.out")
self.assertTrue(target, VALID_TARGET)
# Create the breakpoint inside function 'main'.
breakpoint = target.BreakpointCreateByLocation(self.source, self.line)
self.assertTrue(breakpoint, VALID_BREAKPOINT)
# Register our shared libraries for remote targets so they get automatically uploaded
environment = self.registerSharedLibrariesWithTarget(target, self.shlib_names)
# Now launch the process, and do not stop at entry point.
process = target.LaunchSimple (None, environment, self.get_process_working_directory())
self.assertTrue(process, PROCESS_IS_VALID)
exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)

View File

@ -43,13 +43,12 @@
int main(int argc, const char * argv[])
{
@autoreleasepool {
Container *j = [[Container alloc] init];
InheritContainer *k = [[InheritContainer alloc] init];
printf("ivar value = %u\n", (unsigned)j->_definer->foo); // Set breakpoint 0 here.
printf("ivar value = %u\n", (unsigned)k->foo); // Set breakpoint 1 here.
printf("ivar value = %u\n", (unsigned)j->_definer->foo); // breakpoint1
printf("ivar value = %u\n", (unsigned)k->foo);
}
return 0;
}

View File

@ -1624,6 +1624,51 @@ class TestBase(Base):
else:
print "error: making remote directory '%s': %s" % (remote_test_dir, error)
def registerSharedLibrariesWithTarget(self, target, shlibs):
'''If we are remotely running the test suite, register the shared libraries with the target so they get uploaded, otherwise do nothing
Any modules in the target that have their remote install file specification set will
get uploaded to the remote host. This function registers the local copies of the
shared libraries with the target and sets their remote install locations so they will
be uploaded when the target is run.
'''
environment = None
if lldb.remote_platform and shlibs:
dyld_environment_var = 'DYLD_FRAMEWORK_PATH' # TODO: localize this for remote systems other than darwin
shlib_prefix = "lib"
shlib_extension = ".dylib" # TODO: localize this for remote systems other than darwin
remote_working_dir = lldb.remote_platform.GetWorkingDirectory()
# TODO: localize this environment variable for systems other than darwin
environment = ['%s=%s' % (dyld_environment_var, remote_working_dir)]
# Add any shared libraries to our target if remote so they get
# uploaded into the working directory on the remote side
for name in shlibs:
# The path can be a full path to a shared library, or a make file name like "Foo" for
# "libFoo.dylib" or "libFoo.so", or "Foo.so" for "Foo.so" or "libFoo.so", or just a
# basename like "libFoo.so". So figure out which one it is and resolve the local copy
# of the shared library accordingly
if os.path.exists(name):
local_shlib_path = name # name is the full path to the local shared library
else:
# Check relative names
local_shlib_path = os.path.join(os.getcwd(), shlib_prefix + name + shlib_extension)
if not os.path.exists(local_shlib_path):
local_shlib_path = os.path.join(os.getcwd(), name + shlib_extension)
if not os.path.exists(local_shlib_path):
local_shlib_path = os.path.join(os.getcwd(), name)
# Make sure we found the local shared library in the above code
self.assertTrue(os.path.exists(local_shlib_path))
# Add the shared library to our target
shlib_module = target.AddModule(local_shlib_path, None, None, None)
# We must set the remote install location if we want the shared library
# to get uploaded to the remote target
remote_shlib_path = os.path.join(lldb.remote_platform.GetWorkingDirectory(), os.path.basename(local_shlib_path))
shlib_module.SetRemoteInstallFileSpec(lldb.SBFileSpec(remote_shlib_path, False))
environment
# utility methods that tests can use to access the current objects
def target(self):
if not self.dbg: