2012-01-24 25 views
5

Ho un problema in cui la nostra applicazione si blocca sulle macchine dei nostri clienti che sono in servizio da giorni senza risolvere. Il problema sorge in modo abbastanza casuale da quello che abbiamo visto, anche se potrebbe non essere vero. Il cliente segnala inoltre che la CPU raggiunge il picco quando l'applicazione si blocca.Hang in applicazione COM con plug-in C#

Il problema è che non ho idea di dove l'applicazione non funzioni (in sospeso). Abbiamo anche un paio di plugin scritti in C# come plugin per l'applicazione COM principale.

Sono riuscito a convincere il cliente a prendere un MiniDump con ProcExp su una macchina in cui si è verificato il problema. Tuttavia, non sono molto familiare con WinDBG o MiniDumps. Ho eseguito !analyze -v e !analyze -v -hang, che produce un po 'di output, incluso lo stack di seguito. Per quello che sono in grado di dire, sembra che l'applicazione stia passando in uno dei nostri plugin C# (CLR) e poi di nuovo a COM, che dovrebbe essere un'interfaccia per l'applicazione principale disponibile per i plugin. Ma allora cosa? È possibile dire qualcosa di più da questo stack?

L'applicazione principale è scritta in VB6 se questo è importante.

0012da70 7e3693e9 7e3693a8 0012daf0 00000000 ntdll!KiFastSystemCallRet 
0012da9c 7e37a43b 0012daf0 00000000 0000000f user32!NtUserPeekMessage+0xc 
0012dac8 7348e6fd 0012daf0 00000000 0000000f user32!PeekMessageA+0xeb 
0012db1c 77532a9c 00d03774 00000000 00000000 msvbvm60!CMsgFilter::MessagePending+0x21f 
0012db60 77532a48 00000102 0012dbec 00000001 ole32!CCliModalLoop::HandlePendingMessage+0x40 
0012dba8 7751eda6 80010116 80010115 00000000 ole32!CCliModalLoop::HandleWakeForMsg+0x46 
0012dbbc 77547297 0012ddf0 00000001 0012dbe8 ole32!CCliModalLoop::BlockFn+0x8b 
0012dc30 0ae8a2fd 00000002 00000001 00000001 ole32!CoWaitForMultipleHandles+0xcf 
0012dc50 0ae8a264 00000000 00000001 00000001 mscorwks!NT5WaitRoutine+0x51 
0012dcbc 0ae8a1c8 00000001 0012ddf0 00000000 mscorwks!MsgWaitHelper+0xa5 
0012dcdc 0af3ccd0 00000001 0012ddf0 00000000 mscorwks!Thread::DoAppropriateAptStateWait+0x28 
0012dd60 0af3cd65 00000001 0012ddf0 00000000 mscorwks!Thread::DoAppropriateWaitWorker+0x13c 
0012ddb0 0ae8c026 00000001 0012ddf0 00000000 mscorwks!Thread::DoAppropriateWait+0x40 
0012de00 0ae90f4c 00000001 05ae5c80 0012de60 mscorwks!Thread::JoinEx+0x86 
0012de10 0b00ea40 00000001 00000001 5bdf0a2d mscorwks!Thread::Join+0x14 
0012de60 0af0b9a7 00000001 0012deb0 0af0ba10 mscorwks!RCWCleanupList::CleanupWrappersInCurrentCtxThread+0x15a 
0012de6c 0af0ba10 001df674 0012df10 5bdf0afd mscorwks!RCW::Initialize+0x78 
0012deb0 0af0b6a7 001df674 0012df10 5bdf0b6d mscorwks!RCW::CreateRCW+0x84 
0012df20 0af0b7b5 00000000 0012df5c 5bdf0b21 mscorwks!COMInterfaceMarshaler::CreateObjectRef+0x45 
0012df6c 0ae892a8 5bdf3065 0012e6c8 0012e6c8 mscorwks!COMInterfaceMarshaler::FindOrCreateObjectRef+0xac 
0012e428 0ae89444 001df658 11a11014 00000001 mscorwks!GetObjectRefFromComIP+0x1ec 
0012e448 0ae894ab 05b3b0a8 001df658 0e896204 mscorwks!UnmarshalObjectFromInterface+0x19 
0012e464 0af164d1 0012e6c8 0012e6ac 0af164c1 mscorwks!InterfaceMarshalerBase::ConvertSpaceNativeToCLR+0x30 
0012e470 0af164c1 0012e748 0012e738 5bdf32e1 mscorwks!DefaultMarshalOverrides<InterfaceMarshalerBase>::ReturnCLRFromNativeRetval+0xb 
0012e6ac 0aeb4bff 11741a76 0012e734 0012e74c mscorwks!RunML+0x9ac 
0012e780 11740172 05ae5c80 0012e7d4 501b6046 mscorwks!CLRToCOMWorker+0x25f 
... 
... Stack begins down here in our main COM application. 

Edit 1: Alcune riflessioni che ho dopo aver letto alcune altre post del forum. Mi sembra che l'impiccagione venga introdotta seguendo un marshalling di tipi di dati da .NET a COM. Ora ho letto su another problem che sembrava originare dal fatto che le variabili locali passate in un metodo COM sono state spazzate via e quindi il tempo di esecuzione VB6 aveva problemi a gestire la memoria deallocated. Quell'altro post non era esattamente questo problema, ma mi ha fatto riflettere.

Nel codice .NET mettere in COM abbiamo questo tipo di codice

void SomeNETMethod(MyObject obj, bool doIt) { 
    string someString = obj.SomeString; 
    this.myComComponent.DoItInCOM(ref someString, ref doIt); // This is where it hangs. 
} 

Può la ref bool così come la diretta da metodo a metodo passato parametro hanno nulla a che fare con tutto questo? Come potete vedere, sto inciampando nell'oscurità qui ...

+1

VB6 e fili sono acqua e fuoco. Sembra deadlock quando il thread principale VB6 smette di pompare il loop dei messaggi. È necessario il debugger VB6 per scoprire cosa sta facendo. –

+0

@HansPassant questi problemi potrebbero verificarsi anche se i nostri plugin C# non sono multi-thread? L'unico thread 'altro' che riesco a vedere entra in gioco qui è il thread GC, ma presumo che non sia questo il problema. – lbergnehr

+1

Esiste un DoEvents da qualche parte nel codice VB6 che viene chiamato? Come sottolinea @HansPassant, il thread principale VB6 potrebbe non essere realmente compatibile con il thread C# (specialmente se ha un'interazione WinForms o WPF) e un po 'di magia viene eseguita dietro le quinte nel codice di interoperabilità per legare insieme i thread.In passato ho scoperto che qualsiasi DoEvent chiamato da un'applicazione VB6 chiamata da DotNet può portare a una specie di blocco/blocco. –

risposta

0

Rivedere il metodo "DoItInCOM" mentre il dump del kernel indica che viene visualizzata una finestra di dialogo modale (probabilmente a causa di un errore nella chiamata al metodo COM .)

I parametri .NET vengono correttamente convogliati sul lato COM. Se stavi usando un tipo di C# non standard, potresti avere un problema con la serializzazione, ma non è questo il caso.

Se si inserisce un gestore "On Error Goto" nel codice VB, è probabile che vengano eliminati errori che genererebbero un messaggio sul thread dell'interfaccia utente. Se l'errore è di livello inferiore (il runtime VB lo sta lanciando) sarà necessario risolvere il problema direttamente con le correzioni al componente COM. Rivedere anche il Visualizzatore eventi di Windows per i messaggi di origintatin VB Runtime per ulteriori informazioni.