Skip to content

Commit

Permalink
Added GetRunfilesFile() to be able to reliably determine prelude loca…
Browse files Browse the repository at this point in the history
…tion under various invocation scenarios

The logic is using bazel Runfiles API per Jon's suggestion.

One of the scenarios used by the fuzzing framework is to place the binary and its runfiles into a folder, resulting in a directory layout like this:

[temp dir]
fuzzer
fuzzer.runfiles/

Tested:
bazel test -c opt explorer/fuzzing:explorer_fuzzer
bazel build -c opt explorer/fuzzing:explorer_fuzzer + run the binary from various locations
  • Loading branch information
pk19604014 authored May 2, 2022
1 parent 309ec35 commit 150057f
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 1 deletion.
2 changes: 2 additions & 0 deletions explorer/fuzzing/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ cc_library(
hdrs = ["fuzzer_util.h"],
deps = [
"//common:check",
"//common:error",
"//common/fuzzing:carbon_cc_proto",
"//common/fuzzing:proto_to_carbon_lib",
"//explorer/interpreter:exec_program",
"//explorer/syntax",
"//explorer/syntax:prelude",
"@bazel_tools//tools/cpp/runfiles",
"@com_google_protobuf//:protobuf_headers",
"@llvm-project//llvm:Support",
],
Expand Down
25 changes: 24 additions & 1 deletion explorer/fuzzing/fuzzer_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
#include "explorer/interpreter/exec_program.h"
#include "explorer/syntax/parse.h"
#include "explorer/syntax/prelude.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "tools/cpp/runfiles/runfiles.h"

namespace Carbon {

Expand All @@ -21,6 +24,23 @@ fn Main() -> i32 {
}
)";

auto Internal::GetRunfilesFile(const std::string& file)
-> ErrorOr<std::string> {
using bazel::tools::cpp::runfiles::Runfiles;
std::string error;
// `Runfiles::Create()` fails if passed an empty `argv0`.
std::unique_ptr<Runfiles> runfiles(Runfiles::Create(
/*argv0=*/llvm::sys::fs::getMainExecutable(nullptr, nullptr), &error));
if (runfiles == nullptr) {
return Error(error);
}
std::string full_path = runfiles->Rlocation(file);
if (!llvm::sys::fs::exists(full_path)) {
return ErrorBuilder() << full_path << " doesn't exist";
}
return full_path;
}

auto ProtoToCarbonWithMain(const Fuzzing::CompilationUnit& compilation_unit)
-> std::string {
const bool has_main = std::any_of(
Expand All @@ -43,7 +63,10 @@ void ParseAndExecute(const Fuzzing::CompilationUnit& compilation_unit) {
llvm::errs() << "Parsing failed: " << ast.error().message() << "\n";
return;
}
AddPrelude("explorer/data/prelude.carbon", &arena, &ast->declarations);
const ErrorOr<std::string> prelude_path =
Internal::GetRunfilesFile("carbon/explorer/data/prelude.carbon");
CHECK(prelude_path.ok()) << prelude_path.error().message();
AddPrelude(*prelude_path, &arena, &ast->declarations);
const ErrorOr<int> result =
ExecProgram(&arena, *ast, /*trace_stream=*/std::nullopt);
if (!result.ok()) {
Expand Down
8 changes: 8 additions & 0 deletions explorer/fuzzing/fuzzer_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef EXPLORER_FUZZING_FUZZER_UTIL_H_
#define EXPLORER_FUZZING_FUZZER_UTIL_H_

#include "common/error.h"
#include "common/fuzzing/carbon.pb.h"

namespace Carbon {
Expand All @@ -17,6 +18,13 @@ auto ProtoToCarbonWithMain(const Fuzzing::CompilationUnit& compilation_unit)
// Parses and executes a fuzzer-generated program.
void ParseAndExecute(const Fuzzing::CompilationUnit& compilation_unit);

namespace Internal {

// Returns a full path for a file under bazel runfiles.
// Exposed for testing.
auto GetRunfilesFile(const std::string& file) -> ErrorOr<std::string>;

} // namespace Internal
} // namespace Carbon

#endif // EXPLORER_FUZZING_FUZZER_UTIL_H_
13 changes: 13 additions & 0 deletions explorer/fuzzing/fuzzer_util_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,19 @@ TEST(FuzzerUtilTest, RunFuzzerOnCorpus) {
EXPECT_GT(file_count, 0);
}

TEST(FuzzerUtilTest, GetRunfilesFile) {
EXPECT_THAT(*Internal::GetRunfilesFile(
"carbon/explorer/fuzzing/fuzzer_corpus/empty.textproto"),
testing::EndsWith("/explorer/fuzzing/fuzzer_corpus/"
"empty.textproto"));
EXPECT_THAT(Internal::GetRunfilesFile(
"explorer/fuzzing/fuzzer_corpus/empty.textproto")
.error()
.message(),
testing::EndsWith("fuzzer_util_test.runfiles/explorer/fuzzing/"
"fuzzer_corpus/empty.textproto doesn't exist"));
}

} // namespace
} // namespace Carbon::Testing

Expand Down
3 changes: 3 additions & 0 deletions scripts/fix_cc_deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
"@com_google_libprotobuf_mutator": lambda x: re.sub(
"^(.*:)", "libprotobuf_mutator/", x
),
# @bazel_tools//tools/cpp/runfiles:runfiles.h ->
# tools/cpp/runfiles/runfiles.h
"@bazel_tools": lambda x: re.sub(":", "/", x),
}

# TODO: proto rules are aspect-based and their generated files don't show up in
Expand Down

0 comments on commit 150057f

Please sign in to comment.