sql_multithreaded_fuzzer.cc 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. // Unused because SQLite is so serialized and concurrency-unfriendly that this
  5. // really wouldn't test anything.
  6. #include <condition_variable>
  7. #include <cstdlib>
  8. #include <iostream>
  9. #include <mutex>
  10. #include <string>
  11. #include <thread>
  12. #include <vector>
  13. #include "testing/libfuzzer/proto/lpm_interface.h"
  14. #include "third_party/sqlite/fuzz/disabled_queries_parser.h"
  15. #include "third_party/sqlite/fuzz/sql_query_grammar.pb.h"
  16. #include "third_party/sqlite/fuzz/sql_query_proto_to_string.h"
  17. #include "third_party/sqlite/fuzz/sql_run_queries.h"
  18. #include "third_party/sqlite/sqlite3.h"
  19. using namespace sql_query_grammar;
  20. namespace {
  21. constexpr int kNumThreads = 4; // Must change with MultipleSQLQueries protobuf.
  22. }
  23. DEFINE_BINARY_PROTO_FUZZER(const MultipleSQLQueries& multiple_sql_queries) {
  24. char* skip_queries = ::getenv("SQL_SKIP_QUERIES");
  25. if (skip_queries) {
  26. sql_fuzzer::SetDisabledQueries(
  27. sql_fuzzer::ParseDisabledQueries(skip_queries));
  28. }
  29. assert(multiple_sql_queries.GetDescriptor()->field_count() == kNumThreads);
  30. sqlite3* db = sql_fuzzer::InitConnectionForFuzzing();
  31. if (!db)
  32. return;
  33. if (::getenv("LPM_SQLITE_TRACE")) {
  34. sql_fuzzer::EnableSqliteTracing(db);
  35. }
  36. std::vector<std::string> query_strs[kNumThreads];
  37. query_strs[0] = sql_fuzzer::SQLQueriesToVec(multiple_sql_queries.queries1());
  38. query_strs[1] = sql_fuzzer::SQLQueriesToVec(multiple_sql_queries.queries2());
  39. query_strs[2] = sql_fuzzer::SQLQueriesToVec(multiple_sql_queries.queries3());
  40. query_strs[3] = sql_fuzzer::SQLQueriesToVec(multiple_sql_queries.queries4());
  41. if (::getenv("LPM_DUMP_NATIVE_INPUT")) {
  42. std::cout << "_________________________" << std::endl;
  43. for (int i = 0; i < kNumThreads; i++) {
  44. std::cout << "Thread " << i << ":" << std::endl;
  45. for (std::string query : query_strs[i]) {
  46. if (query == ";")
  47. continue;
  48. std::cout << query << std::endl;
  49. }
  50. }
  51. std::cout << "------------------------" << std::endl;
  52. }
  53. int num_threads_started = 0;
  54. std::mutex m;
  55. std::condition_variable cv;
  56. std::vector<std::thread> threads;
  57. auto to_run = [&](std::vector<std::string> queries) {
  58. // Wait for all the threads to start.
  59. std::unique_lock<std::mutex> lk(m);
  60. num_threads_started++;
  61. cv.notify_all();
  62. cv.wait(lk, [&] { return num_threads_started == kNumThreads; });
  63. m.unlock();
  64. sql_fuzzer::RunSqlQueriesOnConnection(db, queries);
  65. };
  66. for (int i = 0; i < kNumThreads; i++) {
  67. threads.emplace_back(to_run, query_strs[i]);
  68. }
  69. for (int i = 0; i < kNumThreads; i++) {
  70. threads[i].join();
  71. }
  72. sql_fuzzer::CloseConnection(db);
  73. }