mingw32 pthreads, падение программы после выхода

elenangel

некая программа с тредами собирается под винду, запускается, отрабатывает, доходит до return EXIT_SUCCESS в main и дальше падает со странным стеком:
 
Program received signal SIGSEGV, Segmentation fault.
0x7c84afb2 in ntdll!RtlIpv6AddressToStringExA from C:\WINDOWS\system32\ntdll.dll
(gdb) bt
0x7c84afb2 in ntdll!RtlIpv6AddressToStringExA from C:\WINDOWS\system32\ntdll.dll
0x7c83d281 in ntdll!RtlLookupAtomInAtomTable from C:\WINDOWS\system32\ntdll.dll
0x004298ef in ptw32_new
0x0007fe0c in ?
0x00000000 in ?
(gdb)

это под 2003 сервером, под семеркой падает в ptw32_thread_reuse_lock, bt сейчас достать не могу, к сожалению
при этом никаких Ipv6Address и близко нет, везде используется ipv4, и вообще это выглядит странно.
может, кто сталкивался с таким и подскажет как это лечить?
upd: mingw32 и pthreads брал в виде сорцов отсюда и собирал на линуксе

vall

доходит до return EXIT_SUCCESS в main
стэк у тебя уже не тот, замени return на exit/_exit или какой-нить виндовый TerminateCurrentProcessAndExit

elenangel

ok, попробую. а как такое - "стек уже не тот" - вообще может быть?

elenangel

огромное спасибо, _exit(retVal) помогло

vall

если честно — хз. какая-то магия в pthreads проинтерферировала с виндовой.

Dasar

огромное спасибо, _exit(retVal) помогло
Есть вероятность, что это просто починило симптом и замазало проблему

elenangel

само собой, но разбираться с этим сейчас нет времени, есть более актуальные задачи. возможно, когда-нибудь потом решится.

Maurog

некая программа с тредами собирается под винду, запускается, отрабатывает, доходит до return EXIT_SUCCESS в main и дальше падает со странным стеком
могу предположить, что дело не в pthreads, а в том, что у потоков нет хозяинов
дело в том, что под виндой когда главный поток выходит (функция main там работает рантайм прибивает все приложение (некий terminate вызывается)
правильный подход: выходя из main, надо дождаться выхода всех запущенных своей программой потоков

vall

выходя из main, надо дождаться выхода всех запущенных своей программой потоков
охрененно удобное поведение :grin: и конечно же одним сисколом это не реализуется

apl13

А массовый pthread_cancel спасет родину?

Maurog

А массовый pthread_cancel спасет родину?
во-первых, надо знать id потока
во-вторых, вызов асинхронный
в-третьих, я так понимаю, сам поток должен еще как-то обработать запрос на cancel

elenangel

как бы эта идея приходила в голову, но main после отброса лишних деталей представляет из себя mainThread.asyncStart; mainThread.wait; return EXIT_SUCCESS;, где asyncStart = pthread_create, wait = join
внутри mainThread тоже есть треды но на них в mainThread.deinit делается blockingStop;, что в нашей реализации эквивалентно asyncStop; wait;
таким образом, все треды останавливаются перед выходом и у всех них есть хозяин. специально этот факт проверял.

elenangel

ну да, все верно, cancel можно произвести только с разрешения потока и только в так называемых cancelation points, коими являются большинство блокирующих функций ввода-вывода и специальный вызов pthread_test_cancel.
однако, мы давно отказались от отмены тредов функцией cancel так как это не всегда удобно поддерживать и не всегда работает. вместо этого нигде не используются долгие блокирующие вызовы и соответственно любой тред можно остановить изменив ему переменную состояния. также не используются detached треды, потому, что: ОС ресурсы треда удалятся, а класс кто делетить будет? delete this; в деинициализации треда что ли?

Maurog

таким образом, все треды останавливаются перед выходом и у всех них есть хозяин.
а выполняется ли такой инвариант: кол-во потоков сразу после входа в main совпадает с кол-вом потоков в приложении непосредственно перед return SUCCESS из main ?
Оставить комментарий
Имя или ник:
Комментарий: