ソースを参照

Added a patch with a fuzzer Bazel BUILD file and updated fuzz_test rule to use the new @llvm-project//compiler-rt:FuzzerMain

Fixes #1208 (_LIBCPP_DEBUG crash)

Fully bazel-ifying compiler-rt is more complex than I originally thought, due to dependencies on other llvm projects like libcxx which currently also don't have bazel build support -- https://github.com/carbon-language/carbon-lang/issues/1208#issuecomment-1171555971
pk19604014 3 年 前
コミット
9f90fa3633

+ 2 - 1
WORKSPACE

@@ -92,7 +92,8 @@ http_archive(
     name = "llvm-raw",
     name = "llvm-raw",
     build_file_content = "# empty",
     build_file_content = "# empty",
     patch_args = ["-p1"],
     patch_args = ["-p1"],
-    patches = ["@//:bazel/llvm-patches/0001-Patch-for-mallinfo2-when-using-Bazel-build-system.patch"],
+    patches = ["@//:bazel/llvm-patches/0001-Patch-for-mallinfo2-when-using-Bazel-build-system.patch",
+               "@//:bazel/llvm-patches/0002-Added-Bazel-build-for-compiler-rt-fuzzer.patch"],
     sha256 = "0a3929c5f2fe756820277be7b10e95f7480e7cb7f297ec574d3e9ddeac9068d7",
     sha256 = "0a3929c5f2fe756820277be7b10e95f7480e7cb7f297ec574d3e9ddeac9068d7",
     strip_prefix = "llvm-project-%s" % llvm_version,
     strip_prefix = "llvm-project-%s" % llvm_version,
     urls = ["https://github.com/llvm/llvm-project/archive/%s.tar.gz" % llvm_version],
     urls = ["https://github.com/llvm/llvm-project/archive/%s.tar.gz" % llvm_version],

+ 3 - 12
bazel/cc_toolchains/clang_cc_toolchain_config.bzl

@@ -487,7 +487,7 @@ def _impl(ctx):
         flag_sets = [flag_set(
         flag_sets = [flag_set(
             actions = all_compile_actions + all_link_actions,
             actions = all_compile_actions + all_link_actions,
             flag_groups = [flag_group(flags = [
             flag_groups = [flag_group(flags = [
-                "-fsanitize=fuzzer",
+                "-fsanitize=fuzzer-no-link",
             ])],
             ])],
         )],
         )],
     )
     )
@@ -496,11 +496,7 @@ def _impl(ctx):
         name = "proto-fuzzer",
         name = "proto-fuzzer",
         enabled = False,
         enabled = False,
         requires = [feature_set(["nonhost"])],
         requires = [feature_set(["nonhost"])],
-
-        # TODO: this should really be `fuzzer`, but `-fsanitize=fuzzer` triggers
-        # a clang crash when running `bazel test --config=fuzzer ...`. See
-        # https://github.com/carbon-language/carbon-lang/issues/1173
-        implies = ["asan"],
+        implies = ["fuzzer"],
     )
     )
 
 
     linux_flags_feature = feature(
     linux_flags_feature = feature(
@@ -549,12 +545,7 @@ def _impl(ctx):
                     "-D_LIBCPP_DEBUG=1",
                     "-D_LIBCPP_DEBUG=1",
                 ])],
                 ])],
                 with_features = [
                 with_features = [
-                    # _LIBCPP_DEBUG=1 causes protobuf code to crash when linked
-                    # with `-fsanitize=fuzzer`, possibly because of ODR
-                    # violations caused by Carbon source and pre-compiled llvm
-                    # Fuzzer driver library built with different _LIBCPP_DEBUG
-                    # values.
-                    with_feature_set(not_features = ["opt", "proto-fuzzer"]),
+                    with_feature_set(not_features = ["opt"]),
                 ],
                 ],
             ),
             ),
         ],
         ],

+ 6 - 0
bazel/fuzzing/rules.bzl

@@ -13,6 +13,7 @@ def cc_fuzz_test(
         data = [],
         data = [],
         features = [],
         features = [],
         tags = [],
         tags = [],
+        deps = [],
         **kwargs):
         **kwargs):
     """Macro for C++ fuzzing test.
     """Macro for C++ fuzzing test.
 
 
