Build fuzzer tests in standalone builds too.

This will avoid compilation to break, and adds standalone reproducers
for the fuzzer_tests.

BUG=chromium:903380
BUG=dawn:34

Change-Id: I9995a852076d9f6d1ebdee5b999989c2d74d4709
Reviewed-on: https://dawn-review.googlesource.com/c/2321
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: Dan Sinclair <dsinclair@google.com>
This commit is contained in:
Corentin Wallez 2018-11-12 18:09:56 +00:00 committed by Commit Bot service account
parent 45ee4c88c4
commit 597e1587b4
3 changed files with 223 additions and 98 deletions

109
BUILD.gn
View File

@ -17,9 +17,6 @@ import("scripts/dawn_features.gni")
import("//build_overrides/build.gni")
import("//testing/test.gni")
if (build_with_chromium) {
import("//testing/libfuzzer/fuzzer_test.gni")
}
###############################################################################
# Template to wrap the Dawn code generator
@ -948,100 +945,16 @@ if (dawn_standalone) {
###############################################################################
# Fuzzers
###############################################################################
if (build_with_chromium) {
group("dawn_fuzzers") {
testonly = true
deps = [
":dawn_spirv_cross_glsl_fast_fuzzer",
":dawn_spirv_cross_glsl_full_fuzzer",
":dawn_spirv_cross_hlsl_fast_fuzzer",
":dawn_spirv_cross_hlsl_full_fuzzer",
":dawn_spirv_cross_msl_fast_fuzzer",
":dawn_spirv_cross_msl_full_fuzzer",
]
}
static_library("dawn_spirv_cross_fuzzer_common") {
sources = [
"src/fuzzers/DawnSPIRVCrossFuzzer.cpp",
"src/fuzzers/DawnSPIRVCrossFuzzer.h",
]
public_deps = [
"third_party:spirv_cross",
]
}
# Uses Dawn specific options and varies input data
fuzzer_test("dawn_spirv_cross_glsl_fast_fuzzer") {
sources = [
"src/fuzzers/DawnSPIRVCrossGLSLFastFuzzer.cpp",
]
deps = [
":dawn_spirv_cross_fuzzer_common",
]
}
# Varies bother the options and input data
fuzzer_test("dawn_spirv_cross_glsl_full_fuzzer") {
sources = [
"src/fuzzers/DawnSPIRVCrossGLSLFullFuzzer.cpp",
]
deps = [
":dawn_spirv_cross_fuzzer_common",
]
}
# Uses Dawn specific options and varies input data
fuzzer_test("dawn_spirv_cross_hlsl_fast_fuzzer") {
sources = [
"src/fuzzers/DawnSPIRVCrossGLSLFastFuzzer.cpp",
]
deps = [
":dawn_spirv_cross_fuzzer_common",
]
}
# Varies bother the options and input data
fuzzer_test("dawn_spirv_cross_hlsl_full_fuzzer") {
sources = [
"src/fuzzers/DawnSPIRVCrossGLSLFullFuzzer.cpp",
]
deps = [
":dawn_spirv_cross_fuzzer_common",
]
}
# Uses Dawn specific options and varies input data
fuzzer_test("dawn_spirv_cross_msl_fast_fuzzer") {
sources = [
"src/fuzzers/DawnSPIRVCrossGLSLFastFuzzer.cpp",
]
deps = [
":dawn_spirv_cross_fuzzer_common",
]
}
# Varies bother the options and input data
fuzzer_test("dawn_spirv_cross_msl_full_fuzzer") {
sources = [
"src/fuzzers/DawnSPIRVCrossGLSLFullFuzzer.cpp",
]
deps = [
":dawn_spirv_cross_fuzzer_common",
]
}
fuzzer_test("dawn_wire_server_and_frontend_fuzzer") {
sources = [
"src/fuzzers/DawnWireServerAndFrontendFuzzer.cpp",
]
deps = [
":libdawn",
":libdawn_native",
":libdawn_wire",
]
additional_configs = [ ":dawn_shared_library_public" ]
}
group("dawn_fuzzers") {
testonly = true
deps = [
"src/fuzzers:dawn_spirv_cross_glsl_fast_fuzzer",
"src/fuzzers:dawn_spirv_cross_glsl_full_fuzzer",
"src/fuzzers:dawn_spirv_cross_hlsl_fast_fuzzer",
"src/fuzzers:dawn_spirv_cross_hlsl_full_fuzzer",
"src/fuzzers:dawn_spirv_cross_msl_fast_fuzzer",
"src/fuzzers:dawn_spirv_cross_msl_full_fuzzer",
"src/fuzzers:dawn_wire_server_and_frontend_fuzzer",
]
}

150
src/fuzzers/BUILD.gn Normal file
View File

@ -0,0 +1,150 @@
# Copyright 2018 The Dawn Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build_overrides/build.gni")
dawn_top_level = "../.."
# We only have libfuzzer in Chromium builds but if we build fuzzer targets only
# there, we would risk breaking fuzzer targets all the time when making changes
# to Dawn. To avoid that, we make fuzzer targets compile in standalone builds
# as well with a dawn_fuzzer_test target that acts like Chromium's fuzzer_test.
#
# The standalone fuzzer targets are able to run a single fuzzer input which
# could help reproduce fuzzer crashes more easily because you don't need a
# whole Chromium checkout.
if (build_with_chromium) {
import("//testing/libfuzzer/fuzzer_test.gni")
# In Chromium build we just proxy everything to the real fuzzer_test
template("dawn_fuzzer_test") {
fuzzer_test(target_name) {
forward_variables_from(invoker, "*")
}
}
} else {
import("//testing/test.gni")
# In standalone build we do something similar to fuzzer_test.
template("dawn_fuzzer_test") {
test(target_name) {
forward_variables_from(invoker,
[
"cflags",
"cflags_cc",
"check_includes",
"defines",
"deps",
"include_dirs",
"sources",
])
if (!defined(configs)) {
configs = []
}
# Weirdly fuzzer_test uses a special variable for additional configs.
if (defined(invoker.additional_configs)) {
configs += invoker.additional_configs
}
sources += [ "StandaloneFuzzerMain.cpp" ]
}
}
}
static_library("dawn_spirv_cross_fuzzer_common") {
sources = [
"DawnSPIRVCrossFuzzer.cpp",
"DawnSPIRVCrossFuzzer.h",
]
public_deps = [
"${dawn_top_level}/third_party:spirv_cross",
]
}
# Uses Dawn specific options and varies input data
dawn_fuzzer_test("dawn_spirv_cross_glsl_fast_fuzzer") {
sources = [
"DawnSPIRVCrossGLSLFastFuzzer.cpp",
]
deps = [
":dawn_spirv_cross_fuzzer_common",
]
}
# Varies bother the options and input data
dawn_fuzzer_test("dawn_spirv_cross_glsl_full_fuzzer") {
sources = [
"DawnSPIRVCrossGLSLFullFuzzer.cpp",
]
deps = [
":dawn_spirv_cross_fuzzer_common",
]
}
# Uses Dawn specific options and varies input data
dawn_fuzzer_test("dawn_spirv_cross_hlsl_fast_fuzzer") {
sources = [
"DawnSPIRVCrossGLSLFastFuzzer.cpp",
]
deps = [
":dawn_spirv_cross_fuzzer_common",
]
}
# Varies bother the options and input data
dawn_fuzzer_test("dawn_spirv_cross_hlsl_full_fuzzer") {
sources = [
"DawnSPIRVCrossGLSLFullFuzzer.cpp",
]
deps = [
":dawn_spirv_cross_fuzzer_common",
]
}
# Uses Dawn specific options and varies input data
dawn_fuzzer_test("dawn_spirv_cross_msl_fast_fuzzer") {
sources = [
"DawnSPIRVCrossGLSLFastFuzzer.cpp",
]
deps = [
":dawn_spirv_cross_fuzzer_common",
]
}
# Varies bother the options and input data
dawn_fuzzer_test("dawn_spirv_cross_msl_full_fuzzer") {
sources = [
"DawnSPIRVCrossGLSLFullFuzzer.cpp",
]
deps = [
":dawn_spirv_cross_fuzzer_common",
]
}
dawn_fuzzer_test("dawn_wire_server_and_frontend_fuzzer") {
sources = [
"DawnWireServerAndFrontendFuzzer.cpp",
]
deps = [
"${dawn_top_level}:libdawn",
"${dawn_top_level}:libdawn_native",
"${dawn_top_level}:libdawn_wire",
]
additional_configs = [ "${dawn_top_level}:dawn_shared_library_public" ]
}

View File

@ -0,0 +1,62 @@
// Copyright 2018 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <vector>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
int main(int argc, char** argv) {
if (argc != 2) {
std::cout << "Usage: <standalone reproducer> [FILE]" << std::endl;
return 1;
}
std::cout << "WARNING: this is just a best-effort reproducer for fuzzer issues in standalone "
<< "Dawn builds. For the real fuzzer, please build inside Chromium." << std::endl;
const char* filename = argv[1];
std::cout << "Reproducing using file: " << filename << std::endl;
std::vector<char> data;
{
FILE* file = fopen(filename, "rb");
if (!file) {
std::cerr << "Failed to open " << filename << std::endl;
return 1;
}
fseek(file, 0, SEEK_END);
long tellFileSize = ftell(file);
if (tellFileSize <= 0) {
std::cerr << "Input file of incorrect size: " << filename << std::endl;
return 1;
}
fseek(file, 0, SEEK_SET);
size_t fileSize = static_cast<size_t>(tellFileSize);
data.resize(fileSize);
size_t bytesRead = fread(data.data(), sizeof(char), fileSize, file);
fclose(file);
if (bytesRead != fileSize) {
std::cerr << "Failed to read " << filename << std::endl;
return 1;
}
}
return LLVMFuzzerTestOneInput(reinterpret_cast<const uint8_t*>(data.data()), data.size());
}