Commit 69100695 authored by Lucian Grijincu's avatar Lucian Grijincu Committed by Facebook GitHub Bot

folly: symbolizer: tests: switch from qsort to lfind -- ASAN in LLVM12 adds an...

folly: symbolizer: tests: switch from qsort to lfind -- ASAN in LLVM12 adds an __interceptor_qsort.part.0 which makes stacks differ between ASAN and non-ASAN

Summary:
LLVM 12's ASAN intercepts qsort and adds a new stack frame for the intercetor `__interceptor_qsort.part.0`.

That can be solved by switching offsets between mode/dev & mode/opt, but it only makes tests harder to read.

So switch to `lfind` which also lives in a separate `.so` (feature used in tests), but is simple enough that ASAN doesn't need to intercept it.

Differential Revision: D30665575

fbshipit-source-id: ba540aede33c37bea8e1f4777bd7325699f9a8d2
parent 490b287c
...@@ -32,7 +32,7 @@ using namespace folly::symbolizer::test; ...@@ -32,7 +32,7 @@ using namespace folly::symbolizer::test;
FOLLY_NOINLINE void lexicalBlockBar() try { FOLLY_NOINLINE void lexicalBlockBar() try {
size_t unused = 0; size_t unused = 0;
unused++; unused++;
inlineB_inlineA_qsort(); inlineB_inlineA_lfind();
} catch (...) { } catch (...) {
folly::assume_unreachable(); folly::assume_unreachable();
} }
...@@ -45,7 +45,7 @@ void run(LocationInfoMode mode, size_t n) { ...@@ -45,7 +45,7 @@ void run(LocationInfoMode mode, size_t n) {
gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>; gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>;
lexicalBlockBar(); lexicalBlockBar();
symbolizer.symbolize(frames); symbolizer.symbolize(frames);
// The address of the line where lexicalBlockBar calls inlineB_inlineA_qsort. // The address of the line where lexicalBlockBar calls inlineB_inlineA_lfind.
uintptr_t address = frames.frames[7].addr; uintptr_t address = frames.frames[7].addr;
ElfFile elf("/proc/self/exe"); ElfFile elf("/proc/self/exe");
......
...@@ -40,8 +40,10 @@ void foo() {} ...@@ -40,8 +40,10 @@ void foo() {}
FOLLY_NOINLINE void bar() { FOLLY_NOINLINE void bar() {
std::array<int, 2> a = {{1, 2}}; std::array<int, 2> a = {{1, 2}};
// Use qsort, which is in a different library // Use lfind, which is in a different library
qsort(a.data(), 2, sizeof(int), testComparator); int key = 1;
unsigned long nmemb = 2;
lfind(&key, a.data(), &nmemb, sizeof(int), testComparator);
} }
TEST(Symbolizer, Single) { TEST(Symbolizer, Single) {
...@@ -180,35 +182,35 @@ TEST(SymbolizerTest, InlineFunctionBasic) { ...@@ -180,35 +182,35 @@ TEST(SymbolizerTest, InlineFunctionBasic) {
FrameArray<100> frames; FrameArray<100> frames;
gComparatorGetStackTraceArg = &frames; gComparatorGetStackTraceArg = &frames;
gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>; gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>;
call_inlineB_inlineA_qsort(); call_inlineB_inlineA_lfind();
symbolizer.symbolize(frames); symbolizer.symbolize(frames);
expectFrameEq( expectFrameEq(
frames.frames[5], frames.frames[4],
"inlineA_qsort", "inlineA_lfind",
"folly::symbolizer::test::inlineA_qsort()", "folly::symbolizer::test::inlineA_lfind()",
"folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h", "folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h",
kLineno_qsort); kLineno_lfind);
expectFrameEq( expectFrameEq(
frames.frames[6], frames.frames[5],
"inlineB_inlineA_qsort", "inlineB_inlineA_lfind",
"folly::symbolizer::test::inlineB_inlineA_qsort()", "folly::symbolizer::test::inlineB_inlineA_lfind()",
"folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h", "folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h",
kLineno_inlineA_qsort); kLineno_inlineA_lfind);
FrameArray<100> frames2; FrameArray<100> frames2;
gComparatorGetStackTraceArg = &frames2; gComparatorGetStackTraceArg = &frames2;
gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>; gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>;
call_inlineB_inlineA_qsort(); call_inlineB_inlineA_lfind();
symbolizer.symbolize(frames2); symbolizer.symbolize(frames2);
expectFramesEq(frames, frames2); expectFramesEq(frames, frames2);
} }
FOLLY_NOINLINE void call_B_A_qsort() { FOLLY_NOINLINE void call_B_A_lfind() {
kLineno_inlineB_inlineA_qsort = __LINE__ + 1; kLineno_inlineB_inlineA_lfind = __LINE__ + 1;
inlineB_inlineA_qsort(); inlineB_inlineA_lfind();
} }
TEST(SymbolizerTest, InlineFunctionWithoutEnoughFrames) { TEST(SymbolizerTest, InlineFunctionWithoutEnoughFrames) {
...@@ -219,28 +221,28 @@ TEST(SymbolizerTest, InlineFunctionWithoutEnoughFrames) { ...@@ -219,28 +221,28 @@ TEST(SymbolizerTest, InlineFunctionWithoutEnoughFrames) {
FrameArray<100> frames; FrameArray<100> frames;
gComparatorGetStackTraceArg = &frames; gComparatorGetStackTraceArg = &frames;
gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>; gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>;
call_B_A_qsort(); call_B_A_lfind();
symbolizer.symbolize(frames); symbolizer.symbolize(frames);
std::array<SymbolizedFrame, 2> limitedFrames; std::array<SymbolizedFrame, 2> limitedFrames;
// The address of the line where call_B_A_qsort calls inlineB_inlineA_qsort. // The address of the line where call_B_A_lfind calls inlineB_inlineA_lfind.
symbolizer.symbolize( symbolizer.symbolize(
folly::Range<const uintptr_t*>(&frames.addresses[5], 1), folly::Range<const uintptr_t*>(&frames.addresses[4], 1),
folly::range(limitedFrames)); folly::range(limitedFrames));
expectFrameEq( expectFrameEq(
limitedFrames[0], limitedFrames[0],
"inlineB_inlineA_qsort", "inlineB_inlineA_lfind",
"folly::symbolizer::test::inlineB_inlineA_qsort()", "folly::symbolizer::test::inlineB_inlineA_lfind()",
"folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h", "folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h",
kLineno_inlineA_qsort); kLineno_inlineA_lfind);
expectFrameEq( expectFrameEq(
limitedFrames[1], limitedFrames[1],
"call_B_A_qsort", "call_B_A_lfind",
"folly::symbolizer::test::call_B_A_qsort()", "folly::symbolizer::test::call_B_A_lfind()",
"folly/experimental/symbolizer/test/SymbolizerTest.cpp", "folly/experimental/symbolizer/test/SymbolizerTest.cpp",
kLineno_inlineB_inlineA_qsort); kLineno_inlineB_inlineA_lfind);
} }
TEST(SymbolizerTest, InlineFunctionInLexicalBlock) { TEST(SymbolizerTest, InlineFunctionInLexicalBlock) {
...@@ -251,29 +253,29 @@ TEST(SymbolizerTest, InlineFunctionInLexicalBlock) { ...@@ -251,29 +253,29 @@ TEST(SymbolizerTest, InlineFunctionInLexicalBlock) {
FrameArray<100> frames; FrameArray<100> frames;
gComparatorGetStackTraceArg = &frames; gComparatorGetStackTraceArg = &frames;
gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>; gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>;
call_lexicalBlock_inlineB_inlineA_qsort(); call_lexicalBlock_inlineB_inlineA_lfind();
symbolizer.symbolize(frames); symbolizer.symbolize(frames);
expectFrameEq( expectFrameEq(
frames.frames[5], frames.frames[4],
"inlineA_qsort", "inlineA_lfind",
"folly::symbolizer::test::inlineA_qsort()", "folly::symbolizer::test::inlineA_lfind()",
"folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h", "folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h",
kLineno_qsort); kLineno_lfind);
expectFrameEq( expectFrameEq(
frames.frames[6], frames.frames[5],
"inlineB_inlineA_qsort", "inlineB_inlineA_lfind",
"folly::symbolizer::test::inlineB_inlineA_qsort()", "folly::symbolizer::test::inlineB_inlineA_lfind()",
"folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h", "folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h",
kLineno_inlineA_qsort); kLineno_inlineA_lfind);
expectFrameEq( expectFrameEq(
frames.frames[7], frames.frames[6],
"lexicalBlock_inlineB_inlineA_qsort", "lexicalBlock_inlineB_inlineA_lfind",
"folly::symbolizer::test::lexicalBlock_inlineB_inlineA_qsort()", "folly::symbolizer::test::lexicalBlock_inlineB_inlineA_lfind()",
"folly/experimental/symbolizer/test/SymbolizerTestUtils.cpp", "folly/experimental/symbolizer/test/SymbolizerTestUtils.cpp",
kLineno_inlineB_inlineA_qsort); kLineno_inlineB_inlineA_lfind);
} }
TEST(SymbolizerTest, InlineFunctionInDifferentCompilationUnit) { TEST(SymbolizerTest, InlineFunctionInDifferentCompilationUnit) {
...@@ -284,16 +286,16 @@ TEST(SymbolizerTest, InlineFunctionInDifferentCompilationUnit) { ...@@ -284,16 +286,16 @@ TEST(SymbolizerTest, InlineFunctionInDifferentCompilationUnit) {
FrameArray<100> frames; FrameArray<100> frames;
gComparatorGetStackTraceArg = &frames; gComparatorGetStackTraceArg = &frames;
gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>; gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>;
// NOTE: inlineLTO_inlineA_qsort is only inlined with LTO/ThinLTO. // NOTE: inlineLTO_inlineA_lfind is only inlined with LTO/ThinLTO.
call_inlineLTO_inlineA_qsort(); call_inlineLTO_inlineA_lfind();
symbolizer.symbolize(frames); symbolizer.symbolize(frames);
expectFrameEq( expectFrameEq(
frames.frames[6], frames.frames[5],
"inlineLTO_inlineA_qsort", "inlineLTO_inlineA_lfind",
"folly::symbolizer::test::inlineLTO_inlineA_qsort()", "folly::symbolizer::test::inlineLTO_inlineA_lfind()",
"folly/experimental/symbolizer/test/SymbolizerTestUtils.cpp", "folly/experimental/symbolizer/test/SymbolizerTestUtils.cpp",
kLineno_inlineA_qsort); kLineno_inlineA_lfind);
} }
TEST(SymbolizerTest, InlineClassMemberFunctionSameFile) { TEST(SymbolizerTest, InlineClassMemberFunctionSameFile) {
...@@ -304,22 +306,22 @@ TEST(SymbolizerTest, InlineClassMemberFunctionSameFile) { ...@@ -304,22 +306,22 @@ TEST(SymbolizerTest, InlineClassMemberFunctionSameFile) {
FrameArray<100> frames; FrameArray<100> frames;
gComparatorGetStackTraceArg = &frames; gComparatorGetStackTraceArg = &frames;
gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>; gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>;
call_same_file_memberInline_inlineA_qsort(); call_same_file_memberInline_inlineA_lfind();
symbolizer.symbolize(frames); symbolizer.symbolize(frames);
expectFrameEq( expectFrameEq(
frames.frames[5], frames.frames[4],
"inlineA_qsort", "inlineA_lfind",
"folly::symbolizer::test::inlineA_qsort()", "folly::symbolizer::test::inlineA_lfind()",
"folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h", "folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h",
kLineno_qsort); kLineno_lfind);
expectFrameEq( expectFrameEq(
frames.frames[6], frames.frames[5],
"memberInline_inlineA_qsort", "memberInline_inlineA_lfind",
"folly::symbolizer::test::ClassSameFile::memberInline_inlineA_qsort() const", "folly::symbolizer::test::ClassSameFile::memberInline_inlineA_lfind() const",
"folly/experimental/symbolizer/test/SymbolizerTestUtils.cpp", "folly/experimental/symbolizer/test/SymbolizerTestUtils.cpp",
kLineno_inlineA_qsort); kLineno_inlineA_lfind);
} }
TEST(SymbolizerTest, StaticInlineClassMemberFunctionSameFile) { TEST(SymbolizerTest, StaticInlineClassMemberFunctionSameFile) {
...@@ -330,22 +332,22 @@ TEST(SymbolizerTest, StaticInlineClassMemberFunctionSameFile) { ...@@ -330,22 +332,22 @@ TEST(SymbolizerTest, StaticInlineClassMemberFunctionSameFile) {
FrameArray<100> frames; FrameArray<100> frames;
gComparatorGetStackTraceArg = &frames; gComparatorGetStackTraceArg = &frames;
gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>; gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>;
call_same_file_staticMemberInline_inlineA_qsort(); call_same_file_staticMemberInline_inlineA_lfind();
symbolizer.symbolize(frames); symbolizer.symbolize(frames);
expectFrameEq( expectFrameEq(
frames.frames[5], frames.frames[4],
"inlineA_qsort", "inlineA_lfind",
"folly::symbolizer::test::inlineA_qsort()", "folly::symbolizer::test::inlineA_lfind()",
"folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h", "folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h",
kLineno_qsort); kLineno_lfind);
expectFrameEq( expectFrameEq(
frames.frames[6], frames.frames[5],
"staticMemberInline_inlineA_qsort", "staticMemberInline_inlineA_lfind",
"folly::symbolizer::test::ClassSameFile::staticMemberInline_inlineA_qsort()", "folly::symbolizer::test::ClassSameFile::staticMemberInline_inlineA_lfind()",
"folly/experimental/symbolizer/test/SymbolizerTestUtils.cpp", "folly/experimental/symbolizer/test/SymbolizerTestUtils.cpp",
kLineno_inlineA_qsort); kLineno_inlineA_lfind);
} }
TEST(SymbolizerTest, InlineClassMemberFunctionInDifferentFile) { TEST(SymbolizerTest, InlineClassMemberFunctionInDifferentFile) {
...@@ -356,22 +358,22 @@ TEST(SymbolizerTest, InlineClassMemberFunctionInDifferentFile) { ...@@ -356,22 +358,22 @@ TEST(SymbolizerTest, InlineClassMemberFunctionInDifferentFile) {
FrameArray<100> frames; FrameArray<100> frames;
gComparatorGetStackTraceArg = &frames; gComparatorGetStackTraceArg = &frames;
gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>; gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>;
call_different_file_memberInline_inlineA_qsort(); call_different_file_memberInline_inlineA_lfind();
symbolizer.symbolize(frames); symbolizer.symbolize(frames);
expectFrameEq( expectFrameEq(
frames.frames[5], frames.frames[4],
"inlineA_qsort", "inlineA_lfind",
"folly::symbolizer::test::inlineA_qsort()", "folly::symbolizer::test::inlineA_lfind()",
"folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h", "folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h",
kLineno_qsort); kLineno_lfind);
expectFrameEq( expectFrameEq(
frames.frames[6], frames.frames[5],
"memberInline_inlineA_qsort", "memberInline_inlineA_lfind",
"folly::symbolizer::test::ClassDifferentFile::memberInline_inlineA_qsort() const", "folly::symbolizer::test::ClassDifferentFile::memberInline_inlineA_lfind() const",
"folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h", "folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h",
kLineno_inlineA_qsort); kLineno_inlineA_lfind);
} }
TEST(SymbolizerTest, StaticInlineClassMemberFunctionInDifferentFile) { TEST(SymbolizerTest, StaticInlineClassMemberFunctionInDifferentFile) {
...@@ -382,22 +384,22 @@ TEST(SymbolizerTest, StaticInlineClassMemberFunctionInDifferentFile) { ...@@ -382,22 +384,22 @@ TEST(SymbolizerTest, StaticInlineClassMemberFunctionInDifferentFile) {
FrameArray<100> frames; FrameArray<100> frames;
gComparatorGetStackTraceArg = &frames; gComparatorGetStackTraceArg = &frames;
gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>; gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>;
call_different_file_staticMemberInline_inlineA_qsort(); call_different_file_staticMemberInline_inlineA_lfind();
symbolizer.symbolize(frames); symbolizer.symbolize(frames);
expectFrameEq( expectFrameEq(
frames.frames[5], frames.frames[4],
"inlineA_qsort", "inlineA_lfind",
"folly::symbolizer::test::inlineA_qsort()", "folly::symbolizer::test::inlineA_lfind()",
"folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h", "folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h",
kLineno_qsort); kLineno_lfind);
expectFrameEq( expectFrameEq(
frames.frames[6], frames.frames[5],
"staticMemberInline_inlineA_qsort", "staticMemberInline_inlineA_lfind",
"folly::symbolizer::test::ClassDifferentFile::staticMemberInline_inlineA_qsort()", "folly::symbolizer::test::ClassDifferentFile::staticMemberInline_inlineA_lfind()",
"folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h", "folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h",
kLineno_inlineA_qsort); kLineno_inlineA_lfind);
} }
// No inline frames should be filled because of no extra frames. // No inline frames should be filled because of no extra frames.
...@@ -408,14 +410,14 @@ TEST(SymbolizerTest, InlineFunctionBasicNoExtraFrames) { ...@@ -408,14 +410,14 @@ TEST(SymbolizerTest, InlineFunctionBasicNoExtraFrames) {
FrameArray<9> frames; FrameArray<9> frames;
gComparatorGetStackTraceArg = &frames; gComparatorGetStackTraceArg = &frames;
gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<9>; gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<9>;
call_inlineB_inlineA_qsort(); call_inlineB_inlineA_lfind();
symbolizer.symbolize(frames); symbolizer.symbolize(frames);
Symbolizer symbolizer2(nullptr, LocationInfoMode::FULL, 100); Symbolizer symbolizer2(nullptr, LocationInfoMode::FULL, 100);
FrameArray<9> frames2; FrameArray<9> frames2;
gComparatorGetStackTraceArg = &frames2; gComparatorGetStackTraceArg = &frames2;
gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<9>; gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<9>;
call_inlineB_inlineA_qsort(); call_inlineB_inlineA_lfind();
symbolizer2.symbolize(frames2); symbolizer2.symbolize(frames2);
expectFramesEq<9>(frames, frames2); expectFramesEq<9>(frames, frames2);
...@@ -429,27 +431,27 @@ TEST(SymbolizerTest, InlineFunctionWithCache) { ...@@ -429,27 +431,27 @@ TEST(SymbolizerTest, InlineFunctionWithCache) {
FrameArray<100> frames; FrameArray<100> frames;
gComparatorGetStackTraceArg = &frames; gComparatorGetStackTraceArg = &frames;
gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>; gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>;
call_inlineB_inlineA_qsort(); call_inlineB_inlineA_lfind();
symbolizer.symbolize(frames); symbolizer.symbolize(frames);
expectFrameEq( expectFrameEq(
frames.frames[5], frames.frames[4],
"inlineA_qsort", "inlineA_lfind",
"folly::symbolizer::test::inlineA_qsort()", "folly::symbolizer::test::inlineA_lfind()",
"folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h", "folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h",
kLineno_qsort); kLineno_lfind);
expectFrameEq( expectFrameEq(
frames.frames[6], frames.frames[5],
"inlineB_inlineA_qsort", "inlineB_inlineA_lfind",
"folly::symbolizer::test::inlineB_inlineA_qsort()", "folly::symbolizer::test::inlineB_inlineA_lfind()",
"folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h", "folly/experimental/symbolizer/test/SymbolizerTestUtils-inl.h",
kLineno_inlineA_qsort); kLineno_inlineA_lfind);
FrameArray<100> frames2; FrameArray<100> frames2;
gComparatorGetStackTraceArg = &frames2; gComparatorGetStackTraceArg = &frames2;
gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>; gComparatorGetStackTrace = (bool (*)(void*))getStackTrace<100>;
call_inlineB_inlineA_qsort(); call_inlineB_inlineA_lfind();
symbolizer.symbolize(frames2); symbolizer.symbolize(frames2);
expectFramesEq(frames, frames2); expectFramesEq(frames, frames2);
} }
......
...@@ -22,11 +22,13 @@ ...@@ -22,11 +22,13 @@
extern "C" { extern "C" {
// Fwd declare instead of #include <stdlib.h> to minimize generated DWARF. // Fwd declare instead of #include <stdlib.h> to minimize generated DWARF.
void qsort( void* lfind(
void* base, const void* key,
unsigned long nmemb, const void* base,
unsigned long* nmemb,
unsigned long size, unsigned long size,
int (*compar)(const void*, const void*)); int (*compar)(const void*, const void*));
} // "C" } // "C"
namespace folly { namespace folly {
...@@ -38,28 +40,30 @@ namespace test { ...@@ -38,28 +40,30 @@ namespace test {
* cases that define and declare inline functions in different files. * cases that define and declare inline functions in different files.
*/ */
__attribute__((__always_inline__)) inline void inlineA_qsort() { __attribute__((__always_inline__)) inline void inlineA_lfind() {
int a[2] = {1, 2}; int a[2] = {1, 2};
// Use qsort, which is in a different library // Use lfind, which is in a different library
kLineno_qsort = __LINE__ + 1; int key = 1;
qsort(a, 2, sizeof(int), testComparator); unsigned long nmemb = 2;
kLineno_lfind = __LINE__ + 1;
lfind(&key, a, &nmemb, sizeof(int), testComparator);
} }
__attribute__((__always_inline__)) inline void inlineB_inlineA_qsort() { __attribute__((__always_inline__)) inline void inlineB_inlineA_lfind() {
kLineno_inlineA_qsort = __LINE__ + 1; kLineno_inlineA_lfind = __LINE__ + 1;
inlineA_qsort(); inlineA_lfind();
} }
__attribute__((__always_inline__)) inline void __attribute__((__always_inline__)) inline void
ClassDifferentFile::memberInline_inlineA_qsort() const { ClassDifferentFile::memberInline_inlineA_lfind() const {
kLineno_inlineA_qsort = __LINE__ + 1; kLineno_inlineA_lfind = __LINE__ + 1;
inlineA_qsort(); inlineA_lfind();
} }
/* static */ __attribute__((__always_inline__)) inline void /* static */ __attribute__((__always_inline__)) inline void
ClassDifferentFile::staticMemberInline_inlineA_qsort() { ClassDifferentFile::staticMemberInline_inlineA_lfind() {
kLineno_inlineA_qsort = __LINE__ + 1; kLineno_inlineA_lfind = __LINE__ + 1;
inlineA_qsort(); inlineA_lfind();
} }
} // namespace test } // namespace test
......
...@@ -27,80 +27,83 @@ void* gComparatorGetStackTraceArg = nullptr; ...@@ -27,80 +27,83 @@ void* gComparatorGetStackTraceArg = nullptr;
int testComparator(const void* ap, const void* bp) { int testComparator(const void* ap, const void* bp) {
// This comparator is called for the side effect of capturing the stack trace. // This comparator is called for the side effect of capturing the stack trace.
// The function that calls it: qsort usually lives in a separate library - // The function that calls it: lfind usually lives in a separate library -
// which exercises cross-ELF file support. // which exercises cross-ELF file support.
(*gComparatorGetStackTrace)(gComparatorGetStackTraceArg); (*gComparatorGetStackTrace)(gComparatorGetStackTraceArg);
int a = *static_cast<const int*>(ap); int a = *static_cast<const int*>(ap);
int b = *static_cast<const int*>(bp); int b = *static_cast<const int*>(bp);
return a < b ? -1 : a > b ? 1 : 0; // which returns zero if the key object matches the array member, and nonzero
// otherwise.
return (a == b) ? 0 : 1;
// return a < b ? -1 : a > b ? 1 : 0;
} }
int kLineno_qsort = 0; int kLineno_lfind = 0;
int kLineno_inlineA_qsort = 0; int kLineno_inlineA_lfind = 0;
int kLineno_inlineB_inlineA_qsort = 0; int kLineno_inlineB_inlineA_lfind = 0;
// NOTE: inlineLTO_inlineA_qsort is only inlined with LTO/ThinLTO. // NOTE: inlineLTO_inlineA_lfind is only inlined with LTO/ThinLTO.
void inlineLTO_inlineA_qsort() { void inlineLTO_inlineA_lfind() {
kLineno_inlineA_qsort = __LINE__ + 1; kLineno_inlineA_lfind = __LINE__ + 1;
inlineA_qsort(); inlineA_lfind();
} }
void call_inlineA_qsort() { void call_inlineA_lfind() {
inlineA_qsort(); inlineA_lfind();
} }
void call_inlineB_inlineA_qsort() { void call_inlineB_inlineA_lfind() {
inlineB_inlineA_qsort(); inlineB_inlineA_lfind();
} }
void call_inlineLTO_inlineA_qsort() { void call_inlineLTO_inlineA_lfind() {
inlineLTO_inlineA_qsort(); inlineLTO_inlineA_lfind();
} }
class ClassSameFile { class ClassSameFile {
public: public:
__attribute__((__always_inline__)) void memberInline_inlineA_qsort() const { __attribute__((__always_inline__)) void memberInline_inlineA_lfind() const {
kLineno_inlineA_qsort = __LINE__ + 1; kLineno_inlineA_lfind = __LINE__ + 1;
inlineA_qsort(); inlineA_lfind();
} }
__attribute__((__always_inline__)) static void __attribute__((__always_inline__)) static void
staticMemberInline_inlineA_qsort() { staticMemberInline_inlineA_lfind() {
kLineno_inlineA_qsort = __LINE__ + 1; kLineno_inlineA_lfind = __LINE__ + 1;
inlineA_qsort(); inlineA_lfind();
} }
int dummy() const { return dummy_; } int dummy() const { return dummy_; }
int dummy_ = 0; int dummy_ = 0;
}; };
void call_same_file_memberInline_inlineA_qsort() { void call_same_file_memberInline_inlineA_lfind() {
ClassSameFile obj; ClassSameFile obj;
obj.memberInline_inlineA_qsort(); obj.memberInline_inlineA_lfind();
} }
void call_same_file_staticMemberInline_inlineA_qsort() { void call_same_file_staticMemberInline_inlineA_lfind() {
ClassSameFile::staticMemberInline_inlineA_qsort(); ClassSameFile::staticMemberInline_inlineA_lfind();
} }
void call_different_file_memberInline_inlineA_qsort() { void call_different_file_memberInline_inlineA_lfind() {
ClassDifferentFile obj; ClassDifferentFile obj;
obj.memberInline_inlineA_qsort(); obj.memberInline_inlineA_lfind();
} }
void call_different_file_staticMemberInline_inlineA_qsort() { void call_different_file_staticMemberInline_inlineA_lfind() {
ClassDifferentFile::staticMemberInline_inlineA_qsort(); ClassDifferentFile::staticMemberInline_inlineA_lfind();
} }
void lexicalBlock_inlineB_inlineA_qsort() try { void lexicalBlock_inlineB_inlineA_lfind() try {
kLineno_inlineB_inlineA_qsort = __LINE__ + 1; kLineno_inlineB_inlineA_lfind = __LINE__ + 1;
inlineB_inlineA_qsort(); inlineB_inlineA_lfind();
} catch (...) { } catch (...) {
} }
void call_lexicalBlock_inlineB_inlineA_qsort() { void call_lexicalBlock_inlineB_inlineA_lfind() {
lexicalBlock_inlineB_inlineA_qsort(); lexicalBlock_inlineB_inlineA_lfind();
} }
} // namespace test } // namespace test
......
...@@ -29,34 +29,34 @@ extern void* gComparatorGetStackTraceArg; ...@@ -29,34 +29,34 @@ extern void* gComparatorGetStackTraceArg;
int testComparator(const void* ap, const void* bp); int testComparator(const void* ap, const void* bp);
// Set to the line number in the caller function when calling // Set to the line number in the caller function when calling
// qsort/inlineA_qsort/inlineB_inlineA_qsort. // lfind/inlineA_lfind/inlineB_inlineA_lfind.
extern int kLineno_qsort; extern int kLineno_lfind;
extern int kLineno_inlineA_qsort; extern int kLineno_inlineA_lfind;
extern int kLineno_inlineB_inlineA_qsort; extern int kLineno_inlineB_inlineA_lfind;
// Debug Info for inlined functions is emitted in the functions where they're // Debug Info for inlined functions is emitted in the functions where they're
// inlined in. The SymbolizeTest.o object file has many dependencies and will // inlined in. The SymbolizeTest.o object file has many dependencies and will
// have a huge amount of debug info. To simplify debugging call inlined // have a huge amount of debug info. To simplify debugging call inlined
// functions through these trampolines so that all debug info worth inspecting // functions through these trampolines so that all debug info worth inspecting
// is emitted in the tiny SymbolizerTestUtils.o // is emitted in the tiny SymbolizerTestUtils.o
void call_inlineA_qsort(); void call_inlineA_lfind();
void call_inlineB_inlineA_qsort(); void call_inlineB_inlineA_lfind();
void call_inlineLTO_inlineA_qsort(); void call_inlineLTO_inlineA_lfind();
void call_same_file_memberInline_inlineA_qsort(); void call_same_file_memberInline_inlineA_lfind();
void call_same_file_staticMemberInline_inlineA_qsort(); void call_same_file_staticMemberInline_inlineA_lfind();
void call_different_file_memberInline_inlineA_qsort(); void call_different_file_memberInline_inlineA_lfind();
void call_different_file_staticMemberInline_inlineA_qsort(); void call_different_file_staticMemberInline_inlineA_lfind();
void call_lexicalBlock_inlineB_inlineA_qsort(); void call_lexicalBlock_inlineB_inlineA_lfind();
// NOTE: inlineLTO_inlineA_qsort is only inlined with LTO/ThinLTO. // NOTE: inlineLTO_inlineA_lfind is only inlined with LTO/ThinLTO.
void inlineLTO_inlineA_qsort(); void inlineLTO_inlineA_lfind();
class ClassDifferentFile { class ClassDifferentFile {
public: public:
__attribute__((__always_inline__)) inline void memberInline_inlineA_qsort() __attribute__((__always_inline__)) inline void memberInline_inlineA_lfind()
const; const;
__attribute__((__always_inline__)) inline static void __attribute__((__always_inline__)) inline static void
staticMemberInline_inlineA_qsort(); staticMemberInline_inlineA_lfind();
int dummy() const { return dummy_; } int dummy() const { return dummy_; }
int dummy_ = 0; int dummy_ = 0;
......
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