Commit ad8ac4d9 authored by Lucian Grijincu's avatar Lucian Grijincu Committed by Facebook Github Bot

Revert D19384064: Support inline class member functions in stack trace.

Differential Revision:
D19384064

Original commit changeset: a2a6397b94aa

fbshipit-source-id: e8ba1e8f6b3c3d3840a912e4c094b570b23ccbcf
parent 96349f7f
......@@ -637,31 +637,9 @@ detail::Die Dwarf::getDieAtOffset(
die.abbr = !cu.abbrCache.empty() && die.code < kMaxAbbreviationEntries
? cu.abbrCache[die.code - 1]
: getAbbreviation(die.code, cu.abbrevOffset);
return die;
}
detail::Die Dwarf::findDefinitionDie(
const detail::CompilationUnit& cu,
const detail::Die& die) const {
// Find the real definition instead of declaration.
folly::Optional<uint64_t> offset;
forEachAttribute(cu, die, [&](const detail::Attribute& attr) {
// Incomplete, non-defining, or separate declaration corresponding to
// a declaration
if (attr.spec.name == DW_AT_specification) {
offset = boost::get<uint64_t>(attr.attrValue);
return false;
}
return true;
});
if (!offset.hasValue()) {
return die;
}
return getDieAtOffset(cu, cu.offset + offset.value());
}
size_t Dwarf::forEachChild(
const detail::CompilationUnit& cu,
const detail::Die& die,
......@@ -720,6 +698,7 @@ void Dwarf::findSubProgramDieForAddress(
uint64_t lowPc = 0;
uint64_t highPc = 0;
bool isHighPcAddr = false;
StringPiece name;
forEachAttribute(cu, childDie, [&](const detail::Attribute& attr) {
switch (attr.spec.name) {
// Here DW_AT_ranges is not supported since it requires looking up
......@@ -733,6 +712,9 @@ void Dwarf::findSubProgramDieForAddress(
isHighPcAddr = (attr.spec.form == DW_FORM_addr);
highPc = boost::get<uint64_t>(attr.attrValue);
break;
case DW_AT_name:
name = boost::get<StringPiece>(attr.attrValue);
break;
}
// Iterate through all attributes until find all above.
return true;
......@@ -802,15 +784,12 @@ void Dwarf::findInlinedSubroutineDieForAddress(
if (originRefType == DW_FORM_ref1 || originRefType == DW_FORM_ref2 ||
originRefType == DW_FORM_ref4 || originRefType == DW_FORM_ref8 ||
originRefType == DW_FORM_ref_udata) {
// Jump to the actual function definition instead of declaration for name
// and line info.
isrLoc[0].die =
findDefinitionDie(cu, getDieAtOffset(cu, cu.offset + origin));
isrLoc[0].die = getDieAtOffset(cu, cu.offset + origin);
isrLoc.advance(1);
findInlinedSubroutineDieForAddress(cu, childDie, address, isrLoc);
} else if (originRefType == DW_FORM_ref_addr) {
auto srcu = findCompilationUnit(debugInfo_, origin);
isrLoc[0].die = findDefinitionDie(cu, getDieAtOffset(cu, origin));
isrLoc[0].die = getDieAtOffset(cu, origin);
isrLoc.advance(1);
findInlinedSubroutineDieForAddress(srcu, childDie, address, isrLoc);
}
......
......@@ -149,13 +149,6 @@ class Dwarf {
detail::Die getDieAtOffset(const detail::CompilationUnit& cu, uint64_t offset)
const;
/**
* Find the actual definition DIE instead of declaration for the given die.
*/
detail::Die findDefinitionDie(
const detail::CompilationUnit& cu,
const detail::Die& die) const;
/**
* Iterates over all children of a debugging info entry, calling the given
* callable for each. Iteration is stopped early if any of the calls return
......
......@@ -134,9 +134,7 @@ TEST(SymbolizerTest, SymbolCache) {
namespace {
size_t kQsortCallLineNo = 0;
size_t kFooCallByStandaloneBarLineNo = 0;
size_t kFooCallByClassBarLineNo = 0;
size_t kFooCallByClassStaticBarLineNo = 0;
size_t kFooCallLineNo = 0;
template <size_t kNumFrames = 100>
FOLLY_ALWAYS_INLINE void inlineFoo(FrameArray<kNumFrames>& frames) {
......@@ -150,59 +148,12 @@ FOLLY_ALWAYS_INLINE void inlineFoo(FrameArray<kNumFrames>& frames) {
template <size_t kNumFrames = 100>
FOLLY_ALWAYS_INLINE void inlineBar(FrameArray<kNumFrames>& frames) {
kFooCallByStandaloneBarLineNo = __LINE__ + 1;
kFooCallLineNo = __LINE__ + 1;
inlineFoo(frames);
}
void verifyStackTrace(
const FrameArray<100>& frames,
const std::string& barName,
size_t barLine) {
EXPECT_TRUE(frames.frameCount == 14 || frames.frameCount == 15);
EXPECT_EQ("inlineFoo<100>", std::string(frames.frames[5].name));
EXPECT_EQ(
"folly/experimental/symbolizer/test/SymbolizerTest.cpp",
std::string(frames.frames[5].location.file.toString()));
EXPECT_EQ(kQsortCallLineNo, frames.frames[5].location.line);
EXPECT_EQ(barName, std::string(frames.frames[6].name));
EXPECT_EQ(
"folly/experimental/symbolizer/test/SymbolizerTest.cpp",
std::string(frames.frames[6].location.file.toString()));
EXPECT_EQ(barLine, frames.frames[6].location.line);
}
template <size_t kNumFrames = 100>
void compareFrames(
const FrameArray<kNumFrames>& frames1,
const FrameArray<kNumFrames>& frames2) {
EXPECT_EQ(frames1.frameCount, frames2.frameCount);
for (size_t i = 0; i < frames1.frameCount; i++) {
EXPECT_STREQ(frames1.frames[i].name, frames2.frames[i].name);
}
}
} // namespace
class ClassWithInlineFunctions {
public:
FOLLY_ALWAYS_INLINE void inlineBar(FrameArray<100>& frames) const {
kFooCallByClassBarLineNo = __LINE__ + 1;
inlineFoo(frames);
}
FOLLY_ALWAYS_INLINE static void staticInlineBar(FrameArray<100>& frames) {
kFooCallByClassStaticBarLineNo = __LINE__ + 1;
inlineFoo(frames);
}
// Dummy non-inline function.
size_t dummy() const {
return dummy_;
}
size_t dummy_ = 0;
};
TEST(SymbolizerTest, InlineFunctionBasic) {
Symbolizer symbolizer(nullptr, LocationInfoMode::FULL_WITH_INLINE, 0);
......@@ -229,34 +180,25 @@ TEST(SymbolizerTest, InlineFunctionBasic) {
// Frame: _ZN7testing8UnitTest3RunEv
// Frame: _Z13RUN_ALL_TESTSv
// clang-format on
verifyStackTrace(frames, "inlineBar<100>", kFooCallByStandaloneBarLineNo);
EXPECT_TRUE(frames.frameCount == 14 || frames.frameCount == 15);
EXPECT_EQ("inlineFoo<100>", std::string(frames.frames[5].name));
EXPECT_EQ(
"folly/experimental/symbolizer/test/SymbolizerTest.cpp",
std::string(frames.frames[5].location.file.toString()));
EXPECT_EQ(kQsortCallLineNo, frames.frames[5].location.line);
EXPECT_EQ("inlineBar<100>", std::string(frames.frames[6].name));
EXPECT_EQ(
"folly/experimental/symbolizer/test/SymbolizerTest.cpp",
std::string(frames.frames[6].location.file.toString()));
EXPECT_EQ(kFooCallLineNo, frames.frames[6].location.line);
FrameArray<100> frames2;
inlineBar<100>(frames2);
symbolizer.symbolize(frames2);
compareFrames(frames, frames2);
}
TEST(SymbolizerTest, InlineClassMemberFunction) {
Symbolizer symbolizer(nullptr, LocationInfoMode::FULL_WITH_INLINE, 0);
FrameArray<100> frames;
ClassWithInlineFunctions obj;
obj.inlineBar(frames);
symbolizer.symbolize(frames);
verifyStackTrace(frames, "inlineBar", kFooCallByClassBarLineNo);
}
TEST(SymbolizerTest, StaticInlineClassMemberFunction) {
Symbolizer symbolizer(nullptr, LocationInfoMode::FULL_WITH_INLINE, 0);
FrameArray<100> frames;
ClassWithInlineFunctions::staticInlineBar(frames);
symbolizer.symbolize(frames);
verifyStackTrace(frames, "staticInlineBar", kFooCallByClassStaticBarLineNo);
EXPECT_EQ(frames.frameCount, frames2.frameCount);
for (size_t i = 0; i < frames.frameCount; i++) {
EXPECT_STREQ(frames.frames[i].name, frames2.frames[i].name);
}
}
// No inline frames should be filled because of no extra frames.
......@@ -271,7 +213,9 @@ TEST(SymbolizerTest, InlineFunctionBasicNoExtraFrames) {
inlineBar<8>(frames2);
symbolizer2.symbolize(frames2);
compareFrames<8>(frames, frames2);
for (size_t i = 0; i < frames.frameCount; i++) {
EXPECT_STREQ(frames.frames[i].name, frames2.frames[i].name);
}
}
TEST(SymbolizerTest, InlineFunctionWithCache) {
......@@ -281,12 +225,25 @@ TEST(SymbolizerTest, InlineFunctionWithCache) {
inlineBar<100>(frames);
symbolizer.symbolize(frames);
verifyStackTrace(frames, "inlineBar<100>", kFooCallByStandaloneBarLineNo);
EXPECT_TRUE(frames.frameCount == 14 || frames.frameCount == 15);
EXPECT_EQ("inlineFoo<100>", std::string(frames.frames[5].name));
EXPECT_EQ(
"folly/experimental/symbolizer/test/SymbolizerTest.cpp",
std::string(frames.frames[5].location.file.toString()));
EXPECT_EQ(kQsortCallLineNo, frames.frames[5].location.line);
EXPECT_EQ("inlineBar<100>", std::string(frames.frames[6].name));
EXPECT_EQ(
"folly/experimental/symbolizer/test/SymbolizerTest.cpp",
std::string(frames.frames[6].location.file.toString()));
EXPECT_EQ(kFooCallLineNo, frames.frames[6].location.line);
FrameArray<100> frames2;
inlineBar<100>(frames2);
symbolizer.symbolize(frames2);
compareFrames(frames, frames2);
EXPECT_EQ(frames.frameCount, frames2.frameCount);
for (size_t i = 0; i < frames.frameCount; i++) {
EXPECT_STREQ(frames.frames[i].name, frames2.frames[i].name);
}
}
} // namespace test
......
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