[closed]RtlLookupAtomInAtomTable вместо EnterCriticalSection вызывает

elenangel

решение: если pthreads линкуешь статически то нужно делать #include <implement.h> и далее вызов ptw32_processInitialize до первого использования либы
собираю программу с pthreads-win32, pthreads собираю тоже из исходников как часть проекта и линкую статически.
при запуске собранного экзешника под виндами программа молча выходит. запуск под gdb показывает что упало в вызове функции
бектрейс:
 

C:\Prog>gdb snmpt
GNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-mingw32"...
(gdb) r
Starting program: C:\Prog/snmpt.exe
[New thread 2040.0x57c]

Now we will crash :(

Program received signal SIGSEGV, Segmentation fault.
0x7c84cd02 in ntdll!RtlIpv6AddressToStringExA
from C:\WINDOWS\system32\ntdll.dll
(gdb) bt
0x7c84cd02 in ntdll!RtlIpv6AddressToStringExA
from C:\WINDOWS\system32\ntdll.dll
0x7c83d0e7 in ntdll!RtlLookupAtomInAtomTable
from C:\WINDOWS\system32\ntdll.dll
0x0042d1d6 in ptw32_threadReusePop
0x0042d077 in ptw32_new
0x0042cb9a in pthread_create
0x004193e1 in Task::startThread
0x004170ef in Task::asyncStart
0x0041714a in Task::blockingStart
0x00429eb2 in main
(gdb)

ничего подобного RtlLookupAtomInAtomTable, RtlIpv6AddressToStringExA я не вызывал, в исходниках pthread этих функций тоже нету. иду в функцию ptw32_threadReusePop и вижу в ней 2 вызова WINAPI - EnterCriticalSection в начале функции и LeaveCriticalSection - в конце. Добавляю пару printf и убеждаюсь что падает на EnterCriticalSection, то есть почему-то вместо нее вызывается RtlLookupAtomInAtomTable. Сломанный mingw32, вернее его либы? Как с этим бороться?
исходник функции с моими дебажными строчками:
 

/*
* How it works:
* A pthread_t is a struct (2x32 bit scalar types on IA-32, 2x64 bit on IA-64)
* which is normally passed/returned by value to/from pthreads routines.
* Applications are therefore storing a copy of the struct as it is at that
* time.
*
* The original pthread_t struct plus all copies of it contain the address of
* the thread state struct ptw32_thread_t_ (p plus a reuse counter (x). Each
* ptw32_thread_t contains the original copy of it's pthread_t.
* Once malloced, a ptw32_thread_t_ struct is not freed until the process exits.
*
* The thread reuse stack is a simple LILO stack managed through a singly
* linked list element in the ptw32_thread_t.
*
* Each time a thread is destroyed, the ptw32_thread_t address is pushed onto the
* reuse stack after it's ptHandle's reuse counter has been incremented.
*
* The following can now be said from this:
* - two pthread_t's are identical if their ptw32_thread_t reference pointers
* are equal and their reuse counters are equal. That is,
*
* equal = (a.p == b.p && a.x == b.x)
*
* - a pthread_t copy refers to a destroyed thread if the reuse counter in
* the copy is not equal to the reuse counter in the original.
*
* threadDestroyed = (copy.x != ptw32_thread_t *)copy.p)->ptHandle.x)
*
*/

/*
* Pop a clean pthread_t struct off the reuse stack.
*/
pthread_t
ptw32_threadReusePop (void)
{
pthread_t t = {NULL, 0};

fprintf(stdout,"Now we will crash :(\n");
fflush(stdout);

EnterCriticalSection (&ptw32_thread_reuse_lock);
fprintf(stdout,"And we don't get here :(\n");
fflush(stdout);

if (PTW32_THREAD_REUSE_EMPTY != ptw32_threadReuseTop)
{
ptw32_thread_t * tp;

tp = ptw32_threadReuseTop;

ptw32_threadReuseTop = tp->prevReuse;

if (PTW32_THREAD_REUSE_EMPTY == ptw32_threadReuseTop)
{
ptw32_threadReuseBottom = PTW32_THREAD_REUSE_EMPTY;
}

tp->prevReuse = NULL;

t = tp->ptHandle;
}

LeaveCriticalSection (&ptw32_thread_reuse_lock);

return t;

}

версия компилера
 
 
~/cpp/snmpt/src/pthreads $ i586-mingw32msvc-g++ --version
i586-mingw32msvc-g++ (GCC) 4.4.4
Copyright (C) 2010 Free Software Foundation, Inc.
Это свободно распространяемое программное обеспечение. Условия копирования
приведены в исходных текстах. Без гарантии каких-либо качеств, включая
коммерческую ценность и применимость для каких-либо целей.

~/cpp/snmpt/src/pthreads $ i586-mingw32msvc-gcc --version
i586-mingw32msvc-gcc (GCC) 4.4.4
Copyright (C) 2010 Free Software Foundation, Inc.
Это свободно распространяемое программное обеспечение. Условия копирования
приведены в исходных текстах. Без гарантии каких-либо качеств, включая
коммерческую ценность и применимость для каких-либо целей.

ramsit

CamelCase вырвиглазен

elenangel

ты это в адрес ptw32_threadReusePop?

conv3rsje

собираю программу с pthreads-win32
Вроде он тухлый, не?
Не лучше ли будет вот это?

elenangel

за наводку спасибо, эту либу я посмотрю. однако косяк не изза pthread а из-за странной линковки.

conv3rsje

В том и дело, что там вся либа в одном .h файле умещается.
Так что вопрос с линковкой не должен возникнуть.

elenangel

да, косяк не в линковке был. разобрался)
оказывается если pthreads линкуешь статически то нужно делать #include <implement.h> и далее вызов ptw32_processInitialize до первого использования либы. Иначе она обращается к неинициализированным CRITICAL_SECTION из-за чего и возникает такое странное поведение.

elenangel

Не лучше ли будет вот это?
попробовал, все бы ничего, но
Windows Server 2003 and Windows XP/2000: Condition variables are not supported.

а либа их использует :(
Оставить комментарий
Имя или ник:
Комментарий: