Skip to content

Panic: Duplicate mutex destroy on Thread.join (DragonFly) #20698

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

Closed
mneumann opened this issue Jan 7, 2015 · 5 comments
Closed

Panic: Duplicate mutex destroy on Thread.join (DragonFly) #20698

mneumann opened this issue Jan 7, 2015 · 5 comments

Comments

@mneumann
Copy link
Contributor

mneumann commented Jan 7, 2015

The following program triggers this:

use std::thread::Thread;

fn main() {
    Thread::spawn(move || { println!("Hello"); }).join();
    println!("After join");
}

When compiled on DragonFly with most recent rust (and all versions since the removal of rustrt), it fails with:

hello
thread '<main>' panicked at 'assertion failed: `(left == right) && (right == left)` (left: `22`, right: `0`)',
/home/..../rust/src/libstd/sys/unix/mutex.rs:53

The code that fails is:

let r = ffi::pthread_mutex_destory(self.inner.get());
debug_assert_eq!(r, 0);

It returns with error code 22 (EINVAL) instead of 0. To me it seems that Mutex::destroy() is called twice! It might be related to the new TLS thread_local code and destructor support, but it's pretty hard to understand, so any ideas how to track the bug further down and fix it is welcomed.

@alexcrichton
Copy link
Member

Can you get a backtrace at what's failing as well? I would be quite surprised if we destroyed a mutex twice, because that's certainly very bad! Can you also make sure that this passes successfully for you?

#include <assert.h>
#include <pthread.h>

int main() {
  pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
  assert(pthread_mutex_destroy(&lock) == 0);
}

@mneumann
Copy link
Contributor Author

mneumann commented Jan 8, 2015

It fails with error code 22, if I compile it like cc -pthread test.c. If I compile it without -pthread it works. I noticed that in general pthread functions (e.g. pthread_key_create) only work within a pthread-created thread, not in the main thread. I'll send this to the DragonFly specific mailing list for additional help.

The backtrace of the example program I gave above is:

thread '<main>' panicked at 'assertion failed: `(left == right) && (right == left)` (left: `22`, right: `0`)', /home/mneumann/disk/neu/rust-cross-dragonfly/stage2-linux/rust/src/libstd/sys/unix/mutex.rs:53
stack backtrace:
   1:          0x1050730 - sys::backtrace::write::h6c2cb1f1132defcbQft
   2:          0x105e7a0 - failure::on_fail::h52cb2223a000b31akgz
   3:          0x102ce30 - rt::unwind::begin_unwind_inner::h5cadd3b8e3af94baoUy
   4:          0x102d780 - rt::unwind::begin_unwind_fmt::hdcce387453c77319VSy
   5:          0x1028240 - sys::mutex::Mutex::destroy::h944d68132516e13eymu
   6:          0x1028200 - sys_common::mutex::Mutex::destroy::h05060b7894b378a0U8w
   7:          0x10281c0 - sync::mutex::Mutex<T>.Drop::drop::h9736437216186091782
   8:          0x1028130 - std..sync..mutex..Mutex<bool>::glue_drop.1740::hc29669eec6ad0cb3
   9:          0x10280d0 - std..thread..Inner::glue_drop.1737::h852294eb2538a0c8
  10:          0x10280a0 - mem::drop::h5042620272860910571
  11:          0x1027da0 - arc::Arc<T>.Drop::drop::h2578377223763874141
  12:          0x1027d70 - alloc..arc..Arc<std..thread..Inner>::glue_drop.1734::hdefd71314919f852
  13:          0x1027d40 - std..thread..Thread::glue_drop.1731::h5e295f37c79aa596
  14:          0x102c900 - std..thread..JoinGuard<(*>::glue_drop.2140::h772f4f23477015a3
  15:          0x102c7e0 - thread::JoinGuard<T>::join::h10970293053447468842
  16:          0x1025630 - main::he5cc945d2fe13fb6faa
  17:          0x1062540 - rt::lang_start::unboxed_closure.33933
  18:          0x10624d0 - rt::unwind::try::try_fn::__rust_abi::h1667473091729999914
  19:          0x1062490 - rt::unwind::try::try_fn::h1667473091729999914
  20:          0x1070180 - rust_try_inner
  21:          0x1070170 - rust_try
  22:          0x1062060 - rt::unwind::try::h17451077907674403930
  23:          0x1061d30 - rt::lang_start::h35714ae31d7a9360V9y
  24:          0x10257b0 - main
  25:                0x0 - <unknown>

@mneumann
Copy link
Contributor Author

mneumann commented Jan 8, 2015

Interestingly, it does not fail once it goes through a lock/unlock cycle prior of destruction:

#include <pthread.h>
#include <stdio.h>

int main() {
    int err = 0;
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

    err = pthread_mutex_lock(&mutex);
    printf("lock: %d\n", err);

    err = pthread_mutex_unlock(&mutex);
    printf("unlock: %d\n", err);

    err = pthread_mutex_destroy(&mutex);
    printf("destroy1: %d\n", err);

    err = pthread_mutex_destroy(&mutex);
    printf("destroy2: %d\n", err);      

    return 0;
}

returns:

lock: 0
unlock: 0
destroy1: 0
destroy2: 22

And also, if I call pthread_mutex_init() prior of pthread_mutex_destroy() it works, too.

bors added a commit that referenced this issue Jan 9, 2015
Fix assertion in Mutex::destroy() on DragonFly (#20698)

Reviewed-by: alexcrichton
@alexcrichton
Copy link
Member

I believe this was mitigated in #20741

@mneumann
Copy link
Contributor Author

mneumann commented Nov 5, 2015

Yes! #20741 fixed it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants