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
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
Ya, I agree, fix the problem.
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
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
ASKER
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 ...
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...
SetErrorMode ( SEM_NOGPFAULTERRORBOX);
But SEH gives you the chance to interfere...
ASKER
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
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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
ASKER
Also, it appears I must use the Release version
as ASSERTS are still bringing up the crash box,
even with setErrorMode() and a SetUnhandledExceptionFilte
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(schServ ice);
}
else
_tprintf(TEXT("OpenService failed - %s\n"), GetLastErrorText(szErr,256 ));
CloseServiceHandle(schSCMa nager);
}
else
_tprintf(TEXT("OpenSCManag er failed - %s\n"), GetLastErrorText(szErr,256 ));
}
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(schServ
}
else
_tprintf(TEXT("OpenService
CloseServiceHandle(schSCMa
}
else
_tprintf(TEXT("OpenSCManag
}
ASKER
Many Thanks
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
{
// 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 'SetUnhandledExceptionFilt
LONG WINAPI __XceptFilter ( EXCEPTION_POINTERS* pExp)
{
LONG lnRC = EXCEPTION_EXECUTE_HANDLER;
if ( EXCEPTION_ACCESS_VIOLATION
{
}
else return ( EXCEPTION_CONTINUE_SEARCH)
return( lnRC);
}
SetUnhandledExceptionFilte