none
Why would WindowsFormsApplicationBase.Run(Strings{}, commandline) be called in MyApplication.Shutdown event? RRS feed

  • Question

  • I am having trouble with an ActiveX control that worked just fine in VS2003.  In VS2005 and later, I get a First Chance Exception in a DLL that is called from the OCX in the Shutdown Event.  I then get the same exception in the OCX.  I can see that all the interopservices stuff does releaseobject, etc, so I don't see how there can be anything left to clean up or trap.  Still, I need to find out how to keep this error from crashing the program as a stopgap.  What kind of code can I put into the shutdown event to stop this error from displaying (it goes into an infinite loop of error messsages).  Secondly, does anyone know where I could check to find exactly what is wrong?  It may have to do with code in the OCX trying to free the DLL.  Thanks.
    Friday, March 13, 2009 4:35 PM

Answers

  • You may have some RCW being finalized after your Delphi support DLL is unloaded. Read your debug output to check for DLL unload messages. Generally a COM Server DLL should not return S_OK for DllCanUnloadNow if there is a COM object still using it.

    When you are done with RCW, use System.Runtime.InteropServices.Marshal.ReleaseComObject to released it. Read Managing Object Lifetime and Reliability Best Practices for more details.

    MSMVP VC++
    • Marked as answer by Zhi-Xin Ye Friday, March 20, 2009 3:08 AM
    Wednesday, March 18, 2009 12:40 AM

