forked from OSchip/llvm-project
[TestLoadUnload] Enable for Android while skipping it for other remotes.
Summary: This change adds all the necessary infrastructure required to selectively enable and make TestLoadUnload work for Android. One test, which tests the module search paths, is still kept disabled for remote as search paths (because of module caching) are local anyway. Reviewers: tberghammer Reviewed By: tberghammer Subscribers: emaste, lldb-commits, tberghammer Differential Revision: http://reviews.llvm.org/D10469 llvm-svn: 239965
This commit is contained in:
parent
cd3afea451
commit
4470f3826c
|
@ -43,8 +43,8 @@ a.out: main.o $(LIB_D)
|
||||||
main.o: main.c
|
main.o: main.c
|
||||||
$(CC) $(CFLAGS) -c main.c
|
$(CC) $(CFLAGS) -c main.c
|
||||||
|
|
||||||
hidden/$(LIB_D): b.o
|
hidden/$(LIB_D): dh.o
|
||||||
$(CC) $(CFLAGS) $(LD_FLAGS) -o hidden/$(LIB_D) d.o
|
$(CC) $(CFLAGS) $(LD_FLAGS) -o hidden/$(LIB_D) dh.o
|
||||||
if [ "$(OS)" = "Darwin" ]; then dsymutil -o hidden/$(LIB_D).dSYM hidden/$(LIB_D); fi
|
if [ "$(OS)" = "Darwin" ]; then dsymutil -o hidden/$(LIB_D).dSYM hidden/$(LIB_D); fi
|
||||||
|
|
||||||
$(LIB_A): a.o $(LIB_B)
|
$(LIB_A): a.o $(LIB_B)
|
||||||
|
@ -75,5 +75,8 @@ $(LIB_D): d.o
|
||||||
d.o: d.c
|
d.o: d.c
|
||||||
$(CC) $(CFLAGS) -c d.c
|
$(CC) $(CFLAGS) -c d.c
|
||||||
|
|
||||||
|
dh.o: d.c
|
||||||
|
$(CC) $(CFLAGS) -DHIDDEN -c d.c -o dh.o
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(wildcard *.o *~ *.dylib *.so a.out *.dSYM hidden/*)
|
rm -rf $(wildcard *.o *~ *.dylib *.so a.out *.dSYM hidden/*)
|
||||||
|
|
|
@ -25,10 +25,47 @@ class LoadUnloadTestCase(TestBase):
|
||||||
self.line_d_function = line_number('d.c',
|
self.line_d_function = line_number('d.c',
|
||||||
'// Find this line number within d_dunction().')
|
'// Find this line number within d_dunction().')
|
||||||
if not self.platformIsDarwin():
|
if not self.platformIsDarwin():
|
||||||
if "LD_LIBRARY_PATH" in os.environ:
|
if not lldb.remote_platform and "LD_LIBRARY_PATH" in os.environ:
|
||||||
self.runCmd("settings set target.env-vars " + self.dylibPath + "=" + os.environ["LD_LIBRARY_PATH"] + ":" + os.getcwd())
|
self.runCmd("settings set target.env-vars " + self.dylibPath + "=" + os.environ["LD_LIBRARY_PATH"] + ":" + os.getcwd())
|
||||||
else:
|
else:
|
||||||
self.runCmd("settings set target.env-vars " + self.dylibPath + "=" + os.getcwd())
|
if lldb.remote_platform:
|
||||||
|
wd = lldb.remote_platform.GetWorkingDirectory()
|
||||||
|
else:
|
||||||
|
wd = os.getcwd()
|
||||||
|
self.runCmd("settings set target.env-vars " + self.dylibPath + "=" + wd)
|
||||||
|
|
||||||
|
def copy_shlibs_to_remote(self, hidden_dir=False):
|
||||||
|
""" Copies the shared libs required by this test suite to remote.
|
||||||
|
Does nothing in case of non-remote platforms.
|
||||||
|
"""
|
||||||
|
if lldb.remote_platform:
|
||||||
|
cwd = os.getcwd()
|
||||||
|
shlibs = ['libloadunload_a.so', 'libloadunload_b.so',
|
||||||
|
'libloadunload_c.so', 'libloadunload_d.so']
|
||||||
|
wd = lldb.remote_platform.GetWorkingDirectory()
|
||||||
|
for f in shlibs:
|
||||||
|
err = lldb.remote_platform.Put(
|
||||||
|
lldb.SBFileSpec(os.path.join(cwd, f)),
|
||||||
|
lldb.SBFileSpec(os.path.join(wd, f)))
|
||||||
|
if err.Fail():
|
||||||
|
raise RuntimeError(
|
||||||
|
"Unable copy '%s' to '%s'.\n>>> %s" %
|
||||||
|
(f, wd, err.GetCString()))
|
||||||
|
if hidden_dir:
|
||||||
|
shlib = 'libloadunload_d.so'
|
||||||
|
hidden_dir = os.path.join(wd, 'hidden')
|
||||||
|
hidden_file = os.path.join(hidden_dir, shlib)
|
||||||
|
err = lldb.remote_platform.MakeDirectory(hidden_dir)
|
||||||
|
if err.Fail():
|
||||||
|
raise RuntimeError(
|
||||||
|
"Unable to create a directory '%s'." % hidden_dir)
|
||||||
|
err = lldb.remote_platform.Put(
|
||||||
|
lldb.SBFileSpec(os.path.join(cwd, 'hidden', shlib)),
|
||||||
|
lldb.SBFileSpec(hidden_file))
|
||||||
|
if err.Fail():
|
||||||
|
raise RuntimeError(
|
||||||
|
"Unable copy 'libloadunload_d.so' to '%s'.\n>>> %s" %
|
||||||
|
(wd, err.GetCString()))
|
||||||
|
|
||||||
@skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
|
@skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
|
||||||
@not_remote_testsuite_ready
|
@not_remote_testsuite_ready
|
||||||
|
@ -83,12 +120,13 @@ class LoadUnloadTestCase(TestBase):
|
||||||
substrs = [new_dylib])
|
substrs = [new_dylib])
|
||||||
|
|
||||||
@skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
|
@skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
|
||||||
@not_remote_testsuite_ready
|
@skipUnlessListedRemote(['android'])
|
||||||
def test_dyld_library_path(self):
|
def test_dyld_library_path(self):
|
||||||
"""Test (DY)LD_LIBRARY_PATH after moving libd.dylib, which defines d_function, somewhere else."""
|
"""Test (DY)LD_LIBRARY_PATH after moving libd.dylib, which defines d_function, somewhere else."""
|
||||||
|
|
||||||
# Invoke the default build rule.
|
# Invoke the default build rule.
|
||||||
self.buildDefault()
|
self.buildDefault()
|
||||||
|
self.copy_shlibs_to_remote(hidden_dir=True)
|
||||||
|
|
||||||
exe = os.path.join(os.getcwd(), "a.out")
|
exe = os.path.join(os.getcwd(), "a.out")
|
||||||
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
|
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
|
||||||
|
@ -101,53 +139,49 @@ class LoadUnloadTestCase(TestBase):
|
||||||
|
|
||||||
# The directory to relocate the dynamic library and its debugging info.
|
# The directory to relocate the dynamic library and its debugging info.
|
||||||
special_dir = "hidden"
|
special_dir = "hidden"
|
||||||
new_dir = os.path.join(os.getcwd(), special_dir)
|
if lldb.remote_platform:
|
||||||
|
wd = lldb.remote_platform.GetWorkingDirectory()
|
||||||
|
else:
|
||||||
|
wd = os.getcwd()
|
||||||
|
|
||||||
old_dylib = os.path.join(os.getcwd(), dylibName)
|
old_dir = wd
|
||||||
new_dylib = os.path.join(new_dir, dylibName)
|
new_dir = os.path.join(wd, special_dir)
|
||||||
|
old_dylib = os.path.join(old_dir, dylibName)
|
||||||
#system(["ls", "-lR", "."])
|
|
||||||
|
|
||||||
# Try running with the (DY)LD_LIBRARY_PATH environment variable set, make sure
|
|
||||||
# we pick up the hidden dylib.
|
|
||||||
|
|
||||||
env_cmd_string = "settings set target.env-vars " + self.dylibPath + "=" + new_dir
|
|
||||||
if not self.platformIsDarwin():
|
|
||||||
env_cmd_string += ":" + os.getcwd()
|
|
||||||
|
|
||||||
if self.TraceOn():
|
|
||||||
print "Set environment to: ", env_cmd_string
|
|
||||||
self.runCmd(env_cmd_string)
|
|
||||||
self.runCmd("settings show target.env-vars")
|
|
||||||
|
|
||||||
remove_dyld_path_cmd = "settings remove target.env-vars " + self.dylibPath
|
remove_dyld_path_cmd = "settings remove target.env-vars " + self.dylibPath
|
||||||
self.addTearDownHook(lambda: self.dbg.HandleCommand(remove_dyld_path_cmd))
|
self.addTearDownHook(lambda: self.dbg.HandleCommand(remove_dyld_path_cmd))
|
||||||
|
|
||||||
lldbutil.run_break_set_by_file_and_line (self, "d.c", self.line_d_function, num_expected_locations=1, loc_exact=True)
|
|
||||||
|
|
||||||
# For now we don't track (DY)LD_LIBRARY_PATH, so the old library will be in
|
# For now we don't track (DY)LD_LIBRARY_PATH, so the old library will be in
|
||||||
# the modules list.
|
# the modules list.
|
||||||
self.expect("target modules list",
|
self.expect("target modules list",
|
||||||
substrs = [os.path.basename(old_dylib)],
|
substrs = [os.path.basename(old_dylib)],
|
||||||
matching=True)
|
matching=True)
|
||||||
|
|
||||||
self.runCmd("run")
|
lldbutil.run_break_set_by_file_and_line (self, "d.c", self.line_d_function, num_expected_locations=1)
|
||||||
self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
|
# After run, make sure the non-hidden library is picked up.
|
||||||
patterns = ["frame #0.*d_function.*at d.c:%d" % self.line_d_function])
|
self.expect("run", substrs=["return", "700"])
|
||||||
|
|
||||||
# After run, make sure the hidden library is present, and the one we didn't
|
self.runCmd("continue")
|
||||||
# load is not.
|
|
||||||
self.expect("target modules list",
|
# Add the hidden directory first in the search path.
|
||||||
substrs = [special_dir, os.path.basename(new_dylib)])
|
env_cmd_string = ("settings set target.env-vars %s=%s" %
|
||||||
|
(self.dylibPath, new_dir))
|
||||||
|
if not self.platformIsDarwin():
|
||||||
|
env_cmd_string += ":" + wd
|
||||||
|
self.runCmd(env_cmd_string)
|
||||||
|
|
||||||
|
# This time, the hidden library should be picked up.
|
||||||
|
self.expect("run", substrs=["return", "12345"])
|
||||||
|
|
||||||
@skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
|
@skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
|
||||||
@not_remote_testsuite_ready
|
@skipUnlessListedRemote(['android'])
|
||||||
@unittest2.expectedFailure("rdar://15367406")
|
@unittest2.expectedFailure("rdar://15367406")
|
||||||
def test_lldb_process_load_and_unload_commands(self):
|
def test_lldb_process_load_and_unload_commands(self):
|
||||||
"""Test that lldb process load/unload command work correctly."""
|
"""Test that lldb process load/unload command work correctly."""
|
||||||
|
|
||||||
# Invoke the default build rule.
|
# Invoke the default build rule.
|
||||||
self.buildDefault()
|
self.buildDefault()
|
||||||
|
self.copy_shlibs_to_remote()
|
||||||
|
|
||||||
exe = os.path.join(os.getcwd(), "a.out")
|
exe = os.path.join(os.getcwd(), "a.out")
|
||||||
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
|
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
|
||||||
|
@ -159,12 +193,18 @@ class LoadUnloadTestCase(TestBase):
|
||||||
|
|
||||||
self.runCmd("run", RUN_FAILED)
|
self.runCmd("run", RUN_FAILED)
|
||||||
|
|
||||||
|
if lldb.remote_platform:
|
||||||
|
shlib_dir = lldb.remote_platform.GetWorkingDirectory()
|
||||||
|
else:
|
||||||
|
shlib_dir = self.mydir
|
||||||
# Make sure that a_function does not exist at this point.
|
# Make sure that a_function does not exist at this point.
|
||||||
self.expect("image lookup -n a_function", "a_function should not exist yet",
|
self.expect("image lookup -n a_function", "a_function should not exist yet",
|
||||||
error=True, matching=False,
|
error=True, matching=False,
|
||||||
patterns = ["1 match found .* %s" % self.mydir])
|
patterns = ["1 match found .* %s" % shlib_dir])
|
||||||
|
|
||||||
if self.platformIsDarwin():
|
if lldb.remote_platform:
|
||||||
|
dylibName = os.path.join(shlib_dir, 'libloadunload_a.so')
|
||||||
|
elif self.platformIsDarwin():
|
||||||
dylibName = 'libloadunload_a.dylib'
|
dylibName = 'libloadunload_a.dylib'
|
||||||
else:
|
else:
|
||||||
dylibName = 'libloadunload_a.so'
|
dylibName = 'libloadunload_a.so'
|
||||||
|
@ -186,7 +226,7 @@ class LoadUnloadTestCase(TestBase):
|
||||||
|
|
||||||
# Now we should have an entry for a_function.
|
# Now we should have an entry for a_function.
|
||||||
self.expect("image lookup -n a_function", "a_function should now exist",
|
self.expect("image lookup -n a_function", "a_function should now exist",
|
||||||
patterns = ["1 match found .*%s" % self.mydir])
|
patterns = ["1 match found .*%s" % shlib_dir])
|
||||||
|
|
||||||
# Use lldb 'process unload' to unload the dylib.
|
# Use lldb 'process unload' to unload the dylib.
|
||||||
self.expect("process unload %s" % index, "%s unloaded correctly" % dylibName,
|
self.expect("process unload %s" % index, "%s unloaded correctly" % dylibName,
|
||||||
|
@ -195,12 +235,13 @@ class LoadUnloadTestCase(TestBase):
|
||||||
self.runCmd("process continue")
|
self.runCmd("process continue")
|
||||||
|
|
||||||
@skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
|
@skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
|
||||||
@not_remote_testsuite_ready
|
@skipUnlessListedRemote(['android'])
|
||||||
def test_load_unload(self):
|
def test_load_unload(self):
|
||||||
"""Test breakpoint by name works correctly with dlopen'ing."""
|
"""Test breakpoint by name works correctly with dlopen'ing."""
|
||||||
|
|
||||||
# Invoke the default build rule.
|
# Invoke the default build rule.
|
||||||
self.buildDefault()
|
self.buildDefault()
|
||||||
|
self.copy_shlibs_to_remote()
|
||||||
|
|
||||||
exe = os.path.join(os.getcwd(), "a.out")
|
exe = os.path.join(os.getcwd(), "a.out")
|
||||||
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
|
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
|
||||||
|
@ -236,12 +277,13 @@ class LoadUnloadTestCase(TestBase):
|
||||||
substrs = [' resolved, hit count = 2'])
|
substrs = [' resolved, hit count = 2'])
|
||||||
|
|
||||||
@skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
|
@skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
|
||||||
@not_remote_testsuite_ready
|
@skipUnlessListedRemote(['android'])
|
||||||
def test_step_over_load (self):
|
def test_step_over_load (self):
|
||||||
"""Test stepping over code that loads a shared library works correctly."""
|
"""Test stepping over code that loads a shared library works correctly."""
|
||||||
|
|
||||||
# Invoke the default build rule.
|
# Invoke the default build rule.
|
||||||
self.buildDefault()
|
self.buildDefault()
|
||||||
|
self.copy_shlibs_to_remote()
|
||||||
|
|
||||||
exe = os.path.join(os.getcwd(), "a.out")
|
exe = os.path.join(os.getcwd(), "a.out")
|
||||||
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
|
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
|
||||||
|
|
|
@ -8,6 +8,10 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
int
|
int
|
||||||
d_function ()
|
d_function ()
|
||||||
{
|
{ // Find this line number within d_dunction().
|
||||||
return 700; // Find this line number within d_dunction().
|
#ifdef HIDDEN
|
||||||
|
return 12345;
|
||||||
|
#else
|
||||||
|
return 700;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -735,6 +735,28 @@ def skipIfRemote(func):
|
||||||
func(*args, **kwargs)
|
func(*args, **kwargs)
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
def skipUnlessListedRemote(remote_list=None):
|
||||||
|
def myImpl(func):
|
||||||
|
if isinstance(func, type) and issubclass(func, unittest2.TestCase):
|
||||||
|
raise Exception("@skipIfRemote can only be used to decorate a "
|
||||||
|
"test method")
|
||||||
|
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
if remote_list and lldb.remote_platform:
|
||||||
|
self = args[0]
|
||||||
|
triple = self.dbg.GetSelectedPlatform().GetTriple()
|
||||||
|
for r in remote_list:
|
||||||
|
if r in triple:
|
||||||
|
func(*args, **kwargs)
|
||||||
|
return
|
||||||
|
self.skipTest("skip on remote platform %s" % str(triple))
|
||||||
|
else:
|
||||||
|
func(*args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
return myImpl
|
||||||
|
|
||||||
def skipIfRemoteDueToDeadlock(func):
|
def skipIfRemoteDueToDeadlock(func):
|
||||||
"""Decorate the item to skip tests if testing remotely due to the test deadlocking."""
|
"""Decorate the item to skip tests if testing remotely due to the test deadlocking."""
|
||||||
if isinstance(func, type) and issubclass(func, unittest2.TestCase):
|
if isinstance(func, type) and issubclass(func, unittest2.TestCase):
|
||||||
|
|
Loading…
Reference in New Issue