none
Debugging crash that's not caught with try/catch? RRS feed

  • Question

  • Hi!

    I've got a COM object that kills my .NET app without triggerring any catch or windows "... has encountered a problem..." screen. It looks loke this:

    using System;
    using MGCPCBEngines;
    namespace Gerberkiller
      {
      class Program
        {
        [STAThread]
        static void Main(string[] args)
          {
          Gerber G = new Gerber();
          G.DesignFileName = @"<FileName>";
          GerberOutputFile GOF = G.OutputFiles.Add("<FileName>");
          GOF.ConductiveLayer = 1;
          GOF.ConductiveItems.Add(EEnginesConductiveItem.eengCondItemPlaneData);
          try
            {
            G.Go();
            }
          catch (Exception Ex)
            {
            Console.WriteLine(Ex.Message);
            }
          finally
            {
            Console.WriteLine("XXX");
            Console.ReadLine();
            }
          }
        }
      }
    

    the program just ends after the G.Go(). If I single step up to the Go() then the console window closes and that's it. No catch, no finally. If I run it using Ctrl-F5 it's the same. Program starts, first and last output is "press any key..." from the cmd.exe.

    It's like G.Go() would somehow look for the process ID and then kill the process or something.

    The Gerber object is a COM object. I compile the program as x86. I have absolutely no access to the source code of the Gerber class, as it's part of a (rather expensive) CAD system.

    How does one debug something like this? Normal errors (like handing it a nonexisting DesignFile) get caught like they should.

    Can I do something complicated using AppDomains or so? We strongly suspect that the problem lies with the CAD drawing but without any indication as to where or why the program crashes we won't even be able to debug this properly with the software supplier.

    Lots of Greetings!

    Volker

    Tuesday, May 21, 2013 5:29 PM

Answers

  • 0xC0000409 looks like STATUS_STACK_BUFFER_OVERRUN, which suggests there's a problem either with COM object itself, or (most likely) with input data.

    Also, some COM objects do like replacing a default exception handler with its own one. You might suppress this behavior by saving default exception handler on startup and restoring it after creation COM object.

    • Marked as answer by v_he Thursday, May 23, 2013 3:13 PM
    Thursday, May 23, 2013 1:35 AM
  • There are a couple of exceptions that an app cannot recover from irrelevant of EH.  One is out of memory and the other is stack overflow.  Depending upon where it happens your EH might or might not get called.  In the case of it occurring in unmanaged code then don't count on it.

    A stack buffer overrun is equivalent to a stack overflow because the stack is mangled and there is probably no way to get back to the caller (depending upon where the overrun occurred).  At this point your app would be dead in the water and will immediately terminate.  As Alex mentioned this is most likely indicative of bad input.  In my experience you'll see this if you call a method that requires you to pass some sort of write buffer and a size and your write buffer is either a bad pointer or allocated on the stack or the size you specified was too big.  These scenarios tend to cause overflows.

    Michael Taylor
    http://msmvps.com/blogs/p3net

    • Marked as answer by v_he Thursday, May 23, 2013 3:12 PM
    Thursday, May 23, 2013 2:20 PM
    Moderator

