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