2 * Copyright 2016 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21 #include <condition_variable>
24 #include <gtest/gtest.h>
26 #include <folly/experimental/exception_tracer/ExceptionCounterLib.h>
28 struct MyException {};
30 void bar() { throw std::runtime_error("hello"); }
32 void foo() { throw MyException(); }
36 using namespace folly::exception_tracer;
39 void throwAndCatch(F f) {
47 TEST(ExceptionCounter, oneThread) {
49 for (int i = 0; i < 10; ++i) {
53 auto stats = getExceptionStatistics();
54 EXPECT_EQ(stats.size(), 2);
55 EXPECT_EQ(stats[0].count, 10);
56 EXPECT_EQ(stats[1].count, 1);
57 EXPECT_EQ(*(stats[0].info.type), typeid(std::runtime_error));
58 EXPECT_EQ(*(stats[1].info.type), typeid(MyException));
61 TEST(ExceptionCounter, testClearExceptionStatistics) {
63 auto stats = getExceptionStatistics();
64 EXPECT_EQ(stats.size(), 1);
65 stats = getExceptionStatistics();
66 EXPECT_EQ(stats.size(), 0);
69 TEST(ExceptionCounter, testDifferentStacks) {
72 auto stats = getExceptionStatistics();
73 EXPECT_EQ(stats.size(), 2);
76 TEST(ExceptionCounter, multyThreads) {
77 constexpr size_t kNumIterations = 10000;
78 constexpr size_t kNumThreads = 10;
79 std::vector<std::thread> threads;
80 threads.resize(kNumThreads);
82 std::mutex preparedMutex;
83 std::mutex finishedMutex;
84 std::condition_variable preparedBarrier;
85 std::condition_variable finishedBarrier;
86 int preparedThreads = 0;
87 bool finished = false;
89 for (auto& t : threads) {
90 t = std::thread([&]() {
91 for (size_t i = 0; i < kNumIterations; ++i) {
96 std::unique_lock<std::mutex> lock(preparedMutex);
98 preparedBarrier.notify_one();
101 std::unique_lock<std::mutex> lock(finishedMutex);
102 finishedBarrier.wait(lock, [&]() { return finished; });
107 std::unique_lock<std::mutex> lock(preparedMutex);
108 preparedBarrier.wait(lock,
109 [&]() { return preparedThreads == kNumThreads; });
112 auto stats = getExceptionStatistics();
113 EXPECT_EQ(stats.size(), 1);
114 EXPECT_EQ(stats[0].count, kNumIterations * kNumThreads);
117 std::unique_lock<std::mutex> lock(finishedMutex);
119 finishedBarrier.notify_all();
122 for (auto& t : threads) {