CoCreateInstance在控制台应用程序中挂起

时间:2015-07-23 09:53:36

标签: c visual-c++ com firefox-addon stdin

以下是简短的重现样本:

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管道与它通信。

现在最有趣的事情。如果使用cmd.exe(例如)启动此EXE,则无法重现该问题。它仅在Firefox浏览器启动时才会重现。 即使我推出了EXE,我也不会重现这个问题,以防我评论网络电话并使用Sleep(10000)代替它。

目标COM组件处于单独的进程中。

所以,以及#34;挂起&#34; CoCreateInstance我们需要: 1. Windows XP 2. Firefox推出的流程 3.流程&#39;主线程被fread调用锁定。

会发生什么以及可以在这做什么?

来自我的真实应用程序的堆栈跟踪:

Worker Thread   Win32 Thread    sxs.dll!__ioinit    Normal
ntdll.dll!_KiFastSystemCallRet@0()   
ntdll.dll!_NtQueryVolumeInformationFile@20()     
kernel32.dll!_GetFileType@4()    
sxs.dll!__ioinit()   
sxs.dll!__CRT_INIT@12()  
sxs.dll!DllStartup_CrtInit(struct HINSTANCE__ *,unsigned long,void *)    
sxs.dll!__SxsDllMain@12()    
ntdll.dll!_LdrpCallInitRoutine@16()  
ntdll.dll!_LdrpRunInitializeRoutines@4()     
ntdll.dll!_LdrpLoadDll@24()  
ntdll.dll!_LdrLoadDll@16()   
kernel32.dll!_LoadLibraryExW@12()    
kernel32.dll!_LoadLibraryW@4()   
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 C ++的fread实现在零句柄(stdin)上调用_lock_fh,然后在_read_nolock调用中锁定线程(尝试从stdin读取)。我想问题就在这里...当主线程从fread退出时 - CoCreateInstance返回。

1 个答案:

答案 0 :(得分:0)

很酷的工作,我认为你需要这样做:

CoInitializeEx(null, COINIT_APARTMENTTHREADED);

正如在此处所做的那样:https://developer.mozilla.org/en-US/docs/Mozilla/js-ctypes/Examples/Using_COM_from_js-ctypes