Зависание в CoUninitialize
От: Voinov Россия http://www.svoinov.ru
Дата: 13.04.11 09:09
Оценка:
Hi All,

Есть серверное приложение с кучей одинаковых потоков. В каждом потоке в начале вызывается CoInitialize, а в конце CoUninitialize. Сами потоки выполняют некоторые скрипты, где могут создаваться различные COM объекты. Изредка вызов CoUninitialize зависает и не даёт потоку нормально завершиться. При этом стек вызовов имеет такой вид:

---- Registers ----
EAX=00000000 EBX=7C81A360 ECX=05A6FE28 EDX=7C82860C
ESI=00000000 EDI=05A6FBD8 ESP=05A6FB98 EBP=05A6FC00
CS=001B DS=0023
SS=0023 ES=0023
FS=003B GS=0000
EIP=7C82860C
EFLAGS=00000206
---- Callstack ----
# 0x7C82860C, KiFastSystemCallRet+0, <no source info>, ntdll
# 0x77E424FD, Sleep+15, <no source info>, kernel32
# 0x77C9180B, NdrEncapsulatedUnionMarshall+21317, <no source info>, RPCRT4
# 0x77691EB3, CreateErrorInfo+4980, <no source info>, ole32
# 0x77691F8E, CreateErrorInfo+5199, <no source info>, ole32
# 0x77691F53, CreateErrorInfo+5140, <no source info>, ole32
# 0x77691F26, CreateErrorInfo+5095, <no source info>, ole32
# 0x7769182A, CreateErrorInfo+3307, <no source info>, ole32
# 0x7769174C, CreateErrorInfo+3085, <no source info>, ole32
# 0x776BCE40, CoUninitialize+407, <no source info>, ole32
# 0x776BCDF2, CoUninitialize+329, <no source info>, ole32
# 0x00409AB1, ScriptThreadProc+577, scriptthread.cpp [.text+0x00008AB1] 94+0, surrogate

Т.е. оно зависает в каком-то Sleep, вызываемом из NdrEncapsulatedUnionMarshall.
Сталкивался ли кто-нибудь с подобным и как это можно побороть?
Re: Зависание в CoUninitialize
От: Vi2 Удмуртия http://www.adem.ru
Дата: 13.04.11 09:51
Оценка:
Здравствуйте, Voinov, Вы писали:

V>Есть серверное приложение с кучей одинаковых потоков. В каждом потоке в начале вызывается CoInitialize, а в конце CoUninitialize. Сами потоки выполняют некоторые скрипты, где могут создаваться различные COM объекты. Изредка вызов CoUninitialize зависает и не даёт потоку нормально завершиться. При этом стек вызовов имеет такой вид:


V>...

V># 0x7769174C, CreateErrorInfo+3085, <no source info>, ole32
V># 0x776BCE40, CoUninitialize+407, <no source info>, ole32
V># 0x776BCDF2, CoUninitialize+329, <no source info>, ole32
V># 0x00409AB1, ScriptThreadProc+577, scriptthread.cpp [.text+0x00008AB1] 94+0, surrogate

V>Т.е. оно зависает в каком-то Sleep, вызываемом из NdrEncapsulatedUnionMarshall.

V>Сталкивался ли кто-нибудь с подобным и как это можно побороть?

Посмотри здесь решение Бага в CoUninitialize
Автор: Коваленко Дмитрий
Дата: 18.09.06
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[2]: Зависание в CoUninitialize
От: Voinov Россия http://www.svoinov.ru
Дата: 14.04.11 11:43
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Здравствуйте, Voinov, Вы писали:


V>>Есть серверное приложение с кучей одинаковых потоков. В каждом потоке в начале вызывается CoInitialize, а в конце CoUninitialize. Сами потоки выполняют некоторые скрипты, где могут создаваться различные COM объекты. Изредка вызов CoUninitialize зависает и не даёт потоку нормально завершиться. При этом стек вызовов имеет такой вид:


V>>...

