I may be completely misunderstanding how to use the Google Breakpad API, and am open to comments / suggestions / rude remarks if that is the case. I am trying to call the following C++ function:
bool WriteMinidumpForException(EXCEPTION_POINTERS* exinfo);
I have a reference to a std::exception:
try {
return QApplication::notify(receiver, event);
} catch (std::exception &ex) {
eh_.WriteMinidumpForException(?????);
// ... do some more stuff and ultimately kill this process
}
(eh_ is a google_breakpad::ExceptionHandler.)
What do I put in the ?????
Background: The reason this is necessary (I think) is that Qt will not support an exception thrown in an event handler. It will not propagate correctly, and thus the minidump that Breakpad produces is completely useless because the actual context of the exception has been lost. Instead, you must catch all exceptions and handle them in the override of QApplication::notify(), which is what I am trying to do. In the case of an exception, I want to immediately write my minidump for that exception (which is sounds like WriteMinidumpForException will do) and then notify the user and quit the application. But I am not sure what to pass as the EXCEPTION_POINTERS* parameter.
In the MSVC compiler, C++ exceptions piggy-back onto the native Windows exception plumbing (SEH, Structured Exception Handling). There's a pretty big impedance mismatch though, the concept of an exception filter is doesn't have a good match in C++. By the time the catch handler catches an exception, the SEH exception is already handled and the stack unwound. The EXCEPTION_POINTERS info is gonzo. The exception filters actually exist, that's how it filters for the specific type you want to catch, they are however auto-generated by the compiler. No reasonable C++ syntax exists to make them useful.
You need to dip into the compiler support for handling SEH exceptions. Use the __try, __except keywords (__finally is optional) and have your filter catch the exception code for a C++ exception, 0xe04d5343 ('MSC'). You do however lose the ability to catch a specific C++ exception type, that plumbing is buried in the CRT without source. Put a C++ try inside the __try to fix that so your __except only sees exceptions that the C++ code didn't filter.
Using SetUnhandledExceptionFilter() is another way to do this btw, you really should consider it to act as the ultimate backstop of any unhandled exception, independent of the code location. It is the best way to create a minidump of a crashing app. Last but not least, creating a minidump of a crashing app inside the process itself isn't the best approach. There are plenty of odds that this won't work well, the process state can be corrupted pretty badly. One failure mode is having the process heap locked. Not unlikely considering that heap damage is a very common crash reason. Fix that with a "guard process", use a named event to signal it to make a minidump. Your exception filter only needs to set the event, that always works.
Windows SEH and c++ exceptions are not intertwined in any way - the easy way to solve this is to use your own __try __except wrapping e.g. a dereference of a null pointer.
Something like:
__try {
* (int *) 0 = 0;
}
__except
(
eh_.WriteMinidumpForException(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER
)
{
}
Related
try{
//some function
}catch(...){
//write information to a file including this line number
}
--
What's stopping me from doing this instead of specifying a null pointer exception for instance? The program is going to crash anyways so I might as well catch all errors if there is something I haven't thought about?
It's a myth that every program fault will be caught by catch(...). In particular the behaviour of a null pointer dereference is undefined so there's no guarantee at all that it would be caught there.
If you want a particularly generic catch site, then catching std::exception& is a good idea, as is const char*.
C++11 gives you the ability to inspect the exception in catch(...) to a degree via std::current_exception. See https://en.cppreference.com/w/cpp/error/current_exception.
In Microsoft C, an extension exists that allows you to try and catch exceptions:
void exceptionTest(void)
{
int *zz = NULL;
__try {
*zz += 1;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
printf("gotcha! 0x%08x\n", GetExceptionCode() );
}
}
From the documentation (MSC2008):
The try-except statement is a Microsoft extension to the C language that enables applications to gain control of a program when events that normally terminate execution occur. Such events are called exceptions, and the mechanism that deals with exceptions is called structured exception handling.
Exceptions can be either hardware- or software-based. Even when applications cannot completely recover from hardware or software exceptions, structured exception handling makes it possible to display error information and trap the internal state of the application to help diagnose the problem. This is especially useful for intermittent problems that cannot be reproduced easily.
Being specific in exception handling facilitates the bug or probleme analysis by a human or programmatically.
You can build an excpetion handling strategy and eventually recover from an exception. Exception is not necessarily a design flaw resulting in some unexpected null pointer. You may throw exception based on data values or process results to stop the processing or take a decision.
You are confusing things. If you dereference a null pointer then there is no automatically created exception. Dereferencing a null pointer is undefined behaviour. Once it happened its too late for exceptions. They simply wont help a bit.
On the other hand if some code checks for null pointer and then throws an exception, then this only makes sense before the null pointer is dereferenced, ie before undefined behaviour can occur. The program will not "crash anyways" when an exception is thrown in such a case (given that someone catches the exception).
Having said this, nobody will stop you from catching all excpetions. It is just that prior to C++11 you had no way to tell what exception was thrown inside a catch(...) block. C++11 has std::current_exception, though I dont know much about it, so I refer you to documentation.
I have a C++ application built in MS Visual Studio 2005 that links to a 3rd party library. For a certain input, the application crashes in the 3rd party library (apparently somewhere in realloc.c; so has to be a memory issue of some kind). I ran in release because the input is huge. So I ran until it crashes and then choose to debug. While I separately debug the guilty function, I was hoping to use some exception handling to prevent the application from crashing and instead exit cleanly. So I used something like:
try {
//- call 3rd party application function that fails
}
catch(...) {
//- handle exception or whatever
Logger::Fatal("Fatal error: Exiting...");
return false;
}
But to my surprise the application still crashes! I was expecting to see it display the error message since I've presumably caught all exceptions with the ellipsis (...); what am I missing here? I even tried setting /EHca (was /EHsc) in Project Properties -> C/C++ -> Code Configuration -> Enable Exception Handling. On a related note about what might be causing the problem, is the following usage correct?
my_class* mc[] = {nil, nil, nil};
for (int i = 0; i < 3; ++i) {
mc[i] = new my_class();
//-Do stuff with mc[i]
if (mc[i] != nil) {
delete mc[i];
mc[i] = nil;
}
}
The failure to get the exception handling working is rather puzzling. I would certainly appreciate ideas/insights from the C++ gurus out there. BTW, the same problem also occurs on Linux (RHEL5) but I am currently trying to get the exception handling to work on Windows.
NOTE: When I let it debug after the crash. I do get an "Access violation..unable to read location" message. With this updated info, I was hoping something in C++ would still work on both Windows & Linux for such crashes.
Have you tried catching the crash by calling SetUnhandledExceptionFilter?
As Miguel suggested, a correct way to solve your problem is probably to use SetUnhandledExceptionFilter. But I'd like to explain your phenomena in details nevertheless.
First of all, not all the program "crashes" are related to exceptions. For instance, CRT may trigger program termination upon errors, such as invalid element access in a vector, or a pure virtual destructor call. If you want to cover those cases as well - see set_unexpected, set_terminate and etc.
Besides of this, catch block may only catch exceptions thrown from the appropriate code block. OTOH there may be functions that are called elsewhere, such as window procedures (if applicable), other threads and etc.
Now, regarding your problem. Let's first realize why things like catch(...) may catch things like access violation, and etc, and why this does not always happen (like in your case).
Windows provides its own exception handling mechanism - SEH, structured exception handling. It's far superior to C++ exception handling. In addition hardware interrupts (caused by CPU) are automatically "converted" into SEH exceptions, so that the code that uses SEH handles both software exceptions and hardware failures.
Microsoft C++ compilers actually implement C++ exceptions via SEH. That is throw is implemented via RaiseException with specifying C++ - specific exception code and parameters, catch is a C++ - specific wrapper for __except, and for every object with destructor the compiler generates something similar to __finally block. And this also works vice-versa. When a non-C++ exception is raised - the same code generated for C++ exceptions is executed.
In addition there are so-called compiler exception handling options that affect both the compiler exception handling code generation, and its behavior in runtime. They are called exception handling models:
synchronous. The compiler generates a code that is guaranteed to work correctly only if exceptions are raised explicitly. This includes throw statments, and all the "foreign" functions whose code is not visible to the compiler (in some variations - only C++ foreign functions). In particular reading from memory is considered "safe".
asynchronous. The compiler is not allowed to assume anything about where exceptions may arise. Hence it generates the code that should work correctly even if exception is arises from accessing a memory address.
In addition, CRT code that's invoked in catch (...) deliberately ignores non-C++ exceptions, unless asynchronous EH model is choosen.
So that if you want catch (...) to catch non-C++ exceptions - you must choose the asynchronous EH model.
Once I've written an article on the codeproject, after I had a related problem in driver development. It explains all this in details.
We have a .NET program that calls major functionality in unmanaged C++. I have a global exception catcher on the .NET side to catch any unhandled errors, but errors such as access violations in the unmanaged C++ DLLs can bring the program down without any logging. What is the best way to add "global" exception catcher in a DLL? Can I do this in DllMain?
You can use the /EHa exception handling flag, which will cause your C++ catch (...) to also catch structured exceptions, i.e. access violations. The downside of this is that you can't see what the exception was.
Alternatively, you can use a structed exception handler, __try { } __except(FILTER) { }, to handle structured exceptions. This allows you to output what type of exception was caught. However, there are limitations on what you can do in a function with a __try, such as no C++ exception handling or objects with destructors.
You can, however, get around the __try limitation by just calling a function containing the C++ exception handling and original code.
void main() {
__try {
Foo();
}
__except(EXCEPTION_EXECUTE_HANDLER) {
// Log some error regarding the structured exception
}
return 0;
}
void Foo() {
try {
SomeCPPObject bar(1,2);
DoSomeStuff();
}
catch (const std::exception&) {
// Log the C++ exception
}
}
Be careful, however, as you usually should not continue execution after a structured exception has been raised, as the state of your program could be completely destroyed. It's best to only use this type of exception handling to log an error before exiting.
The CLR cannot trap any hardware exceptions that are raised in threads started by the native code. The only way to do so is by using SetUnhandledExceptionFilter(), the callback you register is called by Windows before it is about to tear down the process.
Using this in a program that also has managed code is filled with traps and pitfalls. The CLR uses it too, it has to in order to generate exceptions like NullReferenceException and DivideByZeroException. You have to be very careful to not break that. Doing something like calling GetThreadId() and only filter exceptions of threads that you know are native ones is important. Next thing you'd do is, say, use MiniDumpWriteDump() to generate a minidump so that you can debug the crash.
I'm writing a C++ application. I realized that one of my worker threads may terminate unexpectedly. The (VS 2005) debug log says:
The thread 'Win32 Thread' (0x5d98) has
exited with code -858993460
(0xcccccccc).
I surrounded all the worker thread code with a try/catch block. So, if the reason was an exception, I would catch it. But I can't:
try{
...
Connection* conn = connectionPool->getConnection(); // unexpected exit occurs here
...
} catch(exception& e) {
...
}
I have ten threads running concurrently, and only one of them gets crashed after some time, while the others continue running (and getting new [OCCI] connections).
Is there an exception type that is not caught by "exception"? Or what do I not know about threads/exceptions?
Thanks.
Not all errors raise C++ exceptions that can be caught with the C++ try...catch mechanism. For example, division by zero will not raise a C++ exception, but will cause undefined behaviour which may well make your application exit.
However, your code may be throwing things that are not derived from std::exception , so you may want to rewrite:
try{
Connection* conn = connectionPool->getConnection(); // unexpected exit occurs here
}
catch(exception& e) {
// handle things derived from std::exception
}
catch ( ... ) {
// handle things that are not so derived
}
which will deal with things like throw "eeek!";
Also, but nothing to do with the problem, you should normally catch exceptins via a const reference.
Is there an exception type that is not caught by "exception"?
Yes, SEH exceptions. To catch them you need to either use __try/__except MSVC extension (see Structured Exception Handling), or write a global SEH/VEH handler (see SetUnhandledExceptionFilter and AddVectoredExceptionHandler).
The easiest way to find the problem would be to run your application under a debugger and enable breaking on Win32 Exceptions. Whenever a Win32 Exception is encountered, the application would break into the debugger and you can find out whats going wrong.
If you are not debugging and want to catch a win32 structured exception, you have to use _set_se_translator api to set a translator function. The registered function will be called whenever there is a Win32 exception and you get a chance to convert it to a C++ exception of your choice.
catch(exception& e) catches C++ exceptions derived from std::exception, and nothing else.
It doesn't catch C++ exceptions that are not derived from that class (If I do throw 42, it won't be caught for example), and it doesn't catch exceptions or errors at the system level.
Windows uses Structured Exception Handling (SEH) to signal errors, and those are not caught with a plain C++ catch statement. This might include errors like division by zero, as well as access violations or pretty much anything else that might go wrong at the OS or hardware level.
The docs have a nice explanation of how to catch SEH exceptions.
I found an important clue. When you close a handle with CloseHandle function, the thread exits with code 0xCCCCCCCC. With the help of this clue, I realized that in a very rare situation, I close my thread's handle even though the thread's working. Why does it exit exactly while getting connection? That also has an explanation, but it's related to the structure of the code, which may be difficult to explain here.
Thank you all, who brainstormed with me on the exceptions issue :$.
Like the title says, we’re looking for a way to catch all exceptions from a piece of C++ code, and wrap this in a dll. This way we can shield of the application that uses this dll, from any errors occurring in this dll.
However, this does not seem possible with C++ under Windows.
Example:
void function()
{
try
{
std::list<int>::iterator fd_it;
fd_it++;
} catch(...) {}
}
The exception that occurs is not caught by the standard C++ try/catch block, nor by any SEH translator function set by _set_se_translator(). Instead, the DLL crashes, and the program that uses the DLL is aborted. We compiled with Visual C++ 2005, with the option /SHa. Does anyone know if it’s possible in C++/Win32 to catch these kind of problems and make a rocksolid DLL wrapper?
The only way to make a rock solid DLL wrapper is to load the buggy DLL in another process, so that if it crashes it doesn't take your primary process down with it.
Catching all C++ exceptions seems reasonable, but catching all structured exceptions is another story. SEH might seem to get you most of the way there, because it allows you to catch access violations, divide-by-zero exceptions, etc.
But what if the buggy DLL happens to touch an uncommitted page from another thread's stack? The memory access will page fault, the exception handler will be invoked, and now that page is no longer a guard page. When that thread needs to grow the stack, it will get an access violation, and the process will crash. (These posts describe this case in more detail.)
Another likely problem: the buggy DLL crashes while holding a synchronization object, but you use SEH to catch the exception. If your process attempts to acquire the same synchronization object, then it deadlocks instead of crashing. The shared synchronization object may be part of the C runtime or the OS: what if buggy DLL 1 loads buggy DLL 2, which crashes in its DllMain() while buggy DLL 1 is holding the loader lock? Will your process deadlock the next time it loads a DLL?
For more information on why this (and functions like IsBadReadPtr(), which have similar problems) is a misuse of SEH:
Larry Osterman's WebLog: Structured Exception Handling Considered Harmful
Larry Osterman's WebLog: Should I check the parameters to my function?
Larry Osterman's WebLog: Resilience is NOT necessarily a good thing
The Old New Thing: IsBadXxxPtr should really be called CrashProgramRandomly
On Windows, C++ has 2 different styles of exceptions: C++ and SEH exceptions.
SEH is a windows only form of exceptions (somewhat akin to signals in UNIX). It's more of a system level exception. They will be thrown for such operations as invalid pointer accesses, alignment issues, etc ...
If you want to catch every exception that can be thrown by a C++ app on windows you will need to catch both. Fortunately there is a way to mix the use of C++ and SEH exceptions. I wrote a detailed blog post about this recently, it should help you out.
http://blogs.msdn.com/jaredpar/archive/2008/01/11/mixing-seh-and-c-exceptions.aspx
Incrementing an iterator on a standard libary container will never throw a C++ exception. It may give you undefined behaviour.
The code below is taken from the Zeus IDE. It will trap any Windows generated exceptions:
Step #1: Define an Exception Filter Function
DWORD ExceptionFilter(EXCEPTION_POINTERS *pointers, DWORD dwException)
{
//-- we handle all exceptions
DWORD dwResult = EXCEPTION_EXECUTE_HANDLER;
switch (dwException)
{
case EXCEPTION_ACCESS_VIOLATION:
case EXCEPTION_DATATYPE_MISALIGNMENT:
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
case EXCEPTION_FLT_DENORMAL_OPERAND:
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
case EXCEPTION_FLT_INEXACT_RESULT:
case EXCEPTION_FLT_INVALID_OPERATION:
case EXCEPTION_FLT_OVERFLOW:
case EXCEPTION_FLT_STACK_CHECK:
case EXCEPTION_FLT_UNDERFLOW:
case EXCEPTION_INT_DIVIDE_BY_ZERO:
case EXCEPTION_INT_OVERFLOW:
case EXCEPTION_PRIV_INSTRUCTION:
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
case EXCEPTION_BREAKPOINT:
dwResult = EXCEPTION_EXECUTE_HANDLER;
break;
}
return dwResult;
}
Step #2: Wrap the code in a __try and __except as shown below:
__try
{
// call your dll entry point here
}
__except(ExceptionFilter(GetExceptionInformation(),
GetExceptionCode()))
{
//-- display the fatal error message
MessageBox(0, "An unexpected error was caught here!",
"Unexpected Error", MB_OK);
}
Konrad Rudolph: Of course this code contains a "logic error", it's to illustrate a problem that could occur. Like the man says he wants to be able to shield his dll from any possible errors. You don't think this is a legitimate question? Heard of vendor products. Some of us live in the real world and live with real problems. It's just not possible to fix everyone else's problems
This code contains a logic error, if at all. Since a logic error constitues a bug, don't swallow the exception – fix the error!
Of course, this is specific to the particular code. Others have offered more general advice. However, I've found that a lot of people actually do prefer catching exceptions over fixing logic errors and this is simply unacceptable.
Have you looked at the windows API function SetUnhandledExceptionFilter?
I usually call it in the DllMain function and have it generate a minidump when the DLL crashes. However: (a) I don't know if it traps application exceptions as well as DLL exceptions, and (b) I don't know if you can have the handler return in such a way that program execution can continue. The docs say yes, but I've never done it.
What are you going to do after you catch the exception (especially for SEH exceptions)?
In reality you can make no assumptions about the state of the process, realistically the only option you have is to (optionally) dump core and exit.
Any attempt and proceeding is absolutely going to cause you problems in the long run.