2015-07-23 7 views
1

Ниже приводится короткая выборка воспроизводимый:CoCreateInstance висит в консольном приложении

DWORD WINAPI _threadTest (LPVOID) 
{ 
    Sleep (2000); 
    CoInitialize(0); 
    CoCreateInstance(...); // <---- hangs here 
    return 0; 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    CoInitialize (0); 

    CreateThread (0, 0, _threadTest, 0, 0, 0); 

    uint32_t size = 0; 
    fread (&size, 4, 1, stdin); 

    return 0; 
} 

Зв Прежде всего, проблема возникает только в Windows XP.

Во-вторых, это консольное приложение действительно является частью расширения браузера Firefox. Расширение связывается с ним, используя трубы stdin/stdout.

Теперь самое интересное. Проблема не воспроизводится, если этот EXE запускается с использованием cmd.exe (например). Он воспроизводится только в том случае, если он запущен браузером Firefox. Проблема не воспроизводится, даже если EXE запускается Firefox в случае, если я прокомментирую fread-вызов и вместо него использую Sleep (10000).

Целевой COM-компонент находится в отдельном процессе.

Так, чтобы "повесить" CoCreateInstance нам нужно: 1. Windows XP 2. Процесс запущен Firefox 3. Процесс основной поток заблокирован Fread вызова.

Что происходит и что можно сделать здесь?

Стек след от моего реального приложения:

Worker Thread Win32 Thread sxs.dll!__ioinit Normal 
[email protected]() 
[email protected]()  
[email protected]()  
sxs.dll!__ioinit() 
[email protected]() 
sxs.dll!DllStartup_CrtInit(struct HINSTANCE__ *,unsigned long,void *)  
[email protected]()  
[email protected]() 
[email protected]()  
[email protected]() 
[email protected]() 
[email protected]()  
[email protected]() 
oleaut32.dll!OaLoadLibraryAW(char const *,unsigned short const *)  
oleaut32.dll!GetRedirectionProcAddress(char const *,void * *)  
oleaut32.dll!MapIIDToFusionCLSID(struct _GUID const &,struct _GUID *)  
oleaut32.dll!ProxyStubCLSIDOfInterface(struct _GUID const &,struct _GUID *) 
oleaut32.dll!CPSFactory::CreateProxy(struct IUnknown *,struct _GUID const &,struct IRpcProxyBuffer * *,void * *)  
ole32.dll!CStdMarshal::CreateProxy(struct _GUID const &,struct IRpcProxyBuffer * *,void * *,int *) 
ole32.dll!CStdMarshal::MakeCliIPIDEntry(struct _GUID const &,struct tagSTDOBJREF *,class OXIDEntry *,struct tagIPIDEntry * *)  
ole32.dll!CStdMarshal::UnmarshalIPID(struct _GUID const &,struct tagSTDOBJREF *,class OXIDEntry *,void * *) 
ole32.dll!CStdMarshal::Finish_RemQIAndUnmarshal1(struct tagSQIResult *,struct tagQICONTEXT *)  
ole32.dll!CStdMarshal::Finish_QueryRemoteInterfaces(struct tagSQIResult *,struct tagQICONTEXT *)  
ole32.dll!CStdMarshal::QueryRemoteInterfaces(unsigned short,struct _GUID *,struct tagSQIResult *)  
ole32.dll!CStdIdentity::CInternalUnk::QueryMultipleInterfaces(unsigned long,struct tagMULTI_QI *)  
ole32.dll!CStdIdentity::CInternalUnk::QueryInterface(struct _GUID const &,void * *) 
FmBrowserHelper.exe!_com_ptr_t<_com_IIID<IWGUrlReceiver,&_GUID_454a4044_16ec_4d64_9069_c5b8832b7b55> >::CreateInstance(const _GUID & rclsid, IUnknown * pOuter, unsigned long dwClsContext) Line 592 

Microsoft Visual Fread реализация C++ s вызывает _lock_fh на нулевой ручке (стандартный ввод) перед блокировкой нити _read_nolock вызова (пытаясь читать из стандартного ввода). Я предполагаю, что проблема где-то здесь ... Когда основной поток завершает работу с fread - возвращается CoCreateInstance.

+1

Я также создал отчет Bugzilla здесь: https://bugzilla.mozilla.org/show_bug .cgi? id = 1186095 –

+1

«Что можно сделать?» Прежде всего вам нужны стеки вызовов в замороженном процессе. Неясно, замораживается ли COM-сообщение, или сам объект зависает во время создания экземпляра. Тогда, очевидно, ваш основной поток не совместим с COM/совместимым: если вы делаете это STA, тогда вам нужно отправлять туда сообщения, а не «fread». –

+0

К сожалению, стеки вызовов не содержат никакой полезной информации, потому что по какой-либо неизвестной причине для системных DLL нет символов, которые по неизвестной причине не были (я лицензировал XP, но это не английский, может быть, это причина). Никаких символов для этих dll (осталось): advapi32.dll, ntdll.dll, kernel32.dll. –

ответ

0

Прохладный работы, я думаю, что вам нужно сделать:

CoInitializeEx(null, COINIT_APARTMENTTHREADED); 

Как было сделано здесь: https://developer.mozilla.org/en-US/docs/Mozilla/js-ctypes/Examples/Using_COM_from_js-ctypes

+0

Я вообще не использую js-ctypes. –

+0

@ AlexanderDyagilev - это то, что они используют 'CoInitializeEx', этот код работает с ChromeWorker, которые являются другими потоками. Дайте ему выстрел не повредит. – Noitidart

+1

CoInitializeEx (nullptr, COINIT_APARTMENTTHREADED) совпадает с CoInitialize (0). Пожалуйста, не тратьте свое время. Просто попробовал - не помогло. –

Смежные вопросы