Files
clang-p2996/lldb/test/API/commands/expression/import-std-module/missing-module-sources/TestStdModuleSourcesMissing.py
Raphael Isemann 99b7b41edf [lldb][import-std-module] Do some basic file checks before trying to import a module
Currently when LLDB has enough data in the debug information to import the `std` module,
it will just try to import it. However when debugging libraries where the sources aren't
available anymore, importing the module will generate a confusing diagnostic that
the module couldn't be built.

For the fallback mode (where we retry failed expressions with the loaded module), this
will cause the second expression to fail with a module built error instead of the
actual parsing issue in the user expression.

This patch adds checks that ensures that we at least have any source files in the found
include paths before we try to import the module. This prevents the module from being
loaded in the situation described above which means we don't emit the bogus 'can't
import module' diagnostic and also don't waste any time retrying the expression in the
fallback mode.

For the unit tests I did some refactoring as they now require a VFS with the files in it
and not just the paths. The Python test just builds a binary with a fake C++ module,
then deletes the module before debugging.

Fixes rdar://73264458

Reviewed By: JDevlieghere

Differential Revision: https://reviews.llvm.org/D95096
2021-01-21 12:32:51 +01:00

61 lines
2.6 KiB
Python

"""
Check that missing module source files are correctly handled by LLDB.
"""
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
import os
import shutil
class TestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
# We only emulate a fake libc++ in this test and don't use the real libc++,
# but we still add the libc++ category so that this test is only run in
# test configurations where libc++ is actually supposed to be tested.
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
def test(self):
# The path to our temporary target root that contains the temporary
# module sources.
target_sysroot = self.getBuildArtifact("root")
# Copy the sources to the root.
shutil.copytree(self.getSourcePath("root"), target_sysroot)
# Build the binary with the copied sources.
self.build()
# Delete the copied sources so that they are now unavailable.
shutil.rmtree(target_sysroot)
# Set the sysroot where our dummy libc++ used to exist. Just to make
# sure we don't find some existing headers on the system that could
# XPASS this test.
self.runCmd("platform select --sysroot '" + target_sysroot + "' host")
lldbutil.run_to_source_breakpoint(self,
"// Set break point at this line.",
lldb.SBFileSpec("main.cpp"))
# Import the std C++ module and run an expression.
# As we deleted the sources, LLDB should refuse the load the module
# and just print the normal error we get from the expression.
self.runCmd("settings set target.import-std-module true")
self.expect("expr v.unknown_identifier", error=True,
substrs=["no member named 'unknown_identifier'"])
# Check that there is no confusing error about failing to build the
# module.
self.expect("expr v.unknown_identifier", error=True, matching=False,
substrs=["could not build module 'std'"])
# Test the fallback mode. It should also just print the normal
# error but not mention a failed module build.
self.runCmd("settings set target.import-std-module fallback")
self.expect("expr v.unknown_identifier", error=True,
substrs=["no member named 'unknown_identifier'"])
self.expect("expr v.unknown_identifier", error=True, matching=False,
substrs=["could not build module 'std'"])