2 * Copyright 2013 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.
18 #ifndef FOLLY_EXPERIMENTAL_SYMBOLIZER_SYMBOLIZER_H_
19 #define FOLLY_EXPERIMENTAL_SYMBOLIZER_SYMBOLIZER_H_
23 #include <unordered_map>
25 #include "folly/Range.h"
26 #include "folly/experimental/symbolizer/Elf.h"
27 #include "folly/experimental/symbolizer/Dwarf.h"
28 #include "folly/experimental/symbolizer/StackTrace.h"
31 namespace symbolizer {
34 * Frame information: symbol name and location.
36 * Note that both name and location are references in the Symbolizer object,
37 * which must outlive this SymbolizedFrame object.
39 struct SymbolizedFrame {
40 SymbolizedFrame() : found(false) { }
44 Dwarf::LocationInfo location;
49 FrameArray() : frameCount(0) { }
52 uintptr_t addresses[N];
53 SymbolizedFrame frames[N];
57 * Get stack trace into a given FrameArray, return true on success (and
58 * set frameCount to the actual frame count, which may be > N) and false
62 bool getStackTrace(FrameArray<N>& fa) {
63 ssize_t n = getStackTrace(fa.addresses, N);
66 for (size_t i = 0; i < fa.frameCount; ++i) {
67 fa.frames[i].found = false;
78 Symbolizer() : fileCount_(0) { }
81 * Symbolize given addresses.
83 void symbolize(const uintptr_t* addresses,
84 SymbolizedFrame* frames,
88 void symbolize(FrameArray<N>& fa) {
89 symbolize(fa.addresses, fa.frames, fa.frameCount);
93 * Shortcut to symbolize one address.
95 bool symbolize(uintptr_t address, SymbolizedFrame& frame) {
96 symbolize(&address, &frame, 1);
101 // We can't allocate memory, so we'll preallocate room.
102 // "1023 shared libraries should be enough for everyone"
103 static constexpr size_t kMaxFiles = 1024;
105 ElfFile files_[kMaxFiles];
109 * Print a list of symbolized addresses. Base class.
111 class SymbolizePrinter {
113 void print(uintptr_t address, const SymbolizedFrame& frame);
114 void print(const uintptr_t* addresses,
115 const SymbolizedFrame* frames,
119 void print(const FrameArray<N>& fa, size_t skip=0) {
120 if (skip < fa.frameCount) {
121 print(fa.addresses + skip, fa.frames + skip, fa.frameCount - skip);
125 virtual ~SymbolizePrinter() { }
127 virtual void doPrint(StringPiece sp) = 0;
131 * Print a list of symbolized addresses to a stream.
132 * Not reentrant. Do not use from signal handling code.
134 class OStreamSymbolizePrinter : public SymbolizePrinter {
136 explicit OStreamSymbolizePrinter(std::ostream& out) : out_(out) { }
138 void doPrint(StringPiece sp) override;
143 * Print a list of symbolized addresses to a file descriptor.
144 * Ignores errors. Async-signal-safe.
146 class FDSymbolizePrinter : public SymbolizePrinter {
148 explicit FDSymbolizePrinter(int fd) : fd_(fd) { }
150 void doPrint(StringPiece sp) override;
154 } // namespace symbolizer
157 #endif /* FOLLY_EXPERIMENTAL_SYMBOLIZER_SYMBOLIZER_H_ */