C#代码如下:

private void button2_Click(object sender, System.EventArgs e)
{
        System.Threading.Thread thread = new System.Threading.Thread( new                       System.Threading.ThreadStart(this.ShowOCX2));
        thread.SetApartmentState(System.Threading.ApartmentState.STA);
        thread.Start();
}

 

private void ShowOCX2()
{
        Form2 form = new Form2();
        form.ShowDialog();
}

Form2中是放入了一个ocx(delphi写的一个空ocx,任何自己的代码都没有)。

现在症状是,点击button2之后,出现了form2,直接关闭form2;再次点击button2,程序立刻crash掉。

抓dump(启用了pageheap),发现下面代码:(注意红色的)

Thread 4
Current frame: OCX2Proj1+0x3402
ChildEBP RetAddr Caller,Callee
0513f808 7c9237bf ntdll!ExecuteHandler2+0x26
0513f82c 7c92378b ntdll!ExecuteHandler+0x24, calling ntdll!ExecuteHandler2
0513f850 7c957860 ntdll!RtlDispatchException+0xb1, calling ntdll!RtlpExecuteHandlerForException
0513f874 060e3407 OCX2Proj1+0x3407
0513f880 7c9211a7 ntdll!LdrpCallInitRoutine+0x14
0513f884 7c93e6f4 ntdll!LdrUnloadDll+0x41c, calling ntdll!LdrpCallInitRoutine
0513f888 7c80abf7 kernel32!FreeLibrary+0x3f, calling kernel32!LdrUnloadDll
0513f890 769c3456 ole32!CClassCache::CFinishComposite::Finish+0x1d
0513f894 7c988c37 ntdll!RtlpDphNeedToTrimDelayedFreeQueue+0x3f, calling ntdll!RtlLeaveCriticalSection
0513f8a8 7c98acda ntdll!RtlpDphNormalHeapFree+0xb1, calling ntdll!RtlpDphNeedToTrimDelayedFreeQueue
0513f8bc 7c98770b ntdll!RtlpDebugPageHeapLeaveCritSect+0x10, calling ntdll!RtlLeaveCriticalSection
0513f8c8 7c98af7d ntdll!RtlpDebugPageHeapFree+0x192, calling ntdll!RtlpDebugPageHeapLeaveCritSect
0513f8dc 7c92eafa ntdll!KiUserExceptionDispatcher+0xe, calling ntdll!RtlDispatchException
0513fbdc 060e3402 OCX2Proj1+0x3402 ====> Exception cxr@513f910
0513fb00 7c9306eb ntdll!RtlAllocateHeap+0xeac, calling ntdll!_SEH_epilog
0513fc70 7c9211a7 ntdll!LdrpCallInitRoutine+0x14
0513fc90 7c93e6f4 ntdll!LdrUnloadDll+0x41c, calling ntdll!LdrpCallInitRoutine
0513fcf4 7c939213 ntdll!LdrShutdownThread+0xd7, calling ntdll!LdrpCallInitRoutine
0513fcf8 7c80c096 kernel32!ExitThread+0x3e, calling kernel32!LdrShutdownThread
0513fd70 77d193e9 user32!NtUserPeekMessage+0xc

然后切换进去
0:004> .cxr 513f910
eax=f0f0f0f0 ebx=0000000f ecx=00000000 edx=f0f0f001 esi=06146590 edi=06149638
eip=060e3402 esp=0513fbdc ebp=0513fbf0 iopl=0 nv up ei ng nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010286
OCX2Proj1+0x3402:
060e3402 8b08 mov ecx,dword ptr [eax] ds:0023:f0f0f0f0=????????
0:004> kb
*** Stack trace for last set context - .thread/.cxr resets it
ChildEBP RetAddr Args to Child
WARNING: Stack unwind information not available. Following frames may be wrong.
0513fbf0 060e3f10 0513fc64 060e3cff 0513fc10 OCX2Proj1+0x3402
0513fc10 060e4246 0513fc70 0513fc60 06149664 OCX2Proj1+0x3f10
0513fc70 7c9211a7 060e0000 00000000 00000000 OCX2Proj1+0x4246
0513fc90 7c93e6f4 061467b0 060e0000 00000000 ntdll!LdrpCallInitRoutine+0x14
0513fd88 7c80abf7 060e0000 0513fdd0 0513fdf4 ntdll!LdrUnloadDll+0x41c
0513fd9c 769c3442 060e0000 0513fe18 769c3456 kernel32!FreeLibrary+0x3f
0513fda8 769c3456 0513fddc 76ab67e0 00000000 ole32!CClassCache::CDllPathEntry::CFinishObject::Finish+0x2f
0513fdbc 769b2557 76991ab0 00000000 00000000 ole32!CClassCache::CFinishComposite::Finish+0x1d
0513fe18 769b2243 0133d878 00000080 00000001 ole32!CClassCache::CleanUpDllsForApartment+0x1b5
0513fe44 769b2171 00000000 0513fe90 76ab67e8 ole32!FinishShutdown+0xcd
0513fe60 769af221 00000000 00000000 0133d878 ole32!ApartmentUninitialize+0x7e
0513fe78 769aee88 0513fe90 00000000 00000001 ole32!wCoUninitialize+0x41
0513fe94 769c31f0 76990000 769ad1a2 0513fec4 ole32!CoUninitialize+0x5b
0513fe9c 769ad1a2 0513fec4 769ad141 76990000 ole32!DoThreadSpecificCleanup+0x47
0513fea4 769ad141 76990000 00000003 00000000 ole32!ThreadNotification+0x37
0513fec4 769ad0e9 76990000 00000003 00000000 ole32!DllMain+0x147
0513fee4 7c9211a7 76990000 00000003 00000000 ole32!_DllMainCRTStartup+0x52
0513ff04 7c939213 769ad0a1 76990000 00000003 ntdll!LdrpCallInitRoutine+0x14
0513ff7c 7c80c096 00000000 00000000 01321d40 ntdll!LdrShutdownThread+0xd7
0513ffb4 7c80b688 00000000 00000000 00000000 kernel32!ExitThread+0x3e

最上面三行就是delphi写的那个空白ocx,下面三个是各自的代码:
0:004> u OCX2Proj1+0x4246
OCX2Proj1+0x4246:
060e4246 ?? ???
^ Memory access error in 'u OCX2Proj1+0x4246'


0:004> u OCX2Proj1+0x3f10
OCX2Proj1+0x3f10:
060e3f10 ?? ???
^ Memory access error in 'u OCX2Proj1+0x3f10'

0:004> u OCX2Proj1+0x3402
OCX2Proj1+0x3402:
060e3402 8b08 mov ecx,dword ptr [eax]
060e3404 ff51fc call dword ptr [ecx-4]
060e3407 c3 ret
060e3408 53 push ebx
060e3409 56 push esi
060e340a 57 push edi
060e340b 89c3 mov ebx,eax
060e340d 89d7 mov edi,edx

 

0:004> d [ecx-4]
fffffffc ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
0000000c ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
0000001c ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
0000002c ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
0000003c ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
0000004c ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
0000005c ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
0000006c ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????

 

郁闷之极,好像用VB写一个空OCX放到form上,然后thread调用起来,也有这个问题。哪位老大见过这个问题?貌似和Appartment有关?