This is an archive of the discontinued LLVM Phabricator instance.

sanitizer_common: allow multiple GET_CURRENT_PC() in a function
ClosedPublic

Authored by dvyukov on Jul 15 2021, 9:45 AM.

Details

Reviewers
vitalybuka
melver
Summary

Currently if GET_CURRENT_PC() is used multiple times
in a single function, it will cause duplicate this_pc
label errors.
Append line number to the this_pc label to this fix.

This fixes existing build breakages on mac:
http://45.33.8.238/macm1/14037/step_4.txt

Diff Detail

Event Timeline

dvyukov requested review of this revision.Jul 15 2021, 9:45 AM
dvyukov created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptJul 15 2021, 9:45 AM
Herald added a subscriber: Restricted Project. · View Herald Transcript
melver accepted this revision.Jul 15 2021, 9:52 AM
melver added inline comments.
compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h
234

This is fine, given it's internal and is simple.

But, just wondering, wouldn't an always_inline function not have this problem? Or would it not work for this usecase?

This revision is now accepted and ready to land.Jul 15 2021, 9:52 AM
dvyukov updated this revision to Diff 359027.Jul 15 2021, 9:55 AM

actually append LINE
the previous version resulted in this_pcLINE

dvyukov added inline comments.Jul 15 2021, 9:59 AM
compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h
234

It's actually not that simple. The previous version was broken and resulted in this_pcLINE. This new version works.

An inline function may increase chances of additional inline frames. But it seems that we will need to filter them out anyway (I already see 2 other bot failures related to inline functions). And if we filter them out, it will be easy to filter out an inline function used in GET_CURRENT_PC as well.

dvyukov updated this revision to Diff 359045.Jul 15 2021, 10:35 AM

change GET_CURRENT_PC to StackTrace::GetCurrentPcFast

dvyukov added inline comments.Jul 15 2021, 10:46 AM
compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h
234

Switched to a function. It's indeed nicer.

But the function indeed shows up on top of most frames, so we need https://reviews.llvm.org/D106081 first or all tests fail.

dvyukov added inline comments.Jul 15 2021, 10:48 AM
compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h
234

Wait, no, I rebased this on top of https://reviews.llvm.org/D106081 and it works with gcc now.
But all tests still fail with clang because... drumroll... clang fails to inline ALWAYS_INLINE function and inserts a call:

4493f1:       e8 fa f9 ff ff          callq  448df0 <_ZN11__sanitizer10StackTrace16GetCurrentPcFastEv>
4493f9:       48 89 c6                mov    %rax,%rsi

and this top frame is completely removed by D106081, so we end up without top frame at all...

melver added inline comments.Jul 15 2021, 11:08 AM
compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h
79

Perhaps this is missing an ALWAYS_INLINE to make Clang play nice?

dvyukov added inline comments.Jul 15 2021, 11:44 AM
compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h
79

No, it doesn't help.
I suspect clang does not want to inline functions with addresses of labels taken, otherwise why wouldn't it inline a function that results in a single instruction even w/o inline?

I don't have any other ideas besides reverting to macro...

vitalybuka added inline comments.Jul 15 2021, 11:46 AM
compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cpp
268

Should you rather duplicate the test for Fast version?

dvyukov updated this revision to Diff 359075.Jul 15 2021, 11:48 AM

revert back to GET_CURRENT_PC() macro

dvyukov updated this revision to Diff 359076.Jul 15 2021, 11:51 AM

duplicated test for GET_CURRENT_PC

compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cpp
268

Done. PTAL.

vitalybuka accepted this revision.Jul 15 2021, 12:03 PM
vitalybuka added inline comments.
compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h
145

Why not __builtin_return_address(0) ?
Is this because it's wrong if inlined?

compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cpp
272

can you also add a test like

a= GetCurrentPcFast()
b= GetCurrentPcFast()
c= GetCurrentPcFast()
EXPECT_NE(a,b);
EXPECT_NE(b,c);

dvyukov closed this revision.Jul 16 2021, 10:00 AM

The new version in https://reviews.llvm.org/D106046 amends this as well.

compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h
145

__builtin_return_address(0) is _caller_ PC and we want _current_ PC.

compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cpp
272

The new version in https://reviews.llvm.org/D106046 includes this test.