fuzzing: Factor WireServer set up code out of frontend fuzzer
This will make it easier to bring up other Dawn backend fuzzers
that don't use the Null backend.
Bug: dawn:295
Change-Id: I176b937722a63509cab620ac2a90098d87a6049c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/14623
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
diff --git a/src/fuzzers/BUILD.gn b/src/fuzzers/BUILD.gn
index aea8fe6..2b51d6e 100644
--- a/src/fuzzers/BUILD.gn
+++ b/src/fuzzers/BUILD.gn
@@ -79,6 +79,20 @@
]
}
+static_library("dawn_wire_server_fuzzer_common") {
+ sources = [
+ "DawnWireServerFuzzer.cpp",
+ "DawnWireServerFuzzer.h",
+ ]
+ public_deps = [
+ "${dawn_root}/:libdawn_native_static",
+ "${dawn_root}/:libdawn_wire_static",
+ "${dawn_root}/src/common",
+ "${dawn_root}/src/dawn:dawncpp",
+ "${dawn_root}/src/dawn:libdawn_proc",
+ ]
+}
+
# TODO(rharrison): Remove asan_options once signal trap is no longer
# needed.
# Uses Dawn specific options and varies input data
@@ -123,7 +137,7 @@
"DawnSPVCglslFastFuzzer.cpp",
]
deps = [
- "${dawn_shaderc_dir}:libshaderc_spvc",
+ "${dawn_shaderc_dir}:libshaderc_spvc",
]
}
@@ -132,7 +146,7 @@
"DawnSPVChlslFastFuzzer.cpp",
]
deps = [
- "${dawn_shaderc_dir}:libshaderc_spvc",
+ "${dawn_shaderc_dir}:libshaderc_spvc",
]
}
@@ -141,7 +155,7 @@
"DawnSPVCmslFastFuzzer.cpp",
]
deps = [
- "${dawn_shaderc_dir}:libshaderc_spvc",
+ "${dawn_shaderc_dir}:libshaderc_spvc",
]
}
@@ -151,11 +165,7 @@
]
deps = [
- "${dawn_root}/:libdawn_native_static",
- "${dawn_root}/:libdawn_wire_static",
- "${dawn_root}/src/common",
- "${dawn_root}/src/dawn:dawncpp",
- "${dawn_root}/src/dawn:libdawn_proc",
+ ":dawn_wire_server_fuzzer_common",
]
additional_configs = [ "${dawn_root}/src/common:dawn_internal" ]
diff --git a/src/fuzzers/DawnWireServerAndFrontendFuzzer.cpp b/src/fuzzers/DawnWireServerAndFrontendFuzzer.cpp
index ad904b7..7911738 100644
--- a/src/fuzzers/DawnWireServerAndFrontendFuzzer.cpp
+++ b/src/fuzzers/DawnWireServerAndFrontendFuzzer.cpp
@@ -12,85 +12,26 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include "DawnWireServerFuzzer.h"
+
#include "common/Assert.h"
-#include "dawn/dawn_proc.h"
-#include "dawn/webgpu_cpp.h"
#include "dawn_native/DawnNative.h"
-#include "dawn_wire/WireServer.h"
-
-#include <vector>
-
-class DevNull : public dawn_wire::CommandSerializer {
- public:
- void* GetCmdSpace(size_t size) override {
- if (size > buf.size()) {
- buf.resize(size);
- }
- return buf.data();
- }
- bool Flush() override {
- return true;
- }
-
- private:
- std::vector<char> buf;
-};
-
-static WGPUProcDeviceCreateSwapChain originalDeviceCreateSwapChain = nullptr;
-
-WGPUSwapChain ErrorDeviceCreateSwapChain(WGPUDevice device, const WGPUSwapChainDescriptor*) {
- WGPUSwapChainDescriptor desc;
- desc.nextInChain = nullptr;
- desc.label = nullptr;
- // A 0 implementation will trigger a swapchain creation error.
- desc.implementation = 0;
- return originalDeviceCreateSwapChain(device, &desc);
-}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- DawnProcTable procs = dawn_native::GetProcs();
+ return DawnWireServerFuzzer::Run(data, size, [](dawn_native::Instance* instance) {
+ instance->DiscoverDefaultAdapters();
- // Swapchains receive a pointer to an implementation. The fuzzer will pass garbage in so we
- // intercept calls to create swapchains and make sure they always return error swapchains.
- // This is ok for fuzzing because embedders of dawn_wire would always define their own
- // swapchain handling.
- originalDeviceCreateSwapChain = procs.deviceCreateSwapChain;
- procs.deviceCreateSwapChain = ErrorDeviceCreateSwapChain;
+ std::vector<dawn_native::Adapter> adapters = instance->GetAdapters();
- dawnProcSetProcs(&procs);
-
- // Create an instance and find the null adapter to create a device with.
- std::unique_ptr<dawn_native::Instance> instance = std::make_unique<dawn_native::Instance>();
- instance->DiscoverDefaultAdapters();
-
- std::vector<dawn_native::Adapter> adapters = instance->GetAdapters();
-
- wgpu::Device nullDevice;
- for (dawn_native::Adapter adapter : adapters) {
- if (adapter.GetBackendType() == dawn_native::BackendType::Null) {
- nullDevice = wgpu::Device::Acquire(adapter.CreateDevice());
- break;
+ wgpu::Device nullDevice;
+ for (dawn_native::Adapter adapter : adapters) {
+ if (adapter.GetBackendType() == dawn_native::BackendType::Null) {
+ nullDevice = wgpu::Device::Acquire(adapter.CreateDevice());
+ break;
+ }
}
- }
- ASSERT(nullDevice.Get() != nullptr);
- DevNull devNull;
- dawn_wire::WireServerDescriptor serverDesc = {};
- serverDesc.device = nullDevice.Get();
- serverDesc.procs = &procs;
- serverDesc.serializer = &devNull;
-
- std::unique_ptr<dawn_wire::WireServer> wireServer(new dawn_wire::WireServer(serverDesc));
-
- wireServer->HandleCommands(reinterpret_cast<const char*>(data), size);
-
- // Fake waiting for all previous commands before destroying the server.
- nullDevice.Tick();
-
- // Destroy the server before the device because it needs to free all objects.
- wireServer = nullptr;
- nullDevice = nullptr;
- instance = nullptr;
-
- return 0;
+ ASSERT(nullDevice.Get() != nullptr);
+ return nullDevice;
+ });
}
diff --git a/src/fuzzers/DawnWireServerFuzzer.cpp b/src/fuzzers/DawnWireServerFuzzer.cpp
new file mode 100644
index 0000000..f7a19f1
--- /dev/null
+++ b/src/fuzzers/DawnWireServerFuzzer.cpp
@@ -0,0 +1,91 @@
+// Copyright 2019 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 "DawnWireServerFuzzer.h"
+
+#include "common/Assert.h"
+#include "dawn/dawn_proc.h"
+#include "dawn/webgpu_cpp.h"
+#include "dawn_native/DawnNative.h"
+#include "dawn_wire/WireServer.h"
+
+#include <vector>
+
+namespace {
+
+ class DevNull : public dawn_wire::CommandSerializer {
+ public:
+ void* GetCmdSpace(size_t size) override {
+ if (size > buf.size()) {
+ buf.resize(size);
+ }
+ return buf.data();
+ }
+ bool Flush() override {
+ return true;
+ }
+
+ private:
+ std::vector<char> buf;
+ };
+
+ WGPUProcDeviceCreateSwapChain sOriginalDeviceCreateSwapChain = nullptr;
+
+ WGPUSwapChain ErrorDeviceCreateSwapChain(WGPUDevice device, const WGPUSwapChainDescriptor*) {
+ WGPUSwapChainDescriptor desc;
+ desc.nextInChain = nullptr;
+ desc.label = nullptr;
+ // A 0 implementation will trigger a swapchain creation error.
+ desc.implementation = 0;
+ return sOriginalDeviceCreateSwapChain(device, &desc);
+ }
+
+} // namespace
+
+int DawnWireServerFuzzer::Run(const uint8_t* data, size_t size, MakeDeviceFn MakeDevice) {
+ DawnProcTable procs = dawn_native::GetProcs();
+
+ // Swapchains receive a pointer to an implementation. The fuzzer will pass garbage in so we
+ // intercept calls to create swapchains and make sure they always return error swapchains.
+ // This is ok for fuzzing because embedders of dawn_wire would always define their own
+ // swapchain handling.
+ sOriginalDeviceCreateSwapChain = procs.deviceCreateSwapChain;
+ procs.deviceCreateSwapChain = ErrorDeviceCreateSwapChain;
+
+ dawnProcSetProcs(&procs);
+
+ std::unique_ptr<dawn_native::Instance> instance = std::make_unique<dawn_native::Instance>();
+ wgpu::Device device = MakeDevice(instance.get());
+ ASSERT(device);
+
+ DevNull devNull;
+ dawn_wire::WireServerDescriptor serverDesc = {};
+ serverDesc.device = device.Get();
+ serverDesc.procs = &procs;
+ serverDesc.serializer = &devNull;
+
+ std::unique_ptr<dawn_wire::WireServer> wireServer(new dawn_wire::WireServer(serverDesc));
+
+ wireServer->HandleCommands(reinterpret_cast<const char*>(data), size);
+
+ // Fake waiting for all previous commands before destroying the server.
+ device.Tick();
+
+ // Destroy the server before the device because it needs to free all objects.
+ wireServer = nullptr;
+ device = nullptr;
+ instance = nullptr;
+
+ return 0;
+}
diff --git a/src/fuzzers/DawnWireServerFuzzer.h b/src/fuzzers/DawnWireServerFuzzer.h
new file mode 100644
index 0000000..b4c011e
--- /dev/null
+++ b/src/fuzzers/DawnWireServerFuzzer.h
@@ -0,0 +1,32 @@
+// Copyright 2019 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 "dawn/webgpu_cpp.h"
+
+#include <cstdint>
+#include <functional>
+
+namespace dawn_native {
+
+ class Instance;
+
+} // namespace dawn_native
+
+namespace DawnWireServerFuzzer {
+
+ using MakeDeviceFn = std::function<wgpu::Device(dawn_native::Instance*)>;
+
+ int Run(const uint8_t* data, size_t size, MakeDeviceFn MakeDevice);
+
+} // namespace DawnWireServerFuzzer
diff --git a/src/fuzzers/StandaloneFuzzerMain.cpp b/src/fuzzers/StandaloneFuzzerMain.cpp
index ba8d94b..9755e1d 100644
--- a/src/fuzzers/StandaloneFuzzerMain.cpp
+++ b/src/fuzzers/StandaloneFuzzerMain.cpp
@@ -21,7 +21,7 @@
int main(int argc, char** argv) {
if (argc != 2) {
- std::cout << "Usage: <standalone reproducer> [FILE]" << std::endl;
+ std::cout << "Usage: <standalone reproducer> FILE" << std::endl;
return 1;
}