2 * Copyright 2014 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.
17 #include <folly/experimental/symbolizer/StackTrace.h>
18 #include <folly/experimental/symbolizer/Symbolizer.h>
20 #include <glog/logging.h>
21 #include <gtest/gtest.h>
23 using namespace folly;
24 using namespace folly::symbolizer;
26 FOLLY_NOINLINE void foo1();
27 FOLLY_NOINLINE void foo2();
29 void verifyStackTraces() {
30 constexpr size_t kMaxAddresses = 100;
31 FrameArray<kMaxAddresses> fa;
32 CHECK(getStackTrace(fa));
34 FrameArray<kMaxAddresses> faSafe;
35 CHECK(getStackTraceSafe(faSafe));
37 CHECK_EQ(fa.frameCount, faSafe.frameCount);
40 Symbolizer symbolizer;
41 OStreamSymbolizePrinter printer(std::cerr, SymbolizePrinter::COLOR_IF_TTY);
43 symbolizer.symbolize(fa);
44 VLOG(1) << "getStackTrace\n";
47 symbolizer.symbolize(faSafe);
48 VLOG(1) << "getStackTraceSafe\n";
49 printer.println(faSafe);
52 // Other than the top 2 frames (this one and getStackTrace /
53 // getStackTraceSafe), the stack traces should be identical
54 for (size_t i = 2; i < fa.frameCount; ++i) {
55 VLOG(1) << "i=" << i << " " << std::hex << fa.addresses[i] << " "
56 << faSafe.addresses[i];
57 CHECK_EQ(fa.addresses[i], faSafe.addresses[i]);
69 volatile bool handled = false;
70 void handler(int num, siginfo_t* info, void* ctx) {
71 // Yes, getStackTrace and VLOG aren't async-signal-safe, but signals
72 // raised with raise() aren't "async" signals.
77 TEST(StackTraceTest, Simple) {
81 TEST(StackTraceTest, Signal) {
83 memset(&sa, 0, sizeof(sa));
84 sa.sa_sigaction = handler;
85 sa.sa_flags = SA_RESETHAND | SA_SIGINFO;
86 CHECK_ERR(sigaction(SIGUSR1, &sa, nullptr));
91 int main(int argc, char *argv[]) {
92 testing::InitGoogleTest(&argc, argv);
93 gflags::ParseCommandLineFlags(&argc, &argv, true);
94 return RUN_ALL_TESTS();