main() не завершается после успешного pthread_join

У меня есть программа, которая запускает поток, а затем ждет завершения этого потока, прежде чем он вернется. Код примерно такой:

int main(int32_t argc, char* argv[]) {
  pthread_t t;
  /* initialization and other stuff 
     ... 
  */
  printf("join result:%d\n", pthread_join(t, 0));
  return 0;
}

Программа печатает, как положено: join result: 0. Таким образом, объединение работает, и t завершено. Тем не менее программа не останавливает выполнение. Я могу заставить его остановиться, только если вставлю команду exit(0) (или какой-то другой номер) перед строкой return 0.

Однако, если я удалю строку с вызовом pthread_join, программа завершится без ошибок.

Как это вообще возможно? Что может помешать программе завершить выполнение после объединения всех подпотоков?

EDIT: я только что узнал, что gdb сообщает мне, что я получаю ошибку сегментации после выполнения последней строки с }. Тем не менее, я понятия не имею, что происходит за кулисами:

Program received signal SIGSEGV, Segmentation fault.
0x000000060003aa10 in ?? ()

person Bastian    schedule 20.06.2014    source источник
comment
Я проверял справочную страницу и наткнулся на это: если несколько потоков одновременно пытаются присоединиться к одному и тому же потоку, результаты не определены. Если поток, вызывающий pthread_join(), будет отменен, то целевой поток останется доступным для присоединения (т. е. он не будет отсоединен). Есть ли шанс, что вы делаете что-то подобное?   -  person Robert Ekendahl    schedule 20.06.2014
comment
@RobertEkendahl Но не будет ли это отражено в сообщении printf? В любом случае у меня есть только один основной поток, который создает и присоединяется к другим потокам.   -  person Bastian    schedule 20.06.2014
comment
Я не вижу никакой очевидной причины, по которой вы получите segfault. Можете ли вы опубликовать еще немного кода?   -  person Robert Ekendahl    schedule 20.06.2014
comment
@RobertEkendahl Я постараюсь сократить код до минимума и скоро опубликую его.   -  person Bastian    schedule 20.06.2014
comment
Я думаю, что возможно повреждение стека в основном потоке. Из окон я знаю, что перед выполнением main адрес функции exit_process помещается в стек. Затем return 0 выполняет вызов exit_process. Если в вашем случае стек был поврежден, возможно, указатель на exit_process был заменен недопустимым указателем.   -  person George Nechifor    schedule 20.06.2014
comment
Я думаю, что это может быть проблемой! Я использовал GMP для арифметики произвольной точности и забыл инициализировать переменную GMP, прежде чем использовать ее для вычислений.   -  person Bastian    schedule 20.06.2014
comment
Стандартные проверки: Компилируется ли код без предупреждений, если он компилируется со всеми предупреждениями на -Wall -Wextra -pedantic. Работает ли он без ошибок при проверке памяти, такой как Valgrind (valgrind.com)?   -  person alk    schedule 20.06.2014
comment
@GeoAoe Если вы опубликуете свой комментарий в качестве ответа, я приму его, потому что это была конечная причина моей проблемы (как было сказано ранее).   -  person Bastian    schedule 21.06.2014


Ответы (1)


Я думаю, что возможно повреждение стека в основном потоке. Из окон я знаю, что перед выполнением main адрес функции exit_process помещается в стек. Затем return 0 выполняет вызов exit_process. Если в вашем случае стек был поврежден, возможно, указатель на exit_process был заменен недопустимым указателем.

person George Nechifor    schedule 22.06.2014