return nullptr;
}
- Path path(p);
- auto pos = map_.find(path);
+ scratchpad_.assign(p);
+ auto pos = map_.find(scratchpad_);
if (pos != map_.end()) {
return slots_[pos->second];
}
auto& f = slots_[n];
const char* msg = "";
- int r = f->openAndFollow(path.data(), true, &msg);
+ int r = f->openAndFollow(scratchpad_.data(), true, &msg);
if (r != ElfFile::kSuccess) {
return nullptr;
}
- map_[path] = n;
+ map_[scratchpad_] = n;
return f;
}
// own wrapper around a fixed-size, null-terminated string.
class Path : private boost::totally_ordered<Path> {
public:
+ Path() {
+ assign(folly::StringPiece());
+ }
+
explicit Path(StringPiece s) {
+ assign(s);
+ }
+
+ void assign(StringPiece s) {
DCHECK_LE(s.size(), kMaxSize);
- memcpy(data_, s.data(), s.size());
+ if (!s.empty()) {
+ memcpy(data_, s.data(), s.size());
+ }
data_[s.size()] = '\0';
}
char data_[kMaxSize + 1];
};
+ Path scratchpad_; // Preallocated key for map_ lookups.
boost::container::flat_map<Path, int> map_;
std::vector<std::shared_ptr<ElfFile>> slots_;
};
#include <folly/Conv.h>
#include <folly/FileUtil.h>
+#include <folly/Memory.h>
#include <folly/ScopeGuard.h>
#include <folly/String.h>
printer_(
fd,
SymbolizePrinter::COLOR_IF_TTY,
- size_t(64) << 10) // 64KiB
-{}
+ size_t(64) << 10), // 64KiB
+ addresses_(make_unique<FrameArray<kMaxStackTraceDepth>>()) {}
void StackTracePrinter::flush() {
printer_.flush();
SCOPE_EXIT {
flush();
};
- // Get and symbolize stack trace
- constexpr size_t kMaxStackTraceDepth = 100;
- FrameArray<kMaxStackTraceDepth> addresses;
// Skip the getStackTrace frame
- if (!getStackTraceSafe(addresses)) {
+ if (!getStackTraceSafe(*addresses_)) {
print("(error retrieving stack trace)\n");
} else if (symbolize) {
// Do our best to populate location info, process is going to terminate,
// so performance isn't critical.
Symbolizer symbolizer(&elfCache_, Dwarf::LocationInfoMode::FULL);
- symbolizer.symbolize(addresses);
+ symbolizer.symbolize(*addresses_);
// Skip the top 2 frames:
// getStackTraceSafe
// StackTracePrinter::printStackTrace (here)
//
// Leaving signalHandler on the stack for clarity, I think.
- printer_.println(addresses, 2);
+ printer_.println(*addresses_, 2);
} else {
print("(safe mode, symbolizer not available)\n");
AddressFormatter formatter;
- for (size_t i = 0; i < addresses.frameCount; ++i) {
- print(formatter.format(addresses.addresses[i]));
+ for (size_t i = 0; i < addresses_->frameCount; ++i) {
+ print(formatter.format(addresses_->addresses[i]));
print("\n");
}
}
}
-} // namespace symbolizer
+
+} // namespace symbolizer
} // namespace folly
class StackTracePrinter {
public:
static constexpr size_t kDefaultMinSignalSafeElfCacheSize = 500;
+
explicit StackTracePrinter(
size_t minSignalSafeElfCacheSize = kDefaultMinSignalSafeElfCacheSize,
int fd = STDERR_FILENO);
void flush();
private:
+ static constexpr size_t kMaxStackTraceDepth = 100;
+
int fd_;
SignalSafeElfCache elfCache_;
FDSymbolizePrinter printer_;
+ std::unique_ptr<FrameArray<kMaxStackTraceDepth>> addresses_;
};
} // namespace symbolizer