@@ -28,6 +29,8 @@ def cc_fuzz_test(
         features: Will have the "fuzzer" feature added and passed down to the
         features: Will have the "fuzzer" feature added and passed down to the
             fuzz test.
             fuzz test.
         tags: Will have "fuzz_test" added and passed down to the fuzz test.
         tags: Will have "fuzz_test" added and passed down to the fuzz test.
+        deps: Will have "@llvm-project//compiler-rt:FuzzerMain" added and passed
+            down to the fuzz test.
         **kwargs: Remaining arguments passed down to the fuzz test.
         **kwargs: Remaining arguments passed down to the fuzz test.
     """
     """
 
 
@@ -36,6 +39,8 @@ def cc_fuzz_test(
         tags = tags + ["fuzz_test"]
         tags = tags + ["fuzz_test"]
     if "fuzzer" not in features:
     if "fuzzer" not in features:
         features = features + ["fuzzer"]
         features = features + ["fuzzer"]
+    if "@llvm-project//compiler-rt:FuzzerMain" not in deps:
+      deps = deps + ["@llvm-project//compiler-rt:FuzzerMain"]
 
 
     # Append the corpus files to the test arguments. When run on a list of
     # Append the corpus files to the test arguments. When run on a list of
     # files rather than a directory, libFuzzer-based fuzzers will perform a
     # files rather than a directory, libFuzzer-based fuzzers will perform a
@@ -49,5 +54,6 @@ def cc_fuzz_test(
         data = data,
         data = data,
         features = features,
         features = features,
         tags = tags,
         tags = tags,
+        deps = deps,
         **kwargs
         **kwargs
     )
     )

+ 36 - 0
bazel/llvm-patches/0002-Added-Bazel-build-for-compiler-rt-fuzzer.patch

@@ -0,0 +1,36 @@
+From 2c9527d988d2f5935b9406511104819463c37662 Mon Sep 17 00:00:00 2001
+From: P K <pk19604014@gmail.com>
+Date: Mon, 11 Jul 2022 17:32:57 -0400
+Subject: [PATCH] Added Bazel build for compiler-rt/fuzzer
+
+---
+ .../compiler-rt/BUILD.bazel                    | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+ create mode 100644 compiler-rt/BUILD.bazel
+
+diff --git a/compiler-rt/BUILD.bazel b/compiler-rt/BUILD.bazel
+new file mode 100644
+index 000000000000..c6796b24a8e1
+--- /dev/null
++++ b/compiler-rt/BUILD.bazel
+@@ -0,0 +1,18 @@
++package(default_visibility = ["//visibility:public"])
++
++cc_library(
++    name = "FuzzerMain",
++    srcs = glob(
++        ["lib/fuzzer/Fuzzer*.cpp"],
++    ),
++    hdrs = glob([
++        "lib/fuzzer/Fuzzer*.h",
++        "lib/fuzzer/Fuzzer*.def",
++    ]),
++    copts = [
++      # Not using no-sanitize=address per https://github.com/google/sanitizers/wiki/AddressSanitizerContainerOverflow#false-positives
++      "-fno-sanitize=memory,thread,undefined",
++      "-fsanitize-coverage=0",
++    ],
++    includes = ["lib/fuzzer"],
++)
+--
+2.37.0.144.g8ac04bfd2-goog

+ 2 - 3
explorer/fuzzing/BUILD

@@ -118,12 +118,11 @@ cc_test(
     ],
     ],
 )
 )
 
 
-# Needs `--config=proto-fuzzer` for `bazel build`.
-cc_binary(
+cc_fuzz_test(
     name = "explorer_fuzzer",
     name = "explorer_fuzzer",
     testonly = 1,
     testonly = 1,
     srcs = ["explorer_fuzzer.cpp"],
     srcs = ["explorer_fuzzer.cpp"],
-    features = ["fuzzer"],
+    corpus = glob(["fuzzer_corpus/*"]),
     deps = [
     deps = [
         ":fuzzer_util",
         ":fuzzer_util",
         "@com_google_libprotobuf_mutator//:libprotobuf_mutator",
         "@com_google_libprotobuf_mutator//:libprotobuf_mutator",