Commit a55266f1 authored by Matt Ma's avatar Matt Ma Committed by Facebook GitHub Bot

Change symbolize function to return the actual used frame count.

Summary:
If inline functions are enabled, actual frames used can be larger than the
address count.

Reviewed By: luciang

Differential Revision: D21371112

fbshipit-source-id: c1e602b62b6af427f11701bf25894a99f554ec47
parent e844b95a
...@@ -34,10 +34,10 @@ ...@@ -34,10 +34,10 @@
#include <folly/Memory.h> #include <folly/Memory.h>
#include <folly/ScopeGuard.h> #include <folly/ScopeGuard.h>
#include <folly/String.h> #include <folly/String.h>
#include <folly/experimental/symbolizer/Dwarf.h> #include <folly/experimental/symbolizer/Dwarf.h>
#include <folly/experimental/symbolizer/Elf.h> #include <folly/experimental/symbolizer/Elf.h>
#include <folly/experimental/symbolizer/LineReader.h> #include <folly/experimental/symbolizer/LineReader.h>
#include <folly/lang/SafeAssert.h>
#include <folly/portability/SysMman.h> #include <folly/portability/SysMman.h>
#include <folly/portability/Unistd.h> #include <folly/portability/Unistd.h>
...@@ -94,33 +94,23 @@ Symbolizer::Symbolizer( ...@@ -94,33 +94,23 @@ Symbolizer::Symbolizer(
} }
} }
void Symbolizer::symbolize( size_t Symbolizer::symbolize(
folly::Range<const uintptr_t*> addrs, folly::Range<const uintptr_t*> addrs,
folly::Range<SymbolizedFrame*> frames) { folly::Range<SymbolizedFrame*> frames) {
size_t addrCount = addrs.size(); size_t addrCount = addrs.size();
size_t frameCount = frames.size(); size_t frameCount = frames.size();
size_t remaining = 0; FOLLY_SAFE_CHECK(addrCount <= frameCount, "Not enough frames.");
for (size_t i = 0; i < addrCount; ++i) { size_t remaining = addrCount;
auto& frame = frames[i];
if (!frame.found) {
++remaining;
frame.clear();
}
}
if (remaining == 0) { // we're done
return;
}
if (_r_debug.r_version != 1) { if (_r_debug.r_version != 1) {
return; return 0;
} }
char selfPath[PATH_MAX + 8]; char selfPath[PATH_MAX + 8];
ssize_t selfSize; ssize_t selfSize;
if ((selfSize = readlink("/proc/self/exe", selfPath, PATH_MAX + 1)) == -1) { if ((selfSize = readlink("/proc/self/exe", selfPath, PATH_MAX + 1)) == -1) {
// Something has gone terribly wrong. // Something has gone terribly wrong.
return; return 0;
} }
selfPath[selfSize] = '\0'; selfPath[selfSize] = '\0';
...@@ -230,6 +220,8 @@ void Symbolizer::symbolize( ...@@ -230,6 +220,8 @@ void Symbolizer::symbolize(
} }
} }
} }
return addrCount;
} }
namespace { namespace {
......
...@@ -98,32 +98,32 @@ class Symbolizer { ...@@ -98,32 +98,32 @@ class Symbolizer {
size_t symbolCacheSize = 0); size_t symbolCacheSize = 0);
/** /**
* Symbolize given addresses. * Symbolize given addresses and return the number of @frames filled:
* *
* - all entries in @addrs will be symbolized (if possible, e.g. if they're * - all entries in @addrs will be symbolized (if possible, e.g. if they're
* valid code addresses) * valid code addresses and if frames.size() >= addrs.size())
* *
* - if `mode_ == FULL_WITH_INLINE` and `frames.size() > addrs.size()` then at * - if `mode_ == FULL_WITH_INLINE` and `frames.size() > addrs.size()` then at
* most `frames.size() - addrs.size()` additional inlined functions will * most `frames.size() - addrs.size()` additional inlined functions will
* also be symbolized (at most `kMaxInlineLocationInfoPerFrame` per @addr * also be symbolized (at most `kMaxInlineLocationInfoPerFrame` per @addr
* entry). * entry).
*/ */
void symbolize( size_t symbolize(
folly::Range<const uintptr_t*> addrs, folly::Range<const uintptr_t*> addrs,
folly::Range<SymbolizedFrame*> frames); folly::Range<SymbolizedFrame*> frames);
void symbolize( size_t symbolize(
const uintptr_t* addresses, const uintptr_t* addresses,
SymbolizedFrame* frames, SymbolizedFrame* frames,
size_t frameCount) { size_t frameCount) {
symbolize( return symbolize(
folly::Range<const uintptr_t*>(addresses, frameCount), folly::Range<const uintptr_t*>(addresses, frameCount),
folly::Range<SymbolizedFrame*>(frames, frameCount)); folly::Range<SymbolizedFrame*>(frames, frameCount));
} }
template <size_t N> template <size_t N>
void symbolize(FrameArray<N>& fa) { size_t symbolize(FrameArray<N>& fa) {
symbolize( return symbolize(
folly::Range<const uintptr_t*>(fa.addresses, fa.frameCount), folly::Range<const uintptr_t*>(fa.addresses, fa.frameCount),
folly::Range<SymbolizedFrame*>(fa.frames, N)); folly::Range<SymbolizedFrame*>(fa.frames, N));
} }
......
...@@ -134,6 +134,7 @@ FOLLY_NOINLINE void lexicalBlockBar(FrameArray<kNumFrames>& frames) try { ...@@ -134,6 +134,7 @@ FOLLY_NOINLINE void lexicalBlockBar(FrameArray<kNumFrames>& frames) try {
} }
void verifyStackTrace( void verifyStackTrace(
Symbolizer& symbolizer,
const FrameArray<100>& frames, const FrameArray<100>& frames,
const std::string& barName, const std::string& barName,
size_t barLine, size_t barLine,
...@@ -149,6 +150,12 @@ void verifyStackTrace( ...@@ -149,6 +150,12 @@ void verifyStackTrace(
EXPECT_EQ(barName, std::string(folly::demangle(frames.frames[6].name))); EXPECT_EQ(barName, std::string(folly::demangle(frames.frames[6].name)));
EXPECT_EQ(barFile, std::string(frames.frames[6].location.file.toString())); EXPECT_EQ(barFile, std::string(frames.frames[6].location.file.toString()));
EXPECT_EQ(barLine, frames.frames[6].location.line); EXPECT_EQ(barLine, frames.frames[6].location.line);
FrameArray<10> singleAddressFrames;
singleAddressFrames.frameCount = 1;
singleAddressFrames.addresses[0] = frames.frames[7].addr;
// Two inline function calls are added into frames.
EXPECT_EQ(3, symbolizer.symbolize(singleAddressFrames));
} }
template <size_t kNumFrames = 100> template <size_t kNumFrames = 100>
...@@ -208,6 +215,7 @@ TEST(SymbolizerTest, InlineFunctionBasic) { ...@@ -208,6 +215,7 @@ TEST(SymbolizerTest, InlineFunctionBasic) {
// Frame: _ZN7testing8internal12UnitTestImpl11RunAllTestsEv // Frame: _ZN7testing8internal12UnitTestImpl11RunAllTestsEv
// clang-format on // clang-format on
verifyStackTrace( verifyStackTrace(
symbolizer,
frames, frames,
"void folly::symbolizer::test::inlineBar<100ul>(" "void folly::symbolizer::test::inlineBar<100ul>("
"folly::symbolizer::FrameArray<100ul>&)", "folly::symbolizer::FrameArray<100ul>&)",
...@@ -261,6 +269,7 @@ TEST(SymbolizerTest, InlineFunctionInLexicalBlock) { ...@@ -261,6 +269,7 @@ TEST(SymbolizerTest, InlineFunctionInLexicalBlock) {
symbolizer.symbolize(frames); symbolizer.symbolize(frames);
verifyStackTrace( verifyStackTrace(
symbolizer,
frames, frames,
"void folly::symbolizer::test::inlineBar<100ul>(" "void folly::symbolizer::test::inlineBar<100ul>("
"folly::symbolizer::FrameArray<100ul>&)", "folly::symbolizer::FrameArray<100ul>&)",
...@@ -304,6 +313,7 @@ TEST(SymbolizerTest, InlineClassMemberFunction) { ...@@ -304,6 +313,7 @@ TEST(SymbolizerTest, InlineClassMemberFunction) {
symbolizer.symbolize(frames); symbolizer.symbolize(frames);
verifyStackTrace( verifyStackTrace(
symbolizer,
frames, frames,
"folly::symbolizer::test::ClassWithInlineFunctions::inlineBar(" "folly::symbolizer::test::ClassWithInlineFunctions::inlineBar("
"folly::symbolizer::FrameArray<100ul>&) const", "folly::symbolizer::FrameArray<100ul>&) const",
...@@ -319,6 +329,7 @@ TEST(SymbolizerTest, StaticInlineClassMemberFunction) { ...@@ -319,6 +329,7 @@ TEST(SymbolizerTest, StaticInlineClassMemberFunction) {
symbolizer.symbolize(frames); symbolizer.symbolize(frames);
verifyStackTrace( verifyStackTrace(
symbolizer,
frames, frames,
"folly::symbolizer::test::ClassWithInlineFunctions::staticInlineBar(" "folly::symbolizer::test::ClassWithInlineFunctions::staticInlineBar("
"folly::symbolizer::FrameArray<100ul>&)", "folly::symbolizer::FrameArray<100ul>&)",
...@@ -335,6 +346,7 @@ TEST(SymbolizerTest, InlineClassMemberFunctionInDifferentFile) { ...@@ -335,6 +346,7 @@ TEST(SymbolizerTest, InlineClassMemberFunctionInDifferentFile) {
symbolizer.symbolize(frames); symbolizer.symbolize(frames);
verifyStackTrace( verifyStackTrace(
symbolizer,
frames, frames,
"folly::symbolizer::test::InlineFunctionsWrapper::inlineBar(" "folly::symbolizer::test::InlineFunctionsWrapper::inlineBar("
"folly::symbolizer::FrameArray<100ul>&) const", "folly::symbolizer::FrameArray<100ul>&) const",
...@@ -350,6 +362,7 @@ TEST(SymbolizerTest, StaticInlineClassMemberFunctionInDifferentFile) { ...@@ -350,6 +362,7 @@ TEST(SymbolizerTest, StaticInlineClassMemberFunctionInDifferentFile) {
symbolizer.symbolize(frames); symbolizer.symbolize(frames);
verifyStackTrace( verifyStackTrace(
symbolizer,
frames, frames,
"folly::symbolizer::test::InlineFunctionsWrapper::staticInlineBar(" "folly::symbolizer::test::InlineFunctionsWrapper::staticInlineBar("
"folly::symbolizer::FrameArray<100ul>&)", "folly::symbolizer::FrameArray<100ul>&)",
...@@ -380,6 +393,7 @@ TEST(SymbolizerTest, InlineFunctionWithCache) { ...@@ -380,6 +393,7 @@ TEST(SymbolizerTest, InlineFunctionWithCache) {
symbolizer.symbolize(frames); symbolizer.symbolize(frames);
verifyStackTrace( verifyStackTrace(
symbolizer,
frames, frames,
"void folly::symbolizer::test::inlineBar<100ul>(" "void folly::symbolizer::test::inlineBar<100ul>("
"folly::symbolizer::FrameArray<100ul>&)", "folly::symbolizer::FrameArray<100ul>&)",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment