Link to home
Start Free TrialLog in
Avatar of stevenmcheerful
stevenmcheerful

asked on

HOW SUPRESS CRASH BOX - Windows Crash Box memory could not be read Press Ok to terminate

How do I supress the abnormal termination CRASH box when my console VC6 app has
a problem - it always will the way it was written.

On my development machine, I can crash my server (or CTRL-C it) and it exits
gracefully.  On the customer machine, it ALWAYS brings up the crash box.
I do not want the customer to see it.  He doesn't know when it has crashed.
And it gives me the chance to restart it before he knows anything has happened.

Both machines are WinNT, with Visual Studio 6 installed.  Only difference is my
dev machine is SP4, and the customer machine is SP6.

I have tried both Debug and Release builds - they both exhibit the same behaviour.

Other info:  My MSVC++ project is a console app without MFC support in the build process,
BUT, it depends on DLLs I have written that do have MFC classes (specifically CDatabase
and CString), so the DLLs are built along with the Console Server as one massive project.

I just want to suppress the crash box.

anyone know ?

- steve
Avatar of jkr
jkr
Flag of Germany image

First of all, it's always better to fix *ALL* bugs...

That 'Crash Box' is displayed by the default exception handler (thus, an 'Unhandled Exception'). The most convenient way is to use SEH:

void main()
{
 __try
 {
   MainCode();
 }
 __except ( EXCEPTION_ACCESS_VIOLATION == GetExceptionCode() ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
 {
  // your handler here...
 }
}

However, it's more convenient (and probably what you want to do) to replace the top-level exception
filter by your own via calling 'SetUnhandledExceptionFilter(), e.g.

LONG WINAPI __XceptFilter   (   EXCEPTION_POINTERS* pExp)
{
   LONG    lnRC    =   EXCEPTION_EXECUTE_HANDLER;

   if  (   EXCEPTION_ACCESS_VIOLATION  ==  pExp->ExceptionRecord->ExceptionCode)
       {
       }
    else   return ( EXCEPTION_CONTINUE_SEARCH);

   return( lnRC);
}


   SetUnhandledExceptionFilter (   __XceptFilter);
Avatar of dhymes
dhymes

Ya, I agree, fix the problem.
Avatar of stevenmcheerful

ASKER

Cannot fix the problem right now - the software is not
mine; i.e., I have inherited it from someone who quit.
It is very complex and buggy, and the problems are
sprintf (%15s%4d%6f ... etc. and other ridiculous calls
expecting fixed-length data all over the place in
the thousands upon thousands of lines of source code.

We are undergoing a major exercise for the government,
and I can live through the next two weeks to debug
later *IF* I can restart the server when it has
crashed.  I have another program that pings the
server every 5 seconds, and if it is dead, will
automatically restart it.  BUT, the server does not
truly die until you PRESS OK TO TERMINATE !!!!!

So, it crashed last night whilst I wasn't here, and
the crash box stayed on the screen until I pressed
OK very early this morning.

I will look into SEH today.

Thank-You
Oh - also  ...  SEH looks quite promising but I
wonder why I get the crash box on one machine
but not the other  ...  the code is the same,
currently without SEH  ...
BTW: An even easier solution would be to

SetErrorMode ( SEM_NOGPFAULTERRORBOX);

But SEH gives you the chance to interfere...
yes, I found SetErrorMode, and that does the trick.

Jkr, I will award the points.  2 questions though:

1) you say to interfere (SEH), what do you do or
   what should I do to recover from the memory
   faults?  can ya point me to an example ?


2) I cannot remember how to award the points ...
   where's the button to reward the answer-person ?


 - steve
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial

 Thanks.  Do you have a URL for an example to
        checking the SCM status ?  I have seen
        some examples in the past, but they
       seemed to be quite complicated with
        many caveats  ...   so I will not go
       back to those bookmarked pages, hope you
       have a better source of info for me  ...

       I am using a freeware "pinger" to restart
       the server when it crashes (currently) as
      I believe the software is too unstable to install
     as a service, but eventually I will install as
     a service  ...
 
    - steve

 Also, it appears I must use the Release version
 as ASSERTS are still bringing up the crash box,
 even with setErrorMode() and a SetUnhandledExceptionFilter
 with SEH code installed and compiled  ...

 without Debug run-time ASSERT evaluation, the
 crash box seems to be out of the picture  ...
Try the following:

void StopService()
{
   SC_HANDLE   schService;
   SC_HANDLE   schSCManager;
   SERVICE_STATUS ssStatus;

   schSCManager = OpenSCManager(
                       NULL,                   // machine (NULL == local)
                       NULL,                   // database (NULL == default)
                       SC_MANAGER_ALL_ACCESS   // access required
                       );
   if ( schSCManager )
   {
       schService = OpenService(schSCManager, TEXT(SZSERVICENAME), SERVICE_ALL_ACCESS);

       if (schService)
       {
           // try to stop the service
           if ( ControlService( schService, SERVICE_CONTROL_STOP, &ssStatus ) )
           {
               _tprintf(TEXT("Stopping %s."), TEXT(SZSERVICEDISPLAYNAME));
               Sleep( 1000 );

               while( QueryServiceStatus( schService, &ssStatus ) )
               {
                   if ( ssStatus.dwCurrentState == SERVICE_STOP_PENDING )
                   {
                       _tprintf(TEXT("."));
                       Sleep( 1000 );
                   }
                   else
                       break;
               }

           }
           else QueryServiceStatus( schService, &ssStatus );

           if ( ssStatus.dwCurrentState == SERVICE_STOPPED )
               _tprintf(TEXT("\n%s stopped.\n"), TEXT(SZSERVICEDISPLAYNAME) );
           else
               _tprintf(TEXT("\n%s failed to stop.\n"), TEXT(SZSERVICEDISPLAYNAME) );

           CloseServiceHandle(schService);
       }
       else
           _tprintf(TEXT("OpenService failed - %s\n"), GetLastErrorText(szErr,256));

       CloseServiceHandle(schSCManager);
   }
   else
       _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
}


  Many Thanks