All replies

  • Don't worry about first chance exceptions. Most of time what you see are communication signals.

    If you have crash or other kind exception, it will help others to reproduce and investigate your problem if you post some code/errormessage/call stack/debug output.



    MSMVP VC++
    Monday, March 16, 2009 6:49 PM
  • If you get an "infinite loop of error messages", you are most likely well beyond the stage of a first chance exception.  The ActiveX control presumably did some nasty like corrupt the heap, as they so commonly do.  But that's just a guess, not sharing any relevant information about what you see is a mistake.
    Hans Passant.
    Tuesday, March 17, 2009 12:44 AM
    Moderator
  • Ok,

    I know I am a newbie with this low level of logging, but here is what I have.  I created the OCX and the DLL in Delphi, therefore, I have no PDB file.  I have MAP files that I use the MS utility MapSym or whatever to convert it to a SYM file. It says they are loaded, but differently from what I see with a PDB.  I know it has the symbols from the assembly code that shows me at least some function calls.

    This is the callstack where I break just before the crash.  My breakpoint is in the MyApplication.Shutdown Event handler for the project where I have a line of code that prints out the stack, mostly just to have a line to stop on.

    This is the actual stack:

     WindowsApplication4.exe!WindowsApplication1.My.MyApplication.MyApplication_Shutdown(Object sender = {WindowsApplication1.My.MyApplication}, System.EventArgs e = {System.EventArgs}) Line 14    Basic
         Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnShutdown() + 0x27 bytes    
         Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel() + 0xf6 bytes    
         Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(string[] commandLine) + 0x68 bytes    
         mscoree.dll!__CorExeMain@0()  + 0x34 bytes    
         kernel32.dll!_BaseProcessStart@4()  + 0x23 bytes

    This is my debug.print of the callstack called from inside the Shutdown event handler

    OnShutdown!
       at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
       at System.Environment.get_StackTrace()
       at WindowsApplication1.My.MyApplication.MyApplication_Shutdown(Object sender, EventArgs e) in C:\Data\Projects\WindowsApplication4\WindowsApplication4\ApplicationEvents.vb:line 14
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnShutdown()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
       at WindowsApplication1.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81

    This is my first, first-chance exception:

    First-chance exception at 0x03b5517a (myLog.dll) in WindowsApplication4.exe: 0xC0000005: Access violation reading location 0x03bd241c.


    Here is the callstack.  I assume the Tlist.IndexOf line is the error?  Trying to point to an item in an index that is not there anymore?  I'm lost since both the OCX and the DLL should be long disposed of.  It makes no sense.  Axhost dispose was run by Visual Studio. My OCX loads the myLog.DLL which calls into another 3rd party utility (Codesite).   The dll looks like it is trying to get the list of CodeSite objects that were created, TList is a Delphi type or class for a list.  The OCX is then destroying ones it used internally.  The OCX gives its own error after this in the next section.  NOTE: This OCX works in every other environment except for Visual Studio 2005 and above.

    >    myLog.dll!TList.IndexOf()  + 0x6 bytes    
         [Frames below may be incorrect and/or missing, no symbols loaded for myLog.dll]    
         DOIT.OCX!TCodeSiteObject.Destroy()  + 0x27 bytes    
         DOIT.OCX!TObject.Free()  + 0xb bytes    
         DOIT.OCX!FinalizeUnits()  + 0x38 bytes    
         DOIT.OCX!@Halt0()  + 0x5e bytes    
         ntdll.dll!_LdrpCallInitRoutine@16()  + 0x14 bytes    
         ntdll.dll!_LdrShutdownProcess@0()  - 0xfe bytes    
         kernel32.dll!__ExitProcess@4()  + 0x42 bytes    
         kernel32.dll!7c81cb0e()     
         mscorwks.dll!SafeExitProcess()  + 0xb7 bytes    
         mscorwks.dll!DisableRuntime()  - 0x1a57c8 bytes    
         mscorwks.dll!__CorExeMain@0()  + 0x117 bytes    
         mscoree.dll!__CorExeMain@0()  + 0x34 bytes    
         kernel32.dll!_BaseProcessStart@4()  + 0x23 bytes   

    Assembly code of where the first chance error occurs associated with above stack trace:

    TList.IndexOf:
    03B55174 53               push        ebx  
    03B55175 33 C9            xor         ecx,ecx
    03B55177 EB 01            jmp         TList.IndexOf+6 (3B5517Ah)
    03B55179 41               inc         ecx  
    03B5517A 3B 48 08         cmp         ecx,dword ptr [eax+8]
    03B5517D 7D 08            jge         TList.IndexOf+13h (3B55187h)
    03B5517F 8B 58 04         mov         ebx,dword ptr [eax+4]
    03B55182 3B 14 8B         cmp         edx,dword ptr [ebx+ecx*4]
    03B55185 75 F2            jne         TList.IndexOf+5 (3B55179h)
    03B55187 3B 48 08         cmp         ecx,dword ptr [eax+8]
    03B5518A 75 03            jne         TList.IndexOf+1Bh (3B5518Fh)
    03B5518C 83 C9 FF         or          ecx,0FFFFFFFFh
    03B5518F 8B C1            mov         eax,ecx
    03B55191 5B               pop         ebx  
    03B55192 C3               ret              
    03B55193 90               nop          

    Next Error:

    First-chance exception at 0x03553a06 (DOIT.OCX) in WindowsApplication4.exe: 0xC0000005: Access violation reading location 0x03a46d14.


    This error repeats over and over and over.  I can't get past it.  I believe it is trying to free the Codesite object from above.

    >    DOIT.OCX!TObject.Free()  + 0x6 bytes    
         [Frames below may be incorrect and/or missing, no symbols loaded for DOIT.OCX]    
         DOIT.OCX!@Halt0()  + 0x5e bytes    
         ntdll.dll!_LdrpCallInitRoutine@16()  + 0x14 bytes    
         ntdll.dll!_LdrShutdownProcess@0()  - 0xfe bytes    
         kernel32.dll!__ExitProcess@4()  + 0x42 bytes    
         kernel32.dll!7c81cb0e()     
         mscorwks.dll!SafeExitProcess()  + 0xb7 bytes    
         mscorwks.dll!DisableRuntime()  - 0x1a57c8 bytes    
         mscorwks.dll!__CorExeMain@0()  + 0x117 bytes    
         mscoree.dll!__CorExeMain@0()  + 0x34 bytes    
         kernel32.dll!_BaseProcessStart@4()  + 0x23 bytes 

    This is the assembly code: 

    TObject.Free:
    03553A00 85 C0            test        eax,eax
    03553A02 74 07            je          TObject.Free+0Bh (3553A0Bh)
    03553A04 B2 01            mov         dl,1
    03553A06 8B 08            mov         ecx,dword ptr [eax]
    03553A08 FF 51 FC         call        dword ptr [ecx-4]
    03553A0B C3        

    Can you help me get a little further?  What can I do from here?  Can you see what is causing me my problem or tell me how to back up and find something from these memory addresses that will actually tell me what is going on?  I really don't understand how to "back up the stack" to find things, for example what is being freed above with (3553A0Bh)  Somewhere it must tell me what that address points to?

    Lastly, can't I compile this program in such a way as to avoid this error or trap for it and ignore it?  It is driving me crazy that I can't just supress it somehow.   There must be a way in the shutdown event or somewhere to basically say, "I know this error is coming, please ignore it and close the app gracefully" :)  Thanks so much for the help.  I am really still learning and have that helpless "I feel incompetent even asking these questions" feeling.

    Fred
    Tuesday, March 17, 2009 10:41 PM
  • The Delphi code is bombing.  You'll need to find a Delphi support forum.
    Hans Passant.
    Wednesday, March 18, 2009 12:17 AM
    Moderator
  • You may have some RCW being finalized after your Delphi support DLL is unloaded. Read your debug output to check for DLL unload messages. Generally a COM Server DLL should not return S_OK for DllCanUnloadNow if there is a COM object still using it.

    When you are done with RCW, use System.Runtime.InteropServices.Marshal.ReleaseComObject to released it. Read Managing Object Lifetime and Reliability Best Practices for more details.

    MSMVP VC++
    • Marked as answer by Zhi-Xin Ye Friday, March 20, 2009 3:08 AM
    Wednesday, March 18, 2009 12:40 AM
  • Than you for the help.  I went back to school to learn more about DLLs and the Interop.  It looks like a timing issue that I solved so far by intercepting the DLLProc procedure in the DLL and looking for PROCESS_DETACH and making sure to put some cleanup code there.  Next I'll learn more about threading and makde sure I deal with DllCanUnloadNow properly.  Thanks for the help!  Very exciting when you compile and it runs after 2 weeks of crashing :)
    Friday, March 20, 2009 3:36 PM