All replies

  • First look in the Control Panel - Adminstrative Tools - Event Viewer to see if there is additional information on error.  How long does it normally take to execute the Go() method.  When it fails does it fail immediately, or after a period of time?

    Often when the return parameters aren't the same between a subroutine and a calling function the code will execute the function properly but will fail on the return from the function   When the input parameters are wrong a function normally fails just after it is called.  So the time when the failure occurs is useful information.

    I would try putting the construct for the Gerber code into global space above main() and make it static to see if that works.

       static Gerber G = new Gerber();
       static void Main(string[] args)

    It is possible that the vendors class will not have access to an object delcared inside main().



    jdweng

    Tuesday, May 21, 2013 5:54 PM
  • Hi!

    You are right, there is an event, so at least Windows noticed something amiss. :-)

    However, if that here

    - <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
    - <System>
      <Provider Name="Application Error" /> 
      <EventID Qualifiers="0">1000</EventID> 
      <Level>2</Level> 
      <Task>100</Task> 
      <Keywords>0x80000000000000</Keywords> 
      <TimeCreated SystemTime="2013-05-21T18:05:15.000000000Z" /> 
      <EventRecordID>34168</EventRecordID> 
      <Channel>Application</Channel> 
      <Computer>MIC40.WIN.ECAD</Computer> 
      <Security /> 
      </System>
    - <EventData>
      <Data>Gerbertöter.exe</Data> 
      <Data>1.0.0.0</Data> 
      <Data>519bb718</Data> 
      <Data>MGCPCBEngines.dll</Data> 
      <Data>1.0.0.1</Data> 
      <Data>4f18a2e0</Data> 
      <Data>c0000409</Data> 
      <Data>00017f7a</Data> 
      <Data>11d8</Data> 
      <Data>01ce564dbda31dbb</Data> 
      <Data>C:\temp\Gerbertöter\Gerbertöter\bin\Debug\Gerbertöter.exe</Data> 
      <Data>C:\Mentor\7.9.3EE\SDD_HOME\common\win32\lib\MGCPCBEngines.dll</Data> 
      <Data>fc89de3f-c240-11e2-b147-001999474617</Data> 
      </EventData>
      </Event>

    is all, I'm not quite home yet. Is there a way to, for instance, force windows to create a crash dump?

    • Edited by v_he Tuesday, May 21, 2013 6:18 PM spelling fixed
    Tuesday, May 21, 2013 6:11 PM
  • Just so, I tried the static stuff without success and till do some more timing tests tomorrow.
    Tuesday, May 21, 2013 6:18 PM
  • Remove your exception handlers in your test code.   You will get the default exception handler which will give you the option to "copy to clip board".  Press this shortcut and paste into notepad.

    jdweng

    Tuesday, May 21, 2013 9:48 PM
  • You should forward this application error to the support team for the company that provided the COM assembly, it may mean more to them.

    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Tuesday, May 21, 2013 9:54 PM
    Moderator
  • Are you using Windows 7?  You may need to set up the priveledges to execute "Gerbertöter.exe".

    jdweng

    Tuesday, May 21, 2013 9:54 PM
  • 0xC0000409 looks like STATUS_STACK_BUFFER_OVERRUN, which suggests there's a problem either with COM object itself, or (most likely) with input data.

    Also, some COM objects do like replacing a default exception handler with its own one. You might suppress this behavior by saving default exception handler on startup and restoring it after creation COM object.

    • Marked as answer by v_he Thursday, May 23, 2013 3:13 PM
    Thursday, May 23, 2013 1:35 AM
  • There are a couple of exceptions that an app cannot recover from irrelevant of EH.  One is out of memory and the other is stack overflow.  Depending upon where it happens your EH might or might not get called.  In the case of it occurring in unmanaged code then don't count on it.

    A stack buffer overrun is equivalent to a stack overflow because the stack is mangled and there is probably no way to get back to the caller (depending upon where the overrun occurred).  At this point your app would be dead in the water and will immediately terminate.  As Alex mentioned this is most likely indicative of bad input.  In my experience you'll see this if you call a method that requires you to pass some sort of write buffer and a size and your write buffer is either a bad pointer or allocated on the stack or the size you specified was too big.  These scenarios tend to cause overflows.

    Michael Taylor
    http://msmvps.com/blogs/p3net

    • Marked as answer by v_he Thursday, May 23, 2013 3:12 PM
    Thursday, May 23, 2013 2:20 PM
    Moderator
  • Hm. I tried

    using System;
    using System.IO;
    using MGCPCBEngines;
    namespace Gerbertöter
      {
      class Program
        {
        [STAThread]
        static void Main(string[] args)
          {
          Gerber G = new MGCPCBEngines.Gerber();
          AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
          FileInfo PCBFile = new FileInfo(@"Q:\projects_test\Hetzer\D0052-Pressfit_MOSFET_gerberEngine\WGS01\layout\pcb\D0052-UL-01\PCB\D0052-UL-01.pcb");
          G.DesignFileName = PCBFile.FullName;
          GerberOutputFile GOF = G.OutputFiles.Add("EachElements.gdo");
          GOF.ConductiveLayer = 1;
          GOF.ConductiveItems.Add(EEnginesConductiveItem.eengCondItemPlaneData);
          G.Go();
          }
    
        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
          {
          File.WriteAllText(@"v:\tst.txt", e.ExceptionObject.ToString());
          }
        }
      }
    

    but the unhandledExceptionHandler doesn't get called.

    Was this what you had in mind?

    Thursday, May 23, 2013 3:12 PM
  • 0xC0000409 looks like STATUS_STACK_BUFFER_OVERRUN, which suggests there's a problem either with COM object itself, or (most likely) with input data.

    We got it cleared up and it looks like you're right. There's a 128 character limit hidden in the object which we stumbled over.

    &%**dy stoneage programmers.

    Thursday, May 23, 2013 3:15 PM
  • Remove all exception handlers.  VS installs a default handler automatically.

    using System;
    using System.IO;
    using MGCPCBEngines;
    namespace Gerbertöter
      {
      class Program
        {
        [STAThread]
        static void Main(string[] args)
          {
          Gerber G = new MGCPCBEngines.Gerber();
          FileInfo PCBFile = new FileInfo(@"Q:\projects_test\Hetzer\D0052-Pressfit_MOSFET_gerberEngine\WGS01\layout\pcb\D0052-UL-01\PCB\D0052-UL-01.pcb");
          G.DesignFileName = PCBFile.FullName;
          GerberOutputFile GOF = G.OutputFiles.Add("EachElements.gdo");
          GOF.ConductiveLayer = 1;
          GOF.ConductiveItems.Add(EEnginesConductiveItem.eengCondItemPlaneData);
          G.Go();
          }
        
        }
      }


    jdweng

    Thursday, May 23, 2013 3:18 PM
  • Go into your Debug/Exceptions configuration and check all the boxes in the "Thrown" column.  This will cause the debugger to stop at the start of the exception processing, rather than at the end.  This might let you see anything that's being covered up later.

    Be prepared however to have to stop *lots* of times if the third party code is crap.


    This signature unintentionally left blank.


    • Edited by Nick F. _ Saturday, May 25, 2013 1:30 PM
    Saturday, May 25, 2013 1:26 PM