This is an archive of the discontinued LLVM Phabricator instance.

Don't assume PTHREAD_CREATE_JOINABLE is 0 on all systems
ClosedPublic

Authored by fjricci on Apr 10 2017, 7:15 AM.

Details

Summary

Lsan was using PTHREAD_CREATE_JOINABLE/PTHREAD_CREATE_DETACHED
as truthy values, which works on Linux, where the values are 0 and 1,
but this fails on OS X, where the values are 1 and 2.

Set PTHREAD_CREATE_DETACHED to the correct value for a given system.

Diff Detail

Repository
rL LLVM

Event Timeline

fjricci created this revision.Apr 10 2017, 7:15 AM
alekseyshl added inline comments.Apr 11 2017, 10:00 AM
lib/lsan/lsan_interceptors.cc
61 ↗(On Diff #94668)

Why do we have to define them? why not use the proper definition in phtread.h?

283 ↗(On Diff #94668)

int detached = PTHREAD_CREATE_JOINABLE; to be consistent with the rest of your change.

fjricci added inline comments.Apr 11 2017, 10:10 AM
lib/lsan/lsan_interceptors.cc
61 ↗(On Diff #94668)

We don't want to include any system headers in this file.

283 ↗(On Diff #94668)

This review established that we don't want to define PTHREAD_CREATE_JOINABLE (that value will get over-written by pthread_attr_getdetachstate anyway): D10606

alekseyshl added inline comments.Apr 11 2017, 10:44 AM
lib/lsan/lsan_interceptors.cc
61 ↗(On Diff #94668)

Oh, we already have those defined in tsan... Let's move the definition to saniter_linux.h and sanitizer_mac.h, define them as enum (yes, I'd still vote for defining PTHREAD_CREATE_JOINABLE, I don't see the upside of not defining it) and reuse them in both tsan and lsan.

283 ↗(On Diff #94668)

pthread_attr_getdetachstate returns int and can fail, we're ignoring the error and go with a default value. I admit, it does not change the result of detached == PTHREAD_CREATE_DETACHED check, but does not feel like a sound practice.

fjricci updated this revision to Diff 94866.Apr 11 2017, 11:27 AM

Address comments

fjricci marked 2 inline comments as done.Apr 11 2017, 11:27 AM
alekseyshl accepted this revision.Apr 11 2017, 12:03 PM
alekseyshl added inline comments.
lib/sanitizer_common/sanitizer_linux.h
59 ↗(On Diff #94866)

I'd prefer them to be an anonymous enum:

enum {

PTHREAD_CREATE_JOINABLE = 0,
PTHREAD_CREATE_DETACHED = 1

}

Preprocessor is evil.

This revision is now accepted and ready to land.Apr 11 2017, 12:03 PM
fjricci requested review of this revision.Apr 11 2017, 12:53 PM
fjricci edited edge metadata.

So I think we may have to return to the original method of defining the value in the source files. sanitizer_mac.h is included in files that also include pthread.h, which causes a multiple definition error. We can't use an ifndef, because the pthreads header isn't necessarily included first. If we want to keep these in sanitizer_mac and sanitizer_linux, we'll need to rename them to something that won't conflict with the pthreads name. Thoughts?

fjricci updated this revision to Diff 94964.Apr 12 2017, 7:21 AM

Update to avoid conflicts with definitions from pthreads header

It doesn't look like we have any existing uses of the const-type constants
in platform-specific headers currently though, so I'm not sure that this is
better than the original solution of defining inside the source file.

kubamracek edited edge metadata.Apr 12 2017, 9:48 AM

Can we use the original names instead of kCreateJoinable and kCreateDetached? The name "kCreateDetached" suggests that it's some arbitrary sanitizer-internal constant, but that's not true. It's a platform-defined value that we must follow.

Can we use the original names instead of kCreateJoinable and kCreateDetached? The name "kCreateDetached" suggests that it's some arbitrary sanitizer-internal constant, but that's not true. It's a platform-defined value that we must follow.

The problem with the original name is that we hit conflicts in files that include both 'sanitizer_linux.h' and 'pthread.h', due to a multiple definition.

Can we use the original names instead of kCreateJoinable and kCreateDetached? The name "kCreateDetached" suggests that it's some arbitrary sanitizer-internal constant, but that's not true. It's a platform-defined value that we must follow.

The problem with the original name is that we hit conflicts in files that include both 'sanitizer_linux.h' and 'pthread.h', due to a multiple definition.

Well, not technically a multiple definition, but after the preprocessor replaces PTHREAD_CREATE_JOINABLE, you end up with a statement like '#define 0 = 0` in whichever header is included second, which is an error.

Hmm, what about this then, define bool IsThreadAttached wrapper function in sanitizer_common/sanitizer_{linux|mac}, the same way we do for GetTid(). Definitions from pthread.h are available there, feels like a cleaner solution.

fjricci updated this revision to Diff 95015.Apr 12 2017, 12:15 PM

Add wrapper function for checking thread detached state

alekseyshl added inline comments.Apr 12 2017, 1:51 PM
lib/lsan/lsan_interceptors.cc
289 ↗(On Diff #95016)

What about !SANITIZER_POSIX case? Who's going to provide this function?

fjricci added inline comments.Apr 12 2017, 1:55 PM
lib/lsan/lsan_interceptors.cc
289 ↗(On Diff #95016)

Lots of other things in this function will also break in the !SANITIZER_POSIX case - pthread_attr_getdetachstate, pthread_create, etc. I don't think this file is currently designed to work at all in non-posix cases.

alekseyshl accepted this revision.Apr 12 2017, 2:56 PM

Other than tsan_interceptors.cc question, lgtm.

lib/lsan/lsan_interceptors.cc
289 ↗(On Diff #95016)

Let's remove #if SANITIZER_POSIX around include then, it's misleading.

What about tsan_interceptors.cc? Is it also posix only?

This revision is now accepted and ready to land.Apr 12 2017, 2:56 PM
fjricci added inline comments.Apr 13 2017, 7:18 AM
lib/lsan/lsan_interceptors.cc
289 ↗(On Diff #95016)

Yeah, tsan is also posix only, and there is definitely quite a bit of posix-specific code in that file. Interestingly, they do use the SANITIZER_POSIX guard on the header inclusion in that file, perhaps for future-proofing?

alekseyshl added inline comments.Apr 13 2017, 10:25 AM
lib/lsan/lsan_interceptors.cc
289 ↗(On Diff #95016)

I don't know why. It's trivial to add back and in case of future changes, the failure is more explicit when there's no ifdef around the include.

fjricci added inline comments.Apr 13 2017, 10:26 AM
lib/lsan/lsan_interceptors.cc
289 ↗(On Diff #95016)

Ok, sounds good. I'll remove it from the tsan file as well then, for consistency.

This revision was automatically updated to reflect the committed changes.