2 * Copyright 2017 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>
22 #include <folly/portability/GTest.h>
24 using namespace folly;
25 using namespace folly::symbolizer;
27 FOLLY_NOINLINE void foo1();
28 FOLLY_NOINLINE void foo2();
30 void verifyStackTraces() {
31 constexpr size_t kMaxAddresses = 100;
32 FrameArray<kMaxAddresses> fa;
33 CHECK(getStackTrace(fa));
35 FrameArray<kMaxAddresses> faSafe;
36 CHECK(getStackTraceSafe(faSafe));
38 CHECK_EQ(fa.frameCount, faSafe.frameCount);
41 Symbolizer symbolizer;
42 OStreamSymbolizePrinter printer(std::cerr, SymbolizePrinter::COLOR_IF_TTY);
44 symbolizer.symbolize(fa);
45 VLOG(1) << "getStackTrace\n";
48 symbolizer.symbolize(faSafe);
49 VLOG(1) << "getStackTraceSafe\n";
50 printer.println(faSafe);
53 // Other than the top 2 frames (this one and getStackTrace /
54 // getStackTraceSafe), the stack traces should be identical
55 for (size_t i = 2; i < fa.frameCount; ++i) {
56 LOG(INFO) << "i=" << i << " " << std::hex << "0x" << fa.addresses[i]
57 << " 0x" << faSafe.addresses[i];
58 EXPECT_EQ(fa.addresses[i], faSafe.addresses[i]);
70 volatile bool handled = false;
71 void handler(int /* num */, siginfo_t* /* info */, void* /* ctx */) {
72 // Yes, getStackTrace and VLOG aren't async-signal-safe, but signals
73 // raised with raise() aren't "async" signals.
78 TEST(StackTraceTest, Simple) {
82 TEST(StackTraceTest, Signal) {
84 memset(&sa, 0, sizeof(sa));
85 sa.sa_sigaction = handler;
86 sa.sa_flags = SA_RESETHAND | SA_SIGINFO;
87 CHECK_ERR(sigaction(SIGUSR1, &sa, nullptr));