I made a sample to check what happen when Ctrl+C is pressed in windows console application:
bool TerminationFlag=true;
int main()
{
g_hTerminateEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
::SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
while(1)
{
if(TerminationFlag == false)
{
break;
}
}
return 0;
}
BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType)
{
if (dwCtrlType == CTRL_C_EVENT ||
dwCtrlType == CTRL_BREAK_EVENT ||
dwCtrlType == CTRL_CLOSE_EVENT)
{
TerminationFlag=false;
::SetEvent(g_hTerminateEvent);
return TRUE;
}
return FALSE;
}
I tested the code by running it using start debugging option in visual studio when I press ctrl+c I get the following message
First-chance exception at 0x7c87647d
when I press on continue option my code comes to the line TerminationFlag=false;
even though I have handled Ctrl+C in control handler. Can you please tell me whats the problem?
When an application is being debugged, the debugger gets notified whenever an exception is encountered. At this point, the application is suspended and the debugger decides how to handle the exception. The first pass through this mechanism is called a "first chance" exception.
Tell the debugger to break when an exception is thrownIn the Exception Settings window (Debug > Windows > Exception Settings), expand the node for a category of exceptions, such as Common Language Runtime Exceptions. Then select the check box for a specific exception within that category, such as System.
If the application does not handle the exception, the debugger is re-notified. This is known as a "second chance" exception. The debugger again suspends the application and determines how to handle this exception.
I assume you're using Microsoft Visual Studio from your description of the problem. The first chance exception being raised is the CTRL-C event which is trapped by the debugging environment. This is expected behaviour.
You can choose to ignore this: go to Debug menu/Exceptions/Win32 Exceptions and take out the CONTROL-C check from the "Thrown" column menu. This will ensure that the debugger only breaks on CONTROL-C when it is user-unhandled. See picture below:
Incidentally, you should be waiting for the termination event not polling for a flag. You may want something like:
#include "windows.h"
#include <iostream>
HANDLE g_hTerminateEvent;
BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType)
{
if (dwCtrlType == CTRL_C_EVENT ||
dwCtrlType == CTRL_BREAK_EVENT ||
dwCtrlType == CTRL_CLOSE_EVENT)
{
std::cout << "Terminating" << std::endl;
SetEvent(g_hTerminateEvent);
return TRUE;
}
return FALSE;
}
int main()
{
g_hTerminateEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
DWORD result = WaitForSingleObject(g_hTerminateEvent, INFINITE);
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With