Currently a FileSpecList::FindFileIndex(...) will only match the specified FileSpec if: - it has filename and directory and both match exactly - if has a filename only and any filename in the list matches Because of this, we modify our breakpoint resolving so it can handle relative paths by doing some extra code that removes the directory from the FileSpec when searching if the path is relative. This patch is intended to fix breakpoints so they work as users expect them to by adding the following features: - allow matches to relative paths in the file list to match as long as the relative path is at the end of the specified path at valid directory delimiters - allow matches to paths to match if the specified path is relative and shorter than the file paths in the list This allows us to remove the extra logic from BreakpointResolverFileLine.cpp that added support for setting breakpoints with relative paths. This means we can still set breakpoints with relative paths when the debug info contains full paths. We add the ability to set breakpoints with full paths when the debug info contains relative paths. Debug info contains "./a/b/c/main.cpp", the following will set breakpoints successfully: - /build/a/b/c/main.cpp - a/b/c/main.cpp - b/c/main.cpp - c/main.cpp - main.cpp - ./c/main.cpp - ./a/b/c/main.cpp - ./b/c/main.cpp - ./main.cpp This also ensures that we won't match partial directory names, if a relative path is in the list or is used for the match, things must match at the directory level. The breakpoint resolving code will now use the new FileSpecList::FindCompatibleIndex(...) function to allow this fuzzy matching to work for breakpoints. Differential Revision: https://reviews.llvm.org/D130401
126 lines
5.5 KiB
C++
126 lines
5.5 KiB
C++
//===-- FileSpecListTest.cpp ----------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
#include "lldb/Core/FileSpecList.h"
|
|
|
|
using namespace lldb_private;
|
|
|
|
static FileSpec PosixSpec(llvm::StringRef path) {
|
|
return FileSpec(path, FileSpec::Style::posix);
|
|
}
|
|
|
|
static FileSpec WindowsSpec(llvm::StringRef path) {
|
|
return FileSpec(path, FileSpec::Style::windows);
|
|
}
|
|
|
|
TEST(FileSpecListTest, RelativePathMatchesPosix) {
|
|
|
|
const FileSpec fullpath = PosixSpec("/build/src/main.cpp");
|
|
const FileSpec relative = PosixSpec("./src/main.cpp");
|
|
const FileSpec basename = PosixSpec("./main.cpp");
|
|
const FileSpec full_wrong = PosixSpec("/other/wrong/main.cpp");
|
|
const FileSpec rel_wrong = PosixSpec("./wrong/main.cpp");
|
|
// Make sure these don't match "src/main.cpp" as we want to match full
|
|
// directories only
|
|
const FileSpec rel2_wrong = PosixSpec("asrc/main.cpp");
|
|
const FileSpec rel3_wrong = PosixSpec("rc/main.cpp");
|
|
|
|
FileSpecList files;
|
|
files.Append(fullpath);
|
|
files.Append(relative);
|
|
files.Append(basename);
|
|
files.Append(full_wrong);
|
|
files.Append(rel_wrong);
|
|
files.Append(rel2_wrong);
|
|
files.Append(rel3_wrong);
|
|
|
|
// Make sure the full path only matches the first entry
|
|
EXPECT_EQ((size_t)0, files.FindCompatibleIndex(0, fullpath));
|
|
EXPECT_EQ((size_t)1, files.FindCompatibleIndex(1, fullpath));
|
|
EXPECT_EQ((size_t)2, files.FindCompatibleIndex(2, fullpath));
|
|
EXPECT_EQ((size_t)UINT32_MAX, files.FindCompatibleIndex(3, fullpath));
|
|
// Make sure the relative path matches the all of the entries that contain
|
|
// the relative path
|
|
EXPECT_EQ((size_t)0, files.FindCompatibleIndex(0, relative));
|
|
EXPECT_EQ((size_t)1, files.FindCompatibleIndex(1, relative));
|
|
EXPECT_EQ((size_t)2, files.FindCompatibleIndex(2, relative));
|
|
EXPECT_EQ((size_t)UINT32_MAX, files.FindCompatibleIndex(3, relative));
|
|
|
|
// Make sure looking file a file using the basename matches all entries
|
|
EXPECT_EQ((size_t)0, files.FindCompatibleIndex(0, basename));
|
|
EXPECT_EQ((size_t)1, files.FindCompatibleIndex(1, basename));
|
|
EXPECT_EQ((size_t)2, files.FindCompatibleIndex(2, basename));
|
|
EXPECT_EQ((size_t)3, files.FindCompatibleIndex(3, basename));
|
|
EXPECT_EQ((size_t)4, files.FindCompatibleIndex(4, basename));
|
|
EXPECT_EQ((size_t)5, files.FindCompatibleIndex(5, basename));
|
|
EXPECT_EQ((size_t)6, files.FindCompatibleIndex(6, basename));
|
|
|
|
// Make sure that paths that have a common suffix don't return values that
|
|
// don't match on directory delimiters.
|
|
EXPECT_EQ((size_t)2, files.FindCompatibleIndex(0, rel2_wrong));
|
|
EXPECT_EQ((size_t)5, files.FindCompatibleIndex(3, rel2_wrong));
|
|
EXPECT_EQ((size_t)UINT32_MAX, files.FindCompatibleIndex(6, rel2_wrong));
|
|
|
|
EXPECT_EQ((size_t)2, files.FindCompatibleIndex(0, rel3_wrong));
|
|
EXPECT_EQ((size_t)6, files.FindCompatibleIndex(3, rel3_wrong));
|
|
}
|
|
|
|
TEST(FileSpecListTest, RelativePathMatchesWindows) {
|
|
|
|
const FileSpec fullpath = WindowsSpec(R"(C:\build\src\main.cpp)");
|
|
const FileSpec relative = WindowsSpec(R"(.\src\main.cpp)");
|
|
const FileSpec basename = WindowsSpec(R"(.\main.cpp)");
|
|
const FileSpec full_wrong = WindowsSpec(R"(\other\wrong\main.cpp)");
|
|
const FileSpec rel_wrong = WindowsSpec(R"(.\wrong\main.cpp)");
|
|
// Make sure these don't match "src\main.cpp" as we want to match full
|
|
// directories only
|
|
const FileSpec rel2_wrong = WindowsSpec(R"(asrc\main.cpp)");
|
|
const FileSpec rel3_wrong = WindowsSpec(R"("rc\main.cpp)");
|
|
|
|
FileSpecList files;
|
|
files.Append(fullpath);
|
|
files.Append(relative);
|
|
files.Append(basename);
|
|
files.Append(full_wrong);
|
|
files.Append(rel_wrong);
|
|
files.Append(rel2_wrong);
|
|
files.Append(rel3_wrong);
|
|
|
|
// Make sure the full path only matches the first entry
|
|
EXPECT_EQ((size_t)0, files.FindCompatibleIndex(0, fullpath));
|
|
EXPECT_EQ((size_t)1, files.FindCompatibleIndex(1, fullpath));
|
|
EXPECT_EQ((size_t)2, files.FindCompatibleIndex(2, fullpath));
|
|
EXPECT_EQ((size_t)UINT32_MAX, files.FindCompatibleIndex(3, fullpath));
|
|
// Make sure the relative path matches the all of the entries that contain
|
|
// the relative path
|
|
EXPECT_EQ((size_t)0, files.FindCompatibleIndex(0, relative));
|
|
EXPECT_EQ((size_t)1, files.FindCompatibleIndex(1, relative));
|
|
EXPECT_EQ((size_t)2, files.FindCompatibleIndex(2, relative));
|
|
EXPECT_EQ((size_t)UINT32_MAX, files.FindCompatibleIndex(3, relative));
|
|
|
|
// Make sure looking file a file using the basename matches all entries
|
|
EXPECT_EQ((size_t)0, files.FindCompatibleIndex(0, basename));
|
|
EXPECT_EQ((size_t)1, files.FindCompatibleIndex(1, basename));
|
|
EXPECT_EQ((size_t)2, files.FindCompatibleIndex(2, basename));
|
|
EXPECT_EQ((size_t)3, files.FindCompatibleIndex(3, basename));
|
|
EXPECT_EQ((size_t)4, files.FindCompatibleIndex(4, basename));
|
|
EXPECT_EQ((size_t)5, files.FindCompatibleIndex(5, basename));
|
|
EXPECT_EQ((size_t)6, files.FindCompatibleIndex(6, basename));
|
|
|
|
// Make sure that paths that have a common suffix don't return values that
|
|
// don't match on directory delimiters.
|
|
EXPECT_EQ((size_t)2, files.FindCompatibleIndex(0, rel2_wrong));
|
|
EXPECT_EQ((size_t)5, files.FindCompatibleIndex(3, rel2_wrong));
|
|
EXPECT_EQ((size_t)UINT32_MAX, files.FindCompatibleIndex(6, rel2_wrong));
|
|
|
|
EXPECT_EQ((size_t)2, files.FindCompatibleIndex(0, rel3_wrong));
|
|
EXPECT_EQ((size_t)6, files.FindCompatibleIndex(3, rel3_wrong));
|
|
}
|