annotate libcxx/fuzzing/fuzz_test.cpp @ 192:d7606dcf6fce

Added tag llvm10 for changeset 0572611fdcc8
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 14 Dec 2020 18:01:34 +0900
parents 1d019706d866
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 // -*- C++ -*-
anatofuz
parents:
diff changeset
2 //===------------------------- fuzz_test.cpp ------------------------------===//
anatofuz
parents:
diff changeset
3 //
anatofuz
parents:
diff changeset
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
5 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
7 //
anatofuz
parents:
diff changeset
8 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
9
anatofuz
parents:
diff changeset
10 // A simple program for running regressions on the fuzzing routines.
anatofuz
parents:
diff changeset
11 // This code is not part of any shipping product.
anatofuz
parents:
diff changeset
12 //
anatofuz
parents:
diff changeset
13 // To build:
anatofuz
parents:
diff changeset
14 // clang++ -std=c++11 fuzz_test.cpp fuzzing.cpp
anatofuz
parents:
diff changeset
15 //
anatofuz
parents:
diff changeset
16 // To use:
anatofuz
parents:
diff changeset
17 // fuzz_test -r partial_sort [-v] files...
anatofuz
parents:
diff changeset
18 //
anatofuz
parents:
diff changeset
19 // Each file should contain a test case.
anatofuz
parents:
diff changeset
20
anatofuz
parents:
diff changeset
21 // TODO: should add some memory tracking, too.
anatofuz
parents:
diff changeset
22
anatofuz
parents:
diff changeset
23
anatofuz
parents:
diff changeset
24 #include <iostream>
anatofuz
parents:
diff changeset
25 #include <fstream>
anatofuz
parents:
diff changeset
26 #include <iterator>
anatofuz
parents:
diff changeset
27 #include <vector>
anatofuz
parents:
diff changeset
28 #include <map>
anatofuz
parents:
diff changeset
29 #include <chrono>
anatofuz
parents:
diff changeset
30
anatofuz
parents:
diff changeset
31 #include "fuzzing.h"
anatofuz
parents:
diff changeset
32
anatofuz
parents:
diff changeset
33 // ==== Count memory allocations ====
anatofuz
parents:
diff changeset
34
anatofuz
parents:
diff changeset
35 struct MemoryCounters {
anatofuz
parents:
diff changeset
36 size_t totalAllocationCount;
anatofuz
parents:
diff changeset
37 size_t netAllocationCount;
anatofuz
parents:
diff changeset
38 size_t totalBytesAllocated;
anatofuz
parents:
diff changeset
39 };
anatofuz
parents:
diff changeset
40
anatofuz
parents:
diff changeset
41 MemoryCounters gMemoryCounters;
anatofuz
parents:
diff changeset
42
anatofuz
parents:
diff changeset
43 void ZeroMemoryCounters() {
anatofuz
parents:
diff changeset
44 gMemoryCounters.totalAllocationCount = 0;
anatofuz
parents:
diff changeset
45 gMemoryCounters.netAllocationCount = 0;
anatofuz
parents:
diff changeset
46 gMemoryCounters.totalBytesAllocated = 0;
anatofuz
parents:
diff changeset
47 }
anatofuz
parents:
diff changeset
48
anatofuz
parents:
diff changeset
49 void* operator new(std::size_t size)
anatofuz
parents:
diff changeset
50 {
anatofuz
parents:
diff changeset
51 if (size == 0) size = 1;
anatofuz
parents:
diff changeset
52 void *p = ::malloc(size);
anatofuz
parents:
diff changeset
53 if (p == NULL)
anatofuz
parents:
diff changeset
54 throw std::bad_alloc();
anatofuz
parents:
diff changeset
55 gMemoryCounters.totalAllocationCount += 1;
anatofuz
parents:
diff changeset
56 gMemoryCounters.netAllocationCount += 1;
anatofuz
parents:
diff changeset
57 gMemoryCounters.totalBytesAllocated += size;
anatofuz
parents:
diff changeset
58 return p;
anatofuz
parents:
diff changeset
59 }
anatofuz
parents:
diff changeset
60
anatofuz
parents:
diff changeset
61 void* operator new(std::size_t size, const std::nothrow_t&) noexcept
anatofuz
parents:
diff changeset
62 {
anatofuz
parents:
diff changeset
63 try { return operator new(size); }
anatofuz
parents:
diff changeset
64 catch (const std::bad_alloc &) {}
anatofuz
parents:
diff changeset
65 return nullptr;
anatofuz
parents:
diff changeset
66 }
anatofuz
parents:
diff changeset
67
anatofuz
parents:
diff changeset
68 void* operator new[](std::size_t size)
anatofuz
parents:
diff changeset
69 {
anatofuz
parents:
diff changeset
70 return ::operator new(size);
anatofuz
parents:
diff changeset
71 }
anatofuz
parents:
diff changeset
72
anatofuz
parents:
diff changeset
73 void* operator new[](std::size_t size, const std::nothrow_t&) noexcept
anatofuz
parents:
diff changeset
74 {
anatofuz
parents:
diff changeset
75 try { return operator new(size); }
anatofuz
parents:
diff changeset
76 catch (const std::bad_alloc &) {}
anatofuz
parents:
diff changeset
77 return nullptr;
anatofuz
parents:
diff changeset
78 }
anatofuz
parents:
diff changeset
79
anatofuz
parents:
diff changeset
80 void operator delete(void* ptr) noexcept
anatofuz
parents:
diff changeset
81 {
anatofuz
parents:
diff changeset
82 if (ptr)
anatofuz
parents:
diff changeset
83 ::free(ptr);
anatofuz
parents:
diff changeset
84 gMemoryCounters.netAllocationCount -= 1;
anatofuz
parents:
diff changeset
85 }
anatofuz
parents:
diff changeset
86
anatofuz
parents:
diff changeset
87 void operator delete(void* ptr, const std::nothrow_t&) noexcept
anatofuz
parents:
diff changeset
88 {
anatofuz
parents:
diff changeset
89 ::operator delete(ptr);
anatofuz
parents:
diff changeset
90 }
anatofuz
parents:
diff changeset
91
anatofuz
parents:
diff changeset
92 void operator delete[](void* ptr) noexcept
anatofuz
parents:
diff changeset
93 {
anatofuz
parents:
diff changeset
94 ::operator delete(ptr);
anatofuz
parents:
diff changeset
95 }
anatofuz
parents:
diff changeset
96
anatofuz
parents:
diff changeset
97 void operator delete[](void* ptr, const std::nothrow_t&) noexcept
anatofuz
parents:
diff changeset
98 {
anatofuz
parents:
diff changeset
99 ::operator delete(ptr);
anatofuz
parents:
diff changeset
100 }
anatofuz
parents:
diff changeset
101
anatofuz
parents:
diff changeset
102 // ==== End count memory allocations ====
anatofuz
parents:
diff changeset
103
anatofuz
parents:
diff changeset
104
anatofuz
parents:
diff changeset
105 typedef int (*FuzzProc) (const uint8_t *data, size_t size);
anatofuz
parents:
diff changeset
106
anatofuz
parents:
diff changeset
107 const std::map<std::string, FuzzProc> procs = {
anatofuz
parents:
diff changeset
108 {"sort", fuzzing::sort},
anatofuz
parents:
diff changeset
109 {"stable_sort", fuzzing::stable_sort},
anatofuz
parents:
diff changeset
110 {"partition", fuzzing::partition},
anatofuz
parents:
diff changeset
111 {"partition_copy", fuzzing::partition_copy},
anatofuz
parents:
diff changeset
112 {"stable_partition", fuzzing::stable_partition},
anatofuz
parents:
diff changeset
113 {"unique", fuzzing::unique},
anatofuz
parents:
diff changeset
114 {"unique_copy", fuzzing::unique_copy},
anatofuz
parents:
diff changeset
115 {"nth_element", fuzzing::nth_element},
anatofuz
parents:
diff changeset
116 {"partial_sort", fuzzing::partial_sort},
anatofuz
parents:
diff changeset
117 {"partial_sort_copy", fuzzing::partial_sort_copy},
anatofuz
parents:
diff changeset
118 {"make_heap", fuzzing::make_heap},
anatofuz
parents:
diff changeset
119 {"push_heap", fuzzing::push_heap},
anatofuz
parents:
diff changeset
120 {"pop_heap", fuzzing::pop_heap},
anatofuz
parents:
diff changeset
121 {"regex_ECMAScript", fuzzing::regex_ECMAScript},
anatofuz
parents:
diff changeset
122 {"regex_POSIX", fuzzing::regex_POSIX},
anatofuz
parents:
diff changeset
123 {"regex_extended", fuzzing::regex_extended},
anatofuz
parents:
diff changeset
124 {"regex_awk", fuzzing::regex_awk},
anatofuz
parents:
diff changeset
125 {"regex_grep", fuzzing::regex_grep},
anatofuz
parents:
diff changeset
126 {"regex_egrep", fuzzing::regex_egrep},
anatofuz
parents:
diff changeset
127 {"search", fuzzing::search}
anatofuz
parents:
diff changeset
128 };
anatofuz
parents:
diff changeset
129
anatofuz
parents:
diff changeset
130
anatofuz
parents:
diff changeset
131
anatofuz
parents:
diff changeset
132 bool verbose = false;
anatofuz
parents:
diff changeset
133
anatofuz
parents:
diff changeset
134 void test_one(const char *filename, FuzzProc fp)
anatofuz
parents:
diff changeset
135 {
anatofuz
parents:
diff changeset
136 std::vector<uint8_t> v;
anatofuz
parents:
diff changeset
137 std::ifstream f (filename, std::ios::binary);
anatofuz
parents:
diff changeset
138 if (!f.is_open())
anatofuz
parents:
diff changeset
139 std::cerr << "## Can't open '" << filename << "'" << std::endl;
anatofuz
parents:
diff changeset
140 else
anatofuz
parents:
diff changeset
141 {
anatofuz
parents:
diff changeset
142 typedef std::istream_iterator<uint8_t> Iter;
anatofuz
parents:
diff changeset
143 std::copy(Iter(f), Iter(), std::back_inserter(v));
anatofuz
parents:
diff changeset
144 if (verbose)
anatofuz
parents:
diff changeset
145 std::cout << "File '" << filename << "' contains " << v.size() << " entries" << std::endl;
anatofuz
parents:
diff changeset
146 ZeroMemoryCounters();
anatofuz
parents:
diff changeset
147 const auto start_time = std::chrono::high_resolution_clock::now();
anatofuz
parents:
diff changeset
148 int ret = fp (v.data(), v.size());
anatofuz
parents:
diff changeset
149 const auto finish_time = std::chrono::high_resolution_clock::now();
anatofuz
parents:
diff changeset
150 MemoryCounters mc = gMemoryCounters;
anatofuz
parents:
diff changeset
151 if (ret != 0)
anatofuz
parents:
diff changeset
152 std::cerr << "## Failure code: " << ret << std::endl;
anatofuz
parents:
diff changeset
153 if (verbose)
anatofuz
parents:
diff changeset
154 {
anatofuz
parents:
diff changeset
155 std::cout << "Execution time: "
anatofuz
parents:
diff changeset
156 << std::chrono::duration_cast<std::chrono::milliseconds>(finish_time - start_time).count()
anatofuz
parents:
diff changeset
157 << " milliseconds" << std::endl;
anatofuz
parents:
diff changeset
158 std::cout << "Memory: "
anatofuz
parents:
diff changeset
159 << mc.totalBytesAllocated << " bytes allocated ("
anatofuz
parents:
diff changeset
160 << mc.totalAllocationCount << " allocations); "
anatofuz
parents:
diff changeset
161 << mc.netAllocationCount << " allocations remain" << std::endl;
anatofuz
parents:
diff changeset
162 }
anatofuz
parents:
diff changeset
163 }
anatofuz
parents:
diff changeset
164 }
anatofuz
parents:
diff changeset
165
anatofuz
parents:
diff changeset
166 void usage (const char *name)
anatofuz
parents:
diff changeset
167 {
anatofuz
parents:
diff changeset
168 std::cout << "Usage: " << name << " -r proc [-v] files..." << std::endl;
anatofuz
parents:
diff changeset
169 std::cout << "Supported routines:" << std::endl;
anatofuz
parents:
diff changeset
170 for (const auto &p : procs)
anatofuz
parents:
diff changeset
171 std::cout << " " << p.first << std::endl;
anatofuz
parents:
diff changeset
172 std::cout << std::endl;
anatofuz
parents:
diff changeset
173 }
anatofuz
parents:
diff changeset
174
anatofuz
parents:
diff changeset
175 // Poor man's command-line options
anatofuz
parents:
diff changeset
176 const std::string dashR("-r");
anatofuz
parents:
diff changeset
177 const std::string dashV("-v");
anatofuz
parents:
diff changeset
178
anatofuz
parents:
diff changeset
179 int main(int argc, char *argv[])
anatofuz
parents:
diff changeset
180 {
anatofuz
parents:
diff changeset
181 if (argc < 4 || dashR != argv[1] || procs.find(argv[2]) == procs.end())
anatofuz
parents:
diff changeset
182 usage(argv[0]);
anatofuz
parents:
diff changeset
183 else {
anatofuz
parents:
diff changeset
184 FuzzProc fp = procs.find(argv[2])->second;
anatofuz
parents:
diff changeset
185 int firstFile = 3;
anatofuz
parents:
diff changeset
186 if (dashV == argv[firstFile])
anatofuz
parents:
diff changeset
187 {
anatofuz
parents:
diff changeset
188 verbose = true;
anatofuz
parents:
diff changeset
189 ++firstFile;
anatofuz
parents:
diff changeset
190 }
anatofuz
parents:
diff changeset
191 for (int i = firstFile; i < argc; ++i)
anatofuz
parents:
diff changeset
192 test_one(argv[i], fp);
anatofuz
parents:
diff changeset
193 }
anatofuz
parents:
diff changeset
194 }