V>># 0x7769174C, CreateErrorInfo+3085, <no source info>, ole32
V>># 0x776BCE40, CoUninitialize+407, <no source info>, ole32
V>># 0x776BCDF2, CoUninitialize+329, <no source info>, ole32
V>># 0x00409AB1, ScriptThreadProc+577, scriptthread.cpp [.text+0x00008AB1] 94+0, surrogate

V>>Т.е. оно зависает в каком-то Sleep, вызываемом из NdrEncapsulatedUnionMarshall.

V>>Сталкивался ли кто-нибудь с подобным и как это можно побороть?

Vi2>Посмотри здесь решение Бага в CoUninitialize
Автор: Коваленко Дмитрий
Дата: 18.09.06


Спасибо, но к сожалению, не прокатило. Есть ещё идеи?
Re[3]: Зависание в CoUninitialize
От: Vi2 Удмуртия http://www.adem.ru
Дата: 14.04.11 12:10
Оценка:
Здравствуйте, Voinov, Вы писали:

V>Спасибо, но к сожалению, не прокатило. Есть ещё идеи?


Так основная идея — во время вызова CoUninitialize есть "живой" СОМ объект. Так что поищи его.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re: Зависание в CoUninitialize
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 17.04.11 14:48
Оценка:
Здравствуйте, Voinov, Вы писали:

V>Есть серверное приложение с кучей одинаковых потоков. В каждом потоке в начале вызывается CoInitialize, а в конце CoUninitialize. Сами потоки выполняют некоторые скрипты, где могут создаваться различные COM объекты. Изредка вызов CoUninitialize зависает и не даёт потоку нормально завершиться.


Покажи, пожалуйста, параметры инициализации COM в основном и рабочих потоках — там какая "потоковая" модель указывается?

А эти потоки работают строго со своим набором объектов, или они могут юзать/создавать COM-объекты разделяемые другими потоками? То есть поток создал объект, а потом его где-то на глобальном уровне приложения закэшировал для повторного использования. Такого нет?
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re: Зависание в CoUninitialize
От: Igor_Sokolov  
Дата: 19.04.11 10:10
Оценка:
А зачем, собственно, вообще может понадобиться вызывать CoUninitialize?
просто интересуюсь — всегда игнорировал
Re[2]: Зависание в CoUninitialize
От: Vi2 Удмуртия http://www.adem.ru
Дата: 19.04.11 11:42
Оценка: +1
Здравствуйте, Igor_Sokolov, Вы писали:

I_S>А зачем, собственно, вообще может понадобиться вызывать CoUninitialize?

I_S>просто интересуюсь — всегда игнорировал

"Typically, the COM library is initialized on a thread only once. Subsequent calls to CoInitialize or CoInitializeEx on the same thread will succeed, as long as they do not attempt to change the concurrency model, but will return S_FALSE. To close the COM library gracefully, each successful call to CoInitialize or CoInitializeEx, including those that return S_FALSE, must be balanced by a corresponding call to CoUninitialize. However, the first thread in the application that calls CoInitialize(0) or CoInitializeEx(COINIT_APARTMENTTHREADED) must be the last thread to call CoUninitialize(). If the call sequence is not in this order, then subsequent calls to CoInitialize on the STA will fail and the application will not work." (с) MSDN

"Как правило, библиотека COM инициализируется в потоке только один раз. Последующие вызовы CoInitialize или CoInitializeEx в том же потоке будут успешны, если они не будут пытаться изменить потоковую модель синхронизации СОМ, но с возвратом S_FALSE. Чтобы закрыть библиотеку COM правильно, каждый успешный вызов CoInitialize или CoInitializeEx, в том числе вернувший S_FALSE, должен быть уравновешен соответствующим вызовом CoUninitialize. Кроме того, первый поток в приложении, который вызывает CoInitialize(0) или CoInitializeEx(COINIT_APARTMENTTHREADED) должен быть последним потоком, вызвавшим CoUninitialize(). Если последовательность вызовов происходит не в таком порядке, то последующие вызовы CoInitialize на STA не будут успешны, и приложение не будет работать." (с) MSDN

Удовлетворять требованию парности любых скобок у программиста должно быть на уровне автоматизма, не дожидаясь внешних принуждений от кого бы то ни было.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.