-
Notifications
You must be signed in to change notification settings - Fork 348
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix UB checking for Mutex misusage #1419
Comments
So what we have to do is quite clearly shown in this table: releasing a mutex owned by another thread, and acquiring a mutex we already own, is UB for a "DEFAULT" mutex. The former is also UB for a NORMAL mutex. The hard thing will be to distinguish DEFAULT from NORMAL for the relock check, as they have the same value. We'll likely have to use a trick similar to what glibc did to achieve the same. |
Is the glibc trick sound? If I implemented that trick and someone created a mutex by passing in |
Well, glibc basically says that the following two programs are not equivalent: let mut mutex: libc::pthread_mutex_t = std::mem::zeroed();
libc::pthread_mutex_init(&mut mutex as *mut _, std::ptr::null()); and let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed();
libc::pthread_mutexattr_init(&mut attr as *mut _);
libc::pthread_mutexattr_settype(&mut mutexattr as *mut _, libc::PTHREAD_MUTEX_DEFAULT);
let mut mutex: libc::pthread_mutex_t = std::mem::zeroed();
libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _); The former creates a mutex where relocking is UB, the latter creates one where relocking is a deadlock.
That's the thing, if you call Btw, I am not sure what glibc would do for this: let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed();
libc::pthread_mutexattr_init(&mut attr as *mut _);
let mut mutex: libc::pthread_mutex_t = std::mem::zeroed();
libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _); But to be on the safe side I'd say this is also a "relock is UB" mutex. |
I understand that this is how the glibc implementation behaves. However, this is just one of the possible behaviours allowed by the (POSIX) documentation and also not the most conservative one, or am I missing something? In other words, would not be better to rely only on the documentation and always assume the worst possible case that is allowed by the documentation in that situation? By the way, in both cases when relocking happens, we would get an immediate error and the only difference would be whether the error is UB or a deadlock.
We know for sure that this is the case when |
I think it is the most conservative. Do you have an example for how we could be even more conservative?
Fair. But UB still has a different quality to it. We should not say "UB" when really there's just a deadlock, and vice versa.
It specifies that if you use |
If I look at the table and your second example (I repeat it below), I would say that the implementation of let mut mutexattr: pthread_mutexattr_t = std::mem::zeroed();
pthread_mutexattr_init(&mut attr as *mut _);
pthread_mutexattr_settype(&mut mutexattr as *mut _, PTHREAD_MUTEX_DEFAULT);
let mut mutex: pthread_mutex_t = std::mem::zeroed();
pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _);
Fair point.
But it does also say that if a programmer uses |
No the example is actually what I meant, I just forgot to say that for glibc it also happens to be the case that Miri cannot affect whether |
This is the bit that is confusing me: if If we cannot because that is incompatible with what glibc does, maybe it would be best to mention in the error message that this could be a false positive because of strange glibc semantics? |
The problem here is that while the specification distinguishes between the two types, the actual implementation in glibc uses the same value for both. Miri could use |
You are basically saying that the two snippets I posted here must clearly be equivalent, since I think that is a reasonable interpretation of the spec. However, the glibc people clearly disagree. And since the spec does not explicitly say that |
Ok, you convinced me. |
The relevant discussion on the PR:
#1362 (comment)
The text was updated successfully, but these errors were encountered: