[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
unlock of an unlocked mutex
From: |
Tom de Vries |
Subject: |
unlock of an unlocked mutex |
Date: |
Thu, 7 Jul 2022 18:01:37 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.9.0 |
Hi,
After building gdb with gcc -fsanitize=thread, I ran into a problem in
ncurses.
It's easy to reproduce using this small program:
...
$ cat test.c
#include <stdlib.h>
#include <stdio.h>
#include <curses.h>
int
main (void)
{
newterm (NULL, stdout, stdin);
return 0;
}
...
Compile like so:
...
$ gcc test.c -fsanitize=thread -lncurses
...
and then run:
...
$ ./a.out 2>&1 | tee LOG
==================
WARNING: ThreadSanitizer: unlock of an unlocked mutex (or by a wrong
thread) (pid=5864)
#0 pthread_mutex_unlock <null> (libtsan.so.0+0x3e4ca)
#1 newterm ../ncurses/./base/lib_newterm.c:357
(libncurses.so.6+0x141c4)
#2 __libc_start_main <null> (libc.so.6+0x352bc)
Location is global '_nc_globals' of size 712 at 0x7f9c4b258bc0
(libtinfo.so.6+0x00000022dd98)
Mutex M10 (0x7f9c4b258d98) created at:
#0 pthread_mutex_init <null> (libtsan.so.0+0x4c483)
#1 _nc_mutex_init ../ncurses/./tinfo/lib_data.c:351
(libtinfo.so.6+0xcfee)
#2 __libc_start_main <null> (libc.so.6+0x352bc)
SUMMARY: ThreadSanitizer: unlock of an unlocked mutex (or by a wrong
thread) (/usr/lib64/libtsan.so.0+0x3e4ca) in pthread_mutex_unlock
==================
ThreadSanitizer: reported 1 warnings
...
Using this gdb session:
...
$ gdb -q -batch a.out -ex "set breakpoint pending on" -ex "b
_nc_mutex_lock" -ex "b _nc_mutex_unlock" -ex "b _nc_mutex_init" -ex "b
_nc_mutex_trylock" -ex run -ex "c" -ex c -ex c -ex c -ex c -ex c -ex c
-ex c -ex c -ex c -ex c -ex c -ex c -ex c 2>&1 | tee gdb-log.txt
...
I generated attached gdb-log.txt.
I think the sanitizer complains about this lock:
...
$ grep 472 gdb-log.txt
Breakpoint 1, _nc_mutex_lock (obj=0x7ffff5ab9d98 <_nc_globals+472>) at
../ncurses/./tinfo/lib_data.c:358
Breakpoint 3, _nc_mutex_init (obj=0x7ffff5ab9d98 <_nc_globals+472>) at
../ncurses/./tinfo/lib_data.c:345
Breakpoint 2, _nc_mutex_unlock (obj=0x7ffff5ab9d98 <_nc_globals+472>) at
../ncurses/./tinfo/lib_data.c:374
...
Which is the 'prescreen' lock:
...
$ gdb -q -batch a.out -ex run -ex "print &_nc_globals.mutex_prescreen"
2>&1 | grep 472
$1 = (pthread_mutex_t *) 0x7ffff5ab9d98 <_nc_globals+472>
...
What happens is:
- we lock the mutex
- we init the mutex, which destroys the locked mutex, and creates an
unlocked one
- we unlock the unlocked mutex
I wonder if this fixes it:
...
diff --git a/ncurses/base/lib_newterm.c b/ncurses/base/lib_newterm.c
index bba97ba1..e1c78f50 100644
--- a/ncurses/base/lib_newterm.c
+++ b/ncurses/base/lib_newterm.c
@@ -362,6 +362,7 @@ NCURSES_EXPORT(SCREEN *)
newterm(const char *name, FILE *ofp, FILE *ifp)
{
SCREEN *rc;
+ _nc_init_pthreads();
_nc_lock_global(prescreen);
START_TRACE();
rc = NCURSES_SP_NAME(newterm) (CURRENT_SCREEN_PRE, name, ofp, ifp);
...
Thanks,
- Tom
gdb-log.txt
Description: Text document
- unlock of an unlocked mutex,
Tom de Vries <=