Необъяснимая взаимоблокировка мьютекса pthread

Похоже, что в моем приложении возникла тупиковая ситуация, вызванная определенным мьютексом. Однако код явно разблокирует мьютекс почти сразу после того, как он заблокирован, и нет никаких других зависимостей мьютекса между блокировкой и разблокировкой. Мьютекс определенно не блокируется дважды одним и тем же потоком.

Проблема возникает только у одного (из многих) пользователей моего приложения. Я работаю с дампом ядра, созданным во время тупика. Ожидающие потоки не отображаются в дампе ядра, но код говорит мне, что ни один из них не заблокировал рассматриваемый мьютекс. Это след от потока, удерживающего блокировку:

(gdb) bt
#0  0x0000003aa4e0e054 in __lll_lock_wait () from /lib64/libpthread.so.0
#1  0x0000003aa4e09388 in _L_lock_854 () from /lib64/libpthread.so.0
#2  0x0000003aa4e09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3  0x000000000043cf59 in my_processor (myvar=0x7fff36ba7430, mystring=0x7fff36ba76c0 
"This is a string")

Я также распечатал данные рассматриваемого мьютекса:

(gdb) print my_mutex
$4 = {__data = {__lock = 2, __count = 0, __owner = 0, __nusers = 0, __kind = 2, __spins = 0, __list = {__prev = 0x0, __next = 0x0}},
  __size = "\002", '\000' <repeats 15 times>, "\002", '\000' <repeats 22 times>, __align = 2}

Это не кажется последовательным: владелец 0, что говорит о том, что ни один поток не владеет блокировкой, но все же поток блокируется в ожидании мьютекса.

В следующем фрагменте показано объявление и инициализация мьютекса:

pthread_mutex_t my_mutex;
pthread_mutexattr_t mutex_attr;

/* set up mutex attributes */
pthread_mutexattr_init(&mutex_attr);
pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ERRORCHECK);

/* create mutex */
pthread_mutex_init(&my_mutex, &mutex_attr);

/* destroy mutex attributes */
pthread_mutexattr_destroy(&mutex_attr);

Что могло быть причиной этой проблемы?


person Jason    schedule 12.02.2013    source источник
comment
Возможно ли, что несколько потоков достигают mutex_init одновременно, создавая странное условие?   -  person matzahboy    schedule 13.02.2013
comment
Не могли бы вы показать соответствующие части кода, в которых вы блокируете и разблокируете мьютексы? В каком контексте вызывается приведенный выше код?   -  person junix    schedule 13.02.2013
comment
К вашему сведению, выполнение set print pretty on в GDB значительно упрощает чтение содержимого структуры ...   -  person Oliver Charlesworth    schedule 13.02.2013
comment
Основной поток выполняет приведенный выше фрагмент, вызывающий pthread_mutex_init (), прежде чем он порождает любые другие потоки.   -  person Jason    schedule 13.02.2013
comment
но поток блокируется в ожидании мьютекса. Какой поток? Вставленный код, если он находится в main(), как указано, бесполезен для определения вашей реальной проблемы. Приятно знать, что он был инициализирован и все такое, но ключ к решению потенциально нарушенных парадигм блокировки - это увидеть код, который вызывает блокировки и разблокировки. Пожалуйста, опубликуйте SSCCE, демонстрирующий проблему.   -  person WhozCraig    schedule 13.02.2013
comment
Похоже, что ваш мьютекс где-то перезаписывается из-за переполнения буфера или записи зависшего указателя.   -  person caf    schedule 13.02.2013
comment
Проблема воспроизводится каждый раз, когда пользователь перезапускает приложение. Вероятно или, по крайней мере, правдоподобно, что поведение будет соответствовать переполнению буфера или зависанию указателя, перезаписывающему мьютекс?   -  person Jason    schedule 13.02.2013
comment
@ user1494899: вы можете использовать valgrind, чтобы определить, есть ли переполнение буфера или зависший указатель. И используйте инструмент DRD от valgrind, который может помочь определить, есть ли проблема с использованием мьютекса, которая не связана с ошибкой использования памяти.   -  person Michael Burr    schedule 13.02.2013
comment
@ user1494899: Конечно, поскольку входные данные программы, когда этот пользователь входит в систему, скорее всего, очень похожи или идентичны. Как предлагает Майкл Берр, попробуйте запустить программу под valgrind, используя инструменты memcheck и helgrind.   -  person caf    schedule 15.02.2013