Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 6 Dec 2016 16:30:14 +0100
From:      Dimitri Staessens <dimitri.staessens@intec.ugent.be>
To:        Konstantin Belousov <kostikbel@gmail.com>
Cc:        freebsd-threads@freebsd.org
Subject:   Re: Unlocking a robust mutex in a cleanup handler
Message-ID:  <35726dbb-75f7-682d-ad41-c78b96675485@intec.ugent.be>
In-Reply-To: <20161206144812.GS54029@kib.kiev.ua>
References:  <119e59d4-6125-f313-e6e6-67055a15d224@intec.ugent.be> <20161206112558.GN54029@kib.kiev.ua> <6a7139cd-b6db-d078-ee5e-b7c590eb13d1@intec.ugent.be> <20161206144812.GS54029@kib.kiev.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
Dear Konstantin,

I didn't get the error, but on my machine the thread never exists the 
condwait when the pthread_cancel is called.

gdb output:

$ sudo gdb ./robust_test 3246
GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain 
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "amd64-marcel-freebsd"...(no debugging 
symbols found)...
Attaching to program: /usr/home/dstaesse/robust_test, process 3246
Reading symbols from /lib/libthr.so.3...Reading symbols from 
/usr/lib/debug//lib/libthr.so.3.debug...done.
[New Thread 801416500 (LWP 100404/robust_test)]
[New Thread 801416000 (LWP 100313/robust_test)]
done.
Loaded symbols for /lib/libthr.so.3
Reading symbols from /usr/lib/librt.so.1...done.
Loaded symbols for /usr/lib/librt.so.1
Reading symbols from /lib/libc.so.7...done.
Loaded symbols for /lib/libc.so.7
Reading symbols from /libexec/ld-elf.so.1...done.
Loaded symbols for /libexec/ld-elf.so.1
[Switching to Thread 801416000 (LWP 100313/robust_test)]
0x00000008008386ac in _umtx_op_err () from /lib/libthr.so.3
(gdb) info threads
* 2 Thread 801416000 (LWP 100313/robust_test) 0x00000008008386ac in 
_umtx_op_err () from /lib/libthr.so.3
1 Thread 801416500 (LWP 100404/robust_test)  _thr_ast 
(curthread=0x801416500) at /usr/src/lib/libthr/thread/thr_sig.c:271
Current language: auto; currently minimal
(gdb) bt
#0  0x00000008008386ac in _umtx_op_err () from /lib/libthr.so.3
#1  0x0000000800834df6 in join_common (pthread=<value optimized out>, 
thread_return=<value optimized out>, abstime=<value optimized out>)
     at /usr/src/lib/libthr/thread/thr_join.c:125
#2  0x0000000000401186 in main ()
(gdb) thread 1
[Switching to thread 1 (Thread 801416500 (LWP 100404/robust_test))]#0 
  _thr_ast (curthread=0x801416500)
     at /usr/src/lib/libthr/thread/thr_sig.c:271
271 check_suspend(curthread);
(gdb) bt
#0  _thr_ast (curthread=0x801416500) at 
/usr/src/lib/libthr/thread/thr_sig.c:271
#1  0x0000000800837a5b in __thr_pshared_offpage (key=<value optimized 
out>, doalloc=<value optimized out>)
     at /usr/src/lib/libthr/thread/thr_pshared.c:86
#2  0x00000008008363cb in cond_wait_common (cond=<value optimized out>, 
mutex=0x800643004, abstime=0x0, cancel=1)
     at /usr/src/lib/libthr/thread/thr_cond.c:349
#3  0x0000000000400ff2 in blockfunc ()
#4  0x000000080082ab55 in thread_start (curthread=<value optimized out>) 
at /usr/src/lib/libthr/thread/thr_create.c:289
#5  0x0000000000000000 in ?? ()
(gdb)

cheers,

Dimitri

On 12/06/16 15:48, Konstantin Belousov wrote:
> On Tue, Dec 06, 2016 at 03:17:41PM +0100, Dimitri Staessens wrote:
>> Dear Konstantin,
>>
>> thanks for your immediate response. Please find attached a minimal code
>> example. I do hope I'm sending in the correct format, I'm new to the
>> community.
>>
>> The test creates an integer, robust mutex and condition variable in
>> shared memory. A thread blocks on that condition variable with the
>> associated mutex. After one second, the main thread cancels the blocking
>> thread.
>>
>> I compile as follows:
>>
>> gcc robust_test.c -lpthread -lrt -o robust_test
>>
>> and run
>>
>> ./robust_test
>>
>> On linux it gives the following output:
>> [dstaesse@phoneutria]$ ./robust_test
>> Initializing...
>> Starting thread...
>> Sleeping for one second...
>> Thread started...
>> Cancelling thread...
>> Thread finished.
>> Bye.
>>
>> On FreeBSD I get the following:
>> $ ./robust_test
>> Initializing...
>> Starting thread...
>> Sleeping for one second...
>> Thread started...
>> Cancelling thread...
>> Fatal error 'inact_mtx enter' at line 188 in file
>> /usr/src/lib/libthr/thread/thr_mutex.c (errno = 0)
>> Abort trap (core dumped)
> Try this patch.  It worked for me.
> It is enough to patch and then rebuild only libthr:
> cd /usr/src
> patch -p1 <patch
> (cd lib/libthr && make WITHOUT_TESTS=yes all install)
>
> diff --git a/lib/libthr/thread/thr_cond.c b/lib/libthr/thread/thr_cond.c
> index 506b8eca9e7..64d075ca06f 100644
> --- a/lib/libthr/thread/thr_cond.c
> +++ b/lib/libthr/thread/thr_cond.c
> @@ -224,16 +224,26 @@ cond_wait_kernel(struct pthread_cond *cvp, struct pthread_mutex *mp,
>   		 * state and unlock the mutex without making the state
>   		 * consistent and the state will be unrecoverable.
>   		 */
> -		if (error2 == 0 && cancel)
> +		if (error2 == 0 && cancel) {
> +			if (robust) {
> +				_mutex_leave_robust(curthread, mp);
> +				robust = false;
> +			}
>   			_thr_testcancel(curthread);
> +		}
>   
>   		if (error == EINTR)
>   			error = 0;
>   	} else {
>   		/* We know that it didn't unlock the mutex. */
>   		_mutex_cv_attach(mp, recurse);
> -		if (cancel)
> +		if (cancel) {
> +			if (robust) {
> +				_mutex_leave_robust(curthread, mp);
> +				robust = false;
> +			}
>   			_thr_testcancel(curthread);
> +		}
>   		error2 = 0;
>   	}
>   	if (robust)

-- 
Dimitri Staessens
Ghent University - imec
Dept. of Information Technology (INTEC)
Internet Based Communication Networks and Services
Technologiepark 15
9052 Zwijnaarde
T: +32 9 331 48 70
F: +32 9 331 48 99




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?35726dbb-75f7-682d-ad41-c78b96675485>