This is an archive of the discontinued LLVM Phabricator instance.

Correct atexit(3) support in MSan/NetBSD
ClosedPublic

Authored by krytarowski on Dec 1 2017, 4:23 AM.

Details

Summary

The NetBSD specific implementation of cxa_atexit() does not
preserve the 2nd argument if dso is equal to NULL.

Changes:

  • Split paths of handling intercepted __cxa_atexit() and atexit(3). This affects all supported Operating Systems.
  • Add a local stack-like structure to hold the __cxa_atexit() context. atexit(3) is documented in the C standard as calling callback from the earliest to the oldest entry. This path also fixes potential ABI problem of passing an argument to a function from the atexit(3) callback mechanism.
  • Allow usage of global vars with ctors in interceptors. This allows to use Vector without automatic cleaning up the structures.

This code has been modeled after TSan implementation for the same functions.

Sponsored by <The NetBSD Foundation>

Diff Detail

Repository
rL LLVM

Event Timeline

krytarowski created this revision.Dec 1 2017, 4:23 AM
dvyukov added inline comments.Dec 1 2017, 4:53 AM
lib/msan/msan_vector.h
25 ↗(On Diff #125107)

We should move this code from tsan to sanitizer_common. sanitizer_common is meant exactly to share between sanitizers and avoid duplication of this kind of code.

krytarowski added inline comments.Dec 1 2017, 7:05 AM
lib/msan/msan_vector.h
25 ↗(On Diff #125107)
krytarowski planned changes to this revision.Dec 1 2017, 7:24 AM
krytarowski edited the summary of this revision. (Show Details)

Rebase to trunk.
Reuse __sanitizer::Vector.

vitalybuka added inline comments.Dec 5 2017, 4:55 PM
lib/msan/msan_interceptors.cc
1136

comment states obvious

1181

comment states obvious

1184

do you need to call REAL(__cxa_atexit) under the lock?

vitalybuka added inline comments.Dec 5 2017, 4:57 PM
lib/msan/msan_interceptors.cc
1139

this and PushBack comment below also do no add any value

krytarowski added inline comments.Dec 5 2017, 4:57 PM
lib/msan/msan_interceptors.cc
1184

Yes, as I'm pushing an item to the LIFO container.

vitalybuka edited edge metadata.Dec 5 2017, 5:20 PM

lgtm if redundant comments removed
does anyone else have anything to add?

lib/msan/msan_interceptors.cc
1184

I see
there is possibility of MSanAtExitWrapper immediately after REAL(__cxa_atexit) call
so we don't want want MSanAtExitWrapper pass that mutex before we push

krytarowski added inline comments.Dec 5 2017, 5:24 PM
lib/msan/msan_interceptors.cc
1184

The same algorithm is used in TSan. Blocking mutex is needed for hypothetical scenarios of executing atexit(3) callbacks and registering them concurrently.

Remove comments stating obvious.

vitalybuka accepted this revision.Dec 6 2017, 1:51 PM
This revision is now accepted and ready to land.Dec 6 2017, 1:51 PM
This revision was automatically updated to reflect the committed changes.
krytarowski reopened this revision.Dec 8 2017, 10:42 AM

Reverted, as it broke Linux.

This revision is now accepted and ready to land.Dec 8 2017, 10:42 AM
krytarowski planned changes to this revision.Dec 8 2017, 10:45 AM

I'm not reproducing the issues on NetBSD, so for now I will move this to background and keep patches locally.

I'm not reproducing the issues on NetBSD, so for now I will move this to background and keep patches locally.

Could you please attach move info about Linux issues, just in case some one volunteer to resolve it.

I was able to reproduce the issue on Linux but I m unsure about the proper solution, the wrappers algorithms are identical between TSan and MSan but atexit has different treatment in Msan since it s seemingly a real call. Locally I ve "disabled" atexit interceptor for Linux.

  • disable atexit(3) interceptor
This revision is now accepted and ready to land.Feb 10 2018, 9:56 AM
devnexen added inline comments.Feb 10 2018, 10:01 AM
lib/msan/msan_interceptors.cc
1194

Should it be MemorySanitizer ?

  • add interceptor_scope in atexit interceptor
  • correct ThreadSanitizer -> MemorySanitizer
krytarowski marked an inline comment as done.Feb 10 2018, 10:11 AM

Please test. Thank you in advance.

  • add InterceptorScope interceptor_scope; in __cxa_atexit
devnexen added a comment.EditedFeb 10 2018, 10:29 AM

Please test. Thank you in advance.

I had updated my compiler-rt tree before this update and it finally worked but with this diff it still failed (I see the new message "unreachable called" for each test). Would be good if a genuine Linux developer could confirm.

  • set REAL(atexit) in lib/msan/msan.cc

Please test. Thank you in advance.

I had updated my compiler-rt tree before this update and it finally worked but with this diff it still failed (I see the new message "unreachable called" for each test). Would be good if a genuine Linux developer could confirm.

Updated diff.

Problem is since it s in msan.cc it can t compile.

  • don't set REAL(atexit) to notreachable

Intercept atexit.

I set InterceptorScope interceptor_scope;, maybe it's enough.

I set InterceptorScope interceptor_scope;, maybe it's enough.

I tested again with and without the diff. Without seems to work.

This patch without InterceptorScope interceptor_scope; works, and this patch with InterceptorScope interceptor_scope; doesn't work?

So the original patch should be fine too.

This patch without InterceptorScope interceptor_scope; works, and this patch with InterceptorScope interceptor_scope; doesn't work?

So the original patch should be fine too.

In fact when I mentioned without the diff I meant the original code.

krytarowski planned changes to this revision.Feb 10 2018, 1:24 PM

I see, with guessing I won't go far. I will reschedule it for later once I will get an access to a Linux host capable to build LLVM.

Thanks for testing!

If we remove INTERCEPT_FUNCTION(atexit); does it work?

This comment was removed by devnexen.

Same failed results in my part.

  • fix Linux
This revision is now accepted and ready to land.Nov 9 2018, 6:18 PM
This revision was automatically updated to reflect the committed changes.

Thanks @mgorny for debugging on Linux.