Troubleshooting Windows Access Violations

I am trying to catch all the unhandled exceptions in my application, so I can save the log file when they occur. This is a 64-bit Windows application compiled using Visual Studio 2013, written in C ++. For testing, I use the default C ++ Win32 project generated by VS.

I am catching all exceptions by registering a handler using SetUnhandledExceptionFilter. This works great for / most / cases, but not for everyone. With the exception of all throw () - n exceptions and most hardware exceptions, such as floating point or access violations. Code that does not start the handler:

std::vector<int> foo(5, 0); for (auto& f : foo) foo.erase(foo.begin() + 1); 

Instead, I just get a standard dialog box with a crash, without calling the calling exception handler. If I run it in Visual Studio with a debugger attached, it correctly reports an access violation exception. Other types of access violations also trigger the handler:

 float* ptr = nullptr; float value = *ptr; 

The code above starts the exception handler.

I tried using the try / catch or catching SIGSEGV signal, but none of them start with the first example. interrupt / termination signals are not called. In short, I am in no way notified when an accident occurs.

I want to know if there is a way to get some kind of notification in my application before it crashes due to an access violation caused by the first example? Since VS seems able to detect this, I assume there is a way.

EDIT: I just want it to be clear that I'm running the code in release mode, and the error in the first example is not caused by an error checking the iterator out of bounds in debug mode.

EDIT2: I included the simplest example that I can come up with with the win32 console application. See here: http://pastebin.com/8L1SN5PQ

Be sure to run it in release mode without a debugger attached.

+5
source share
2 answers

These runtime errors are handled differently; they do not throw a SEH exception. It is roughly classified somewhere between a “programming error” and a “malware attack”. And about as informative as the misunderstood C ++ exception, if you don't have an attached debugger, the default handler causes an instant death with __fastfail ().

You will need to call _ set_invalid_parameter_handler () in your main () function to change the way they are processed. You can throw a C ++ exception in your own handler or call RaiseException () to call the catch-em-all handler or just report it right there. Encourage the latter, you want to make sure that the process is always completed.

Beware that your snippet is not the best example. This is UB when you create your program without iterator debugging turned on, for example, the Release assembly with default settings. UB does not guarantee that you will receive a SEH exception. And if this happens, you will need to write your exception filter very carefully, it will be called with a heap lock, still busy so that the main material cannot work. The best way is to awaken a defensive process with a named event. Then he takes the mini-drive and completes the program.

+3
source

You do not see the exception because it is handled internally at run time C. In particular, it checks for no access violation.

Running it in the debugger, I found that it is line 242 in vector :

  _DEBUG_ERROR("vector iterators incompatible"); 

He ultimately calls _CrtDebugReportW : https://msdn.microsoft.com/en-us/library/8hyw4sy7.aspx

You can control the behavior of _CrtDebugReportW with _CrtSetReportMode .

Please note that this does not affect the release mode, since it is a check of the limits of the debug mode.

0
source

Source: https://habr.com/ru/post/1233343/


All Articles