This is an archive of the discontinued LLVM Phabricator instance.

Add __no_instrument_function__ to _LIBCPP_INLINE_VISIBILITY and _LIBCPP_ALWAYS_INLINE
AbandonedPublic

Authored by mdaniels on Oct 22 2016, 11:14 AM.

Details

Summary

When using libc++ along with -finstrument-functions I am seeing link errors, even in the simple hello world case.

It looks like this is caused by functions in libc++'s headers that are marked to always be inlined. Since they are always inlined there is external definition for the linker to get the address of. I have worked around this by adding the no_instrument_function attribute to _LIBCPP_INLINE_VISIBILITY and _LIBCPP_ALWAYS_INLINE.

It looks like this was report with PR17879 but author closed it as invalid. So I could very well be missing something here.

Patch tested by running the test suite with -finstrument-functions set in the compiler flags. Link errors were no longer seen and there was no change to the test result when compared to a clean run. The tests were run using a x86_64 Linux host using gcc 5.4 and clang 3.8 with libc++ from ToT, as well as a QNX Neutrino host using gcc 5.4 and libc++ 3.7.

This may also be a problem on Windows as they has similar attributes being set, but I do not have a setup to test that.

Diff Detail

Event Timeline

mdaniels updated this revision to Diff 75531.Oct 22 2016, 11:14 AM
mdaniels retitled this revision from to Add __no_instrument_function__ to _LIBCPP_INLINE_VISIBILITY and _LIBCPP_ALWAYS_INLINE.
mdaniels updated this object.
mdaniels added reviewers: EricWF, mclow.lists.
EricWF edited edge metadata.Oct 23 2016, 11:59 AM

Could you please point me to the documentation regarding -finstrument-function?

mdaniels edited edge metadata.Nov 2 2016, 9:36 AM
mdaniels added a subscriber: cfe-commits.
EricWF added a comment.Nov 4 2016, 7:03 PM

It looks like this is caused by functions in libc++'s headers that are marked to always be inlined. Since they are always inlined there is external definition for the linker to get the address of. I have worked around this by adding the no_instrument_function attribute to _LIBCPP_INLINE_VISIBILITY and _LIBCPP_ALWAYS_INLINE.

That isn't quite correct. This problem only occurs on methods which are externally instantiated withing the dylib but there definitions are marked __attribute__((visibility("hidden"))).
For example std::string and std::num_get. Therefore the compiler *knows* there is an externally available definition but its hidden from the linker.

I would prefer to fix this by using _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY on these methods instead of _LIBCPP_INLINE_VISIBILITY or _LIBCPP_ALWAYS_INLINE instead.

EricWF added a comment.Nov 5 2016, 2:51 AM

I created a fix as described above. Could you please tell me if it works for you?

It can be found here:

https://reviews.llvm.org/D26324

mdaniels abandoned this revision.Nov 18 2016, 1:46 PM