Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .github/workflows/win_clang_rel_x64.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,25 @@ jobs:
- name: Regression check capture replay tests
run: |
python test\scripts\regression_check.py ${{ github.workspace }}\..\baseline_capture_replay_tests.json ${{ github.workspace }}\..\test_capture_replay_tests.json

- name: Generate fuzzer for main branch (with patch)
shell: cmd
run: |
set "PATH=%CD%\..\depot_tools;%PATH%"
set "DEPOT_TOOLS_WIN_TOOLCHAIN=0"
cd test
gn gen out\Fuzzer --args="is_debug=false use_libfuzzer=true is_asan=true gpgmm_enable_assert_on_warning=true gpgmm_enable_device_checks=true"

- name: Build fuzzer for main branch (with patch)
shell: cmd
run: |
set "PATH=%CD%\..\depot_tools;%PATH%"
set "DEPOT_TOOLS_WIN_TOOLCHAIN=0"
cd test
ninja -C out\Fuzzer

- name: Run gpgmm_d3d12_resource_allocator_fuzzer (with patch)
shell: cmd
run: |
cd test
out\Fuzzer\gpgmm_d3d12_resource_allocator_fuzzer.exe -max_total_time=120
5 changes: 4 additions & 1 deletion BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ import("build_overrides/gpgmm_overrides_with_defaults.gni")
group("all") {
testonly = true

deps = [ "src/tests:gpgmm_tests" ]
deps = [
"src/fuzzers",
"src/tests:gpgmm_tests",
]

if (gpgmm_enable_dawn) {
deps += [ "//third_party/dawn/src/dawn/tests:dawn_end2end_tests" ]
Expand Down
5 changes: 5 additions & 0 deletions DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ deps = {
'url': '{chromium_git}/external/github.com/open-source-parsers/jsoncpp@9059f5cad030ba11d37818847443a53918c327b1',
'condition': 'gpgmm_standalone',
},
# Fuzzing
'third_party/libFuzzer/src': {
'url': '{chromium_git}/chromium/llvm-project/compiler-rt/lib/fuzzer.git@debe7d2d1982e540fbd6bd78604bf001753f9e74',
'condition': 'gpgmm_standalone',
},
}

hooks = [
Expand Down
19 changes: 16 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,34 @@ Then use `ninja -C out/Release` or `ninja -C out/Debug` to build.

### Run tests

Run unit tests:
#### Run unit tests:
```sh
> out/Debug/gpgmm_unittests
```

Run end2end tests:
Unit tests check the front-end code in isolation or without using backend GPU.

#### Run end2end tests:
```sh
> out/Debug/gpgmm_end2end_tests
```

Run capture replay tests:
End2End tests check both the front AND backend code using a backend GPU.

#### Run capture replay tests:
```sh
> out/Debug/gpgmm_capture_replay_tests
```

Capture replay tests checks using pre-recorded memory patterns using a backend GPU.

#### Run fuzzing tests:
```sh
> out/Debug/gpgmm_*_fuzzer
```

Fuzzer checks using random memory patterns using a backend GPU.

## How do I use it?

To allocate, you create an allocator then create allocations from it:
Expand Down
41 changes: 41 additions & 0 deletions src/fuzzers/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Copyright 2021 The GPGMM 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")
import("../../build_overrides/gpgmm_overrides_with_defaults.gni")

import("//testing/libfuzzer/fuzzer_test.gni")

# if (build_with_chromium) {
# import("//testing/libfuzzer/fuzzer_test.gni")
# } else {
# import("//testing/test.gni")
# }

if (is_win) {
fuzzer_test("gpgmm_d3d12_resource_allocator_fuzzer") {
sources = [ "D3D12ResourceAllocatorFuzzer.cpp" ]

deps = [ "${gpgmm_root_dir}:gpgmm" ]
}
}

group("fuzzers") {
testonly = true
deps = []

if (is_win) {
deps += [ ":gpgmm_d3d12_resource_allocator_fuzzer" ]
}
}
62 changes: 62 additions & 0 deletions src/fuzzers/D3D12ResourceAllocatorFuzzer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2021 The GPGMM 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 "testing/libfuzzer/libfuzzer_exports.h"

#include <gpgmm_d3d12.h>

namespace {

ComPtr<gpgmm::d3d12::ResourceAllocator> gResourceAllocator;

} // namespace

extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
gpgmm::d3d12::ALLOCATOR_DESC desc = {};
gpgmm::d3d12::ResourceAllocator::CreateAllocator(desc, &gResourceAllocator);
return 0;
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
if (size < 8) {
return 0;
}

if (gResourceAllocator == nullptr) {
return 0;
}

D3D12_RESOURCE_DESC resourceDesc = {};
resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
resourceDesc.Alignment = 0;
resourceDesc.Width = static_cast<uint64_t>(data[0]);
resourceDesc.Height = 1;
resourceDesc.DepthOrArraySize = 1;
resourceDesc.MipLevels = 1;
resourceDesc.Format = DXGI_FORMAT_UNKNOWN;
resourceDesc.SampleDesc.Count = 1;
resourceDesc.SampleDesc.Quality = 0;
resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
resourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE;

gpgmm::d3d12::ALLOCATION_DESC allocationDesc = {};
allocationDesc.HeapType = D3D12_HEAP_TYPE_DEFAULT;

ComPtr<gpgmm::d3d12::ResourceAllocation> allocation;
gResourceAllocator->CreateResource(allocationDesc, resourceDesc, D3D12_RESOURCE_STATE_COMMON,
nullptr, &allocation);
return 0;
}
85 changes: 85 additions & 0 deletions third_party/libFuzzer/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("///build/config/sanitizers/sanitizers.gni")

config("warnings") {
if (is_clang) {
cflags = [
"-Wno-shadow",

# See crbug.com/932188, libFuzzer does not check the result of write()
# when it does raw printing.
"-Wno-unused-result",
]
}
}

# Engine should be compiled without coverage (infinite loop in trace_cmp).
fuzzing_engine_remove_configs = [
"//build/config/coverage:default_coverage",
"//build/config/sanitizers:default_sanitizer_flags",
]

# Add any sanitizer flags back. In MSAN builds, instrumenting libfuzzer with
# MSAN is necessary since all parts of the binary need to be instrumented for it
# to work. ASAN builds are more subtle: libfuzzer depends on features from the
# C++ STL. If it were not instrumented, templates would be insantiated without
# ASAN from libfuzzer and with ASAN in other TUs. The linker might merge
# instrumented template instantiations with non-instrumented ones (which could
# have a different ABI) in the final binary, which is problematic for TUs
# expecting one particular ABI (https://crbug.com/915422). The other sanitizers
# are added back for the same reason.
fuzzing_engine_add_configs = [
"//build/config/sanitizers:default_sanitizer_flags_but_coverage",
":warnings",
]

source_set("libfuzzer") {
sources = [
"src/FuzzerCrossOver.cpp",
"src/FuzzerDataFlowTrace.cpp",
"src/FuzzerDriver.cpp",
"src/FuzzerExtFunctionsDlsym.cpp",
"src/FuzzerExtFunctionsWeak.cpp",
"src/FuzzerExtFunctionsWindows.cpp",
"src/FuzzerExtraCounters.cpp",
"src/FuzzerFork.cpp",
"src/FuzzerIO.cpp",
"src/FuzzerIOPosix.cpp",
"src/FuzzerIOWindows.cpp",
"src/FuzzerLoop.cpp",
"src/FuzzerMerge.cpp",
"src/FuzzerMutate.cpp",
"src/FuzzerSHA1.cpp",
"src/FuzzerTracePC.cpp",
"src/FuzzerUtil.cpp",
"src/FuzzerUtilDarwin.cpp",
"src/FuzzerUtilFuchsia.cpp",
"src/FuzzerUtilLinux.cpp",
"src/FuzzerUtilPosix.cpp",
"src/FuzzerUtilWindows.cpp",
]

if (!is_ios) {
sources += [ "src/FuzzerMain.cpp" ]
}

configs -= fuzzing_engine_remove_configs
configs += fuzzing_engine_add_configs

deps = []
if (is_fuchsia) {
deps += [ "//third_party/fuchsia-sdk/sdk:fdio" ]
}
}

if (use_afl) {
source_set("afl_driver") {
sources = [ "src/afl/afl_driver.cpp" ]

configs -= fuzzing_engine_remove_configs
configs += fuzzing_engine_add_configs
}
}
4 changes: 4 additions & 0 deletions tools/memory/asan/blocklist_win.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# The rules in this file are only applied at compile time. If you can modify the
# source in question, consider function attributes to disable instrumentation.
#
# Please think twice before you add or remove these rules.