How to report a stack buffer overrun on Windows? - c++

In the code shown below I have used all documented ways to detect an exception and produce a diagnostic. It uses the C++ try/catch keywords, catches an SEH exception with the __try/__catch extension keywords, uses the Windows' AddVectoredExceptionHandler() and SetUnhandledExceptionFilter() winapi functions to install VEH/SEH filters.
Running this with Visual C++ 2003:
/GS: outputs "hello,world!" and terminates with exit code 0.
/GS-: outputs "hello,world!" and terminates with exit code 0.
Running this with Visual C++ 2013:
/GS: no output, terminates with exit code -1073740791
/GS-: outputs "hello,world!" and terminates with exit with 0.
How do I produce a diagnostic in a VS2013 compiled program with /GS in effect?
#include "stdafx.h"
#include <Windows.h>
#define CALL_FIRST 1
#define CALL_LAST 0
LONG WINAPI MyVectoredHandler(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
UNREFERENCED_PARAMETER(ExceptionInfo);
printf("MyVectoredHandler\n");
return EXCEPTION_CONTINUE_SEARCH;
}
LONG WINAPI MyUnhandledExceptionFilter(_In_ struct _EXCEPTION_POINTERS *ExceptionInfo)
{
printf("SetUnhandledExceptionFilter\n");
return EXCEPTION_CONTINUE_SEARCH;
}
void f()
{
__try
{
char p[20] = "hello,world!";
p[24] = '!';
printf("%s\n", p);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
printf("f() exception\n");
}
}
int _tmain(int argc, _TCHAR* argv[])
{
AddVectoredExceptionHandler(CALL_FIRST, MyVectoredHandler);
SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
try{
f();
}
catch (...){
printf("catched f exception\n");
}
return 0;
}

The CRT function that handles stack buffer overruns detection, __report_gsfailure(), assumes that the stack frame corruption was induced by a malware attack. Such malware traditionally messed with the fs:[0] SEH exception filters (stored on the stack frame) to get an exception handler to trigger the malware payload. One of the ways to get data to turn into executable code.
So that CRT function cannot assume that throwing an exception is safe to do. And no longer does in the CRT included with VS2013, goes back to ~VS2005. It will failfast if the OS supports it and, if not, ensures that a registered VEH/SEH exception handler cannot see the exception either. Kaboom, crash to the desktop with no diagnostic unless you have a debugger attached.
The /SAFESEH option defeats this kind of malware attack so it isn't as serious as it once was. If you are still at the stage where your code suffers from stack corruption bugs and your app is not popular enough to become the target of malware then replacing the CRT function is something you could consider.
Do talk this over with your supervisor, you never want to be personally responsible for this given the enormous liability to your client. History rarely tells the tale of what happened to the one programmer whose code put an entire corporation out of business for a month. But surely wasn't anything pretty.
Paste this code somewhere close to your main() function:
__declspec(noreturn) extern "C"
void __cdecl __report_gsfailure() {
RaiseException(STATUS_STACK_BUFFER_OVERRUN, EXCEPTION_NONCONTINUABLE, 0, nullptr);
}
And plan to remove it again soon.

There is no solution for the question as asked.
Overrunning an array causes undefined behaviour in standard C++, so no particular result is guaranteed. Failure to give a reliable result is not a problem with the compiler - it is permitted behaviour.
I'm aware of no implementation that guarantees any specific behaviour in response to an overrun - VS certainly doesn't. Which is hardly surprising as compilers are not required to do that (that is, essentially, the meaning of undefined behaviour). The reason that is the case is that it is often difficult to reliably or consistently detect such occurrences.
This means the only consistent way to detect an array overrun is to check that array indices are valid BEFORE using them to access an array element and take appropriate actions (e.g. throw an exception which can be caught instead of doing the bad operation). The downside is that it does not provide a simple or reliable way to catch errors in arbitrary code - short of modifying all code to do the required checks.

I would have liked to comment on the accepted answer, but I just joined and don't have enough reputation to do that yet.
I tried the solution with Visual Studio 2017 and had to make a couple of changes to get the solution to compile.
First I had to change the signature of __report_gsfailure to match one of Microsoft's header files to fix a compilation error.
__declspec(noreturn) extern "C" void __cdecl __report_gsfailure(_In_ uintptr_t _StackCookie)
{
RaiseException(STATUS_STACK_BUFFER_OVERRUN, EXCEPTION_NONCONTINUABLE, 0, nullptr);
}
Next I encountered a LNK2005 error, which I was able to correct by adding /FORCE:MULTIPLE to the Linker->Command Line for my project's properties.

Related

Catching fortran runtime errors and signals in C++ binding

I would like to be able to catch a terminating Fortran runtime errors in a C++ binding.
I have a legacy F90 code to bind to and expect all kind of errors e.g. numerical, IO etc.
I managed to handle STOP according to:
Intercepting Fortran STOP from C++
and able to throw/catch exception for this case in the C++ code.
I got some understanding 'Signal Handling in Fortran' at
https://www.sharcnet.ca/help/images/4/42/Fortran_Signal_Handling.pdf
However I do not manage with this, an example for f90 fortran would be very helpful.
For example trying to open a non existant file in the fortran subroutine would give a runtime error, and the C++ code terminates:
open (unit=13,FILE="fnameBAD",status="old",action="read",position="rewind")
Fortran runtime error: Cannot open file 'fnameBAD': No such file or directory
I would like to be able to catch this and other runtime errors using signals.
This won't work, at least for GFortran. When then OPEN statement fails, the GFortran runtime library will shut itself down, and only finally is the signal generated. So by the time you can catch the signal in the signal handler, libgfortran has already shut itself down (including closing all open files).
The solution, as Vladimir F says in a comment, is to catch the error in the OPEN statement with the iostat= specifier.
I've implemented something like that for unittesting C-bindings for a Fortran code from C/C++ to catch abort calls using setjmp and longjmp (essentially the same as an answer in the already linked question):
#include <setjmp.h>
#include <signal.h>
jmp_buf jmp_env;
void on_sigabrt(int signum)
{
(void) signum; // silence "unused parameter" warning
longjmp(jmp_env, 1);
}
void func()
{
if (setjmp(jmp_env) == 0) {
signal(SIGABRT, &on_sigabrt);
/* YOUR CALLS HERE */
} else {
/* ERROR HANDLING GOES HERE */
}
}
The problem #janneb already described remains: Even while longjmp should restore the stack to the point of the setjmp, it does not guarantee that all internal state in the Fortran runtime library is restored.
In fact, both books Modern Fortran: Style and Usage (rule 182) and The Fortran 2003 Handbook (15.6.4) mention that Fortran code should not be wrapped in between setjmp and longjmp.
On the other hand, there are compiler vendors which explicitly provide setjmp/longjmp wrappers (Oracle for example), as well as several projects with a similar focus:
funwind
zsvjmp
That being said, it is likely a better (and more portable) approach to use proper error handling using the iostat attribute whenever possible, as others already commented.

How to catch C++ exceptions in C? [duplicate]

I am developing C++ component dll that can be used by C or C++ applications.
The exposed dll functions are as follows
#include <tchar.h>
#ifdef IMPORT
#define DLL __declspec(dllimport)
#else
#define DLL __declspec(dllexport)
#endif
extern "C" {
DLL bool __cdecl Init();
DLL bool __cdecl Foo(const TCHAR*);
DLL bool __cdecl Release();
}
the internal implementation of these functions are C++ classes which are not exposed, I assume using this style the dll can be used either in C or C++ apps.
The problem is I do not handle any type of c++ exception (i.e. bad_alloc) and I left this stuff to the caller (the higher layer).
After much debate with my colleagues that I should catch all the exceptions and return error code or at least false because in case of C application it can not handle C++ exceptions? is that true? and what I should do in general? is there a rule of thumb for handling exeptions if you are developing component that will be used by other system.
C doesn't have exceptions, therefore in general you should catch all exception and return an error code and/or provide a function that returns the information about the last error.
If this is Windows using MSVC then yes you can catch exceptions in C but you can't catch them that well. C++ exceptions are fed through the OS ABI's Structured Exception Handling mechanism, and Microsoft have a __try, __except, __finally C extension to handle OS structured exceptions. Note that these include access violations, divide-by-zero, etc. that you'd normally want to terminate your program and log a bug report. You can identify C++ exceptions by code 0xE04D5343 (4D 53 43 = "MSC") and throw the rest on.
That all said, you probably don't want to be throwing exceptions across a DLL boundary, and certainly not if you're only exposing a C API.
As a general rule, you should never allow C++ exceptions to propagate beyond a module's boundary. This is because the C++ standard does not specify how exception propagation has to be implemented, and as such this is compiler (and compiler flags) and operating system dependent. You cannot guarantee that the code calling your module will be compiled with the same compiler with the same compiler flags as your module. In fact, as you're demonstrating with this question is that you cannot guarantee that code calling your module will be written in the same language.
For more details, please refer to Item 62 in C++ Coding Standards by Sutter and Alexandrescu.
Ok, since it was asked for:
C++ example code:
#include <typeinfo>
#include <exception>
extern "C" {
void sethandler(void (*func)(void)) { std::set_terminate(func); }
int throwingFunc(int arg) {
if (arg == 0)
throw std::bad_cast();
return (arg - 1);
}
}
C example code:
#include <stdio.h>
extern int throwingFunc(int arg);
extern void sethandler(void (*func)(void));
void myhandler(void)
{
printf("handler called - must've been some exception ?!\n");
}
int main(int argc, char **argv)
{
sethandler(myhandler);
printf("throwingFunc(1) == %d\n", throwingFunc(1));
printf("throwingFunc(-1) == %d\n", throwingFunc(-1));
printf("throwingFunc(0) == %d\n", throwingFunc(0));
return 0;
}
When I compile these two, link them together and run this (Ubuntu 10.04, gcc 4.4.5, x64), I get:
$ ./xx
throwingFunc(1) == 0
throwingFunc(-1) == -2
handler called - must've been some exception ?!
Aborted
So while you can catch exceptions from C, that's hardly sufficient - because C++ runtime behaviour after std::terminate() is undefined, and because the handler gets no status information whatsoever (to distiguish exception types and/or sources). The handler cannot clean up anything.
Btw, I've deliberately chosen std::bad_cast() as exception type in this example. This is because throwing that illustrates a difference in behaviour between std::set_unexpected() and std::set_terminate() - the unexpected handler will get called for all non std::bad_* exceptions, while in order to catch standard exceptions, a terminate handler is required ... see the dilemma ? The harness is too wide to be of practical use :(
Only propagate exceptions to the caller if the caller is designed to handle them. I guess in your case terminate() will be called immediately once any exception escapes C++ code because from the point of C++ runtime that exception has not been handled.
The same situation arises in COM servers design - the clients can be in whatever language/technology. The rul is that no exceptions should escape COM server methods - all exceptions must be caught and translated in HRESULT and (optionally) IErrorInfo. You should do similarly in your situations.
In case C code is sandwiched between two layers of C++ code propagating exceptions to C code is still a very bad idea.

Throwing an exception in C++ in a C callback, possibly crossing over dynamic library boundary... is it safe?

I'm using libjpeg right now to save JPEG images. If there is an error, libjpeg's default behavior is to call exit(), which I want to avoid since it's not a fatal error for my program. libjpeg allows you to use your own error manager, and mandates that if you use your own error_exit() function (which calls exit() by default) you must not return control to the caller. libjpeg suggests using setjmp.h to meet this requirement and not exit() the program.
However, I am writing a C++ program, and I have access to exceptions. This question's answer states it's safe (as in well-defined behavior) to throw an exception from the callback. But it doesn't mention dynamic libraries, and there's a general rule of thumb that you don't throw exceptions across dynamic library boundaries.
Here's an example:
#include <iostream>
#include <jpeglib.h>
#include <cstdio>
#include <stdexcept>
static void handleLibJpegFatalError(j_common_ptr cinfo)
{
(*cinfo->err->output_message)(cinfo);
throw std::runtime_error("error in libjpeg, check stderr");
}
int main()
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE* file = std::fopen("out.jpeg", "wb"); // assume this doesn't fail for this example
try
{
cinfo.err = jpeg_std_error(&jerr);
jerr.error_exit = handleLibJpegFatalError;
// let's say this triggers a fatal error in libjpeg and handleLibJpegFatalError() is called
// by libjpeg
jpeg_create_compress(&cinfo);
}
catch (...)
{
std::cerr << "Error saving the JPEG!\n";
}
jpeg_destroy_compress(&cinfo);
std::fclose(file);
}
What I would like to know is: can I throw an exception from this callback, and catch it back in my application, even if libjpeg is compiled as a dynamic library? libjpeg may be a static or dynamic library, and if it's a dynamic library it may possibly be built with a different compiler. However, the code that throws and catches the exception will certainly be in the same compilation unit. Is the above code safe?
FYI, I'm developing for OS X and Windows (and keeping the future of a Linux possibility in mind), so I'm more interested in if this is known to be well defined behavior in general, and not for a specific platform/compiler.
The other answer applies here. Nothing will get trashed when unwinding the stack. It doesn't even matter if the library uses some crazy calling convention internally, as long as it doesn't specifically mess with your C++ implementation's exception handling structures (which it wont as a C program). No C++ implementation that I know of finds the catch block by popping off stack frames (that would make optimization a nightmare), they all maintain internal structures for exception handling. As long as a call lower down in the call chain doesn't mess with those structures, stack unwinding will work perfectly fine for all of your personal code. Now, in general, it's quite possible that this would leave a library with a messed up internal state as you never return execution to the library for cleanup, but in the case of your error callback, libjpeg expects for control flow to not return and has presumably already cleaned up after itself.
In this case, I would go for it. In general, I would only throw fatal exceptions from a C callback.
Hope that helped.
It's not safe. Depending on how the relevant non-C++ library code was compiled, the necessary unwind tables may not exist. This is just a practical reason why it might fail; the conceptual reason is that it's simply undefined behavior.
You should follow the documentation and use setjmp/longjmp to get just outside the call to libjpeg code, then throw an exception immediately in the if (setjmp(...)) { ... } body if you want to use exceptions.
As discussed in other answers, it ought to be safe as long as you are in control of all the modules and they will be built by the same toolchain (inc. statically linking).
But I want to add a caveat here that some toolchains require this support to be turned on, since libjpeg's functions are marked extern "C". By default, Visual Studio assumes that such functions will not propagate exceptions.
If you don't turn this on, expect much pain. I spent hours on a testcase almost identical to yours before I realised this. 😃

Disabling Exceptions for MSVC

I'm trying to disable exceptions completely in Visual Studio 2010, and to ensure that exception handling is disabled I have the following test:
class CompilerFlagsTestExceptionConstructor
{
public:
CompilerFlagsTestExceptionConstructor() { throw std::exception("Exceptions Enabled"); }
~CompilerFlagsTestExceptionConstructor() { }
};
class CompilerFlagsTests : public CPPUNIT_NS::TestFixture
{
CPPUNIT_TEST_SUITE( CompilerFlagsTests );
CPPUNIT_TEST( Test_NoExceptions );
CPPUNIT_TEST_SUITE_END();
public:
void Test_NoExceptions()
{
try
{
CompilerFlagsTestExceptionConstructor object;
}
catch(std::exception)
{
assert(!"Exceptions are enabled");
}
}
};
I have checked in the property pages that exception handling is disabled, and I've also disabled RTTI in all my projects. I have tried setting /EH to negative as well as omitting it from the command line.
Every time I run this test, it fails and it properly throws an exception
The reason I want to disable exception handling is because the target software is written for a target architecture that doesn't natively support exception handling and causes massive code bloat to accommodate the stack unwinding. The target architecture also has a maximum size of executable, so disabling exceptions shrinks code and also has a performance benefit. I want to disable exception handling on the windows version to ensure that the error handling to the target is working.
Am I doing something wrong? Is this test ever going to work? Is there some other way of forcing and testing that exceptions are disabled?
Thanks!
That's not what /EH does, it merely controls what unwind handlers are emitted. /EHsc ensures that destructors are called when C++ exceptions might be raised, /EHa ensures that they're called for any exceptions, including SEH. Omitting /EH is what you want to cut down on handler overhead, the compiler omits the exception filters that get the destructors called on stack-allocated objects. Change the destructor to this:
~CompilerFlagsTestExceptionConstructor() {
assert(!"Something is wrong with /EH");
}
If you want the look for unwanted try/catch code then you'll need to pay attention to
warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
I'm not sure your test makes sense. What should the behavior be if exceptions are disabled? throw just becomes a no op? That's what the test suggests the behavior is.
I would expect for usefully disabling exceptions throw should be a compile error, or alternatively throwing with exceptions disabled should immediately terminate the process.
But this is a digression. MSVC will emit a call to _CxxThrowException for the throw syntax. If we define our own version of this we can make it dance to our song:
#include <windows.h>
#include <stdio.h>
extern "C"
void __stdcall _CxxThrowException(void * pObject,
_s__ThrowInfo const * pObjectInfo)
{
printf("Nope\n");
}
struct a
{ };
int main()
{
try {
throw a();
} catch(const a&) {
printf("Caught an exception\n");
}
}
This program prints out
Nope
Of course this information is provided for purely entertainment purposes and with the context that you're doing this to match up with the error handling logic. I hope for example, that you don't intend to ship the windows version of the program to anyone like this.
/EHsc- should do the trick (at least it does with msvc 14)

Finding out the source of an exception in C++ after it is caught?

I'm looking for an answer in MS VC++.
When debugging a large C++ application, which unfortunately has a very extensive usage of C++ exceptions. Sometimes I catch an exception a little later than I actually want.
Example in pseudo code:
FunctionB()
{
...
throw e;
...
}
FunctionA()
{
...
FunctionB()
...
}
try
{
Function A()
}
catch(e)
{
(<--- breakpoint)
...
}
I can catch the exception with a breakpoint when debugging. But I can't trace back if the exception occurred in FunctionA() or FunctionB(), or some other function. (Assuming extensive exception use and a huge version of the above example).
One solution to my problem is to determine and save the call stack in the exception constructor (i.e. before it is caught). But this would require me to derive all exceptions from this base exception class. It would also require a lot of code, and perhaps slow down my program.
Is there an easier way that requires less work? Without having to change my large code base?
Are there better solutions to this problem in other languages?
You pointed to a breakpoint in the code. Since you are in the debugger, you could set a breakpoint on the constructor of the exception class, or set Visual Studio debugger to break on all thrown exceptions (Debug->Exceptions Click on C++ exceptions, select thrown and uncaught options)
If you are just interested in where the exception came from, you could just write a simple macro like
#define throwException(message) \
{ \
std::ostringstream oss; \
oss << __FILE __ << " " << __LINE__ << " " \
<< __FUNC__ << " " << message; \
throw std::exception(oss.str().c_str()); \
}
which will add the file name, line number and function name to the exception text (if the compiler provides the respective macros).
Then throw exceptions using
throwException("An unknown enum value has been passed!");
There's an excellent book written by John Robbins which tackles many difficult debugging questions. The book is called Debugging Applications for Microsoft .NET and Microsoft Windows. Despite the title, the book contains a host of information about debugging native C++ applications.
In this book, there is a lengthy section all about how to get the call stack for exceptions that are thrown. If I remember correctly, some of his advice involves using structured exception handling (SEH) instead of (or in addition to) C++ exceptions. I really cannot recommend the book highly enough.
Put a breakpoint in the exception object constructor. You'll get your breakpoint before the exception is thrown.
There is no way to find out the source of an exception after it's caught, unless you include that information when it is thrown. By the time you catch the exception, the stack is already unwound, and there's no way to reconstruct the stack's previous state.
Your suggestion to include the stack trace in the constructor is your best bet. Yes, it costs time during construction, but you probably shouldn't be throwing exceptions often enough that this is a concern. Making all of your exceptions inherit from a new base may also be more than you need. You could simply have the relevant exceptions inherit (thank you, multiple inheritance), and have a separate catch for those.
You can use the StackTrace64 function to build the trace (I believe there are other ways as well). Check out this article for example code.
Here's how I do it in C++ using GCC libraries:
#include <execinfo.h> // Backtrace
#include <cxxabi.h> // Demangling
vector<Str> backtrace(size_t numskip) {
vector<Str> result;
std::vector<void*> bt(100);
bt.resize(backtrace(&(*bt.begin()), bt.size()));
char **btsyms = backtrace_symbols(&(*bt.begin()), bt.size());
if (btsyms) {
for (size_t i = numskip; i < bt.size(); i++) {
Aiss in(btsyms[i]);
int idx = 0; Astr nt, addr, mangled;
in >> idx >> nt >> addr >> mangled;
if (mangled == "start") break;
int status = 0;
char *demangled = abi::__cxa_demangle(mangled.c_str(), 0, 0, &status);
Str frame = (status==0) ? Str(demangled, demangled+strlen(demangled)) :
Str(mangled.begin(), mangled.end());
result.push_back(frame);
free(demangled);
}
free(btsyms);
}
return result;
}
Your exception's constructor can simply call this function and store away the stack trace. It takes the param numskip because I like to slice off the exception's constructor from my stack traces.
There's no standard way to do this.
Further, the call stack must typically be recorded at the time of the exception being thrown; once it has been caught the stack has unrolled, so you no longer know what was going on at the point of being thrown.
In VC++ on Win32/Win64, you might get usable-enough results by recording the value from the compiler intrinsic _ReturnAddress() and ensuring that your exception class constructor is __declspec(noinline). In conjunction with the debug symbol library, I think you could probably get the function name (and line number, if your .pdb contains it) that corresponds to the return address using SymGetLineFromAddr64.
In native code you can get a shot at walking the callstack by installing a Vectored Exception handler. VC++ implements C++ exceptions on top of SEH exceptions and a vectored exception handler is given first shot before any frame based handlers. However be really careful, problems introduced by vectored exception handling can be difficult to diagnose.
Also Mike Stall has some warnings about using it in an app that has managed code. Finally, read Matt Pietrek's article and make sure you understand SEH and vectored exception handling before you try this. (Nothing feels quite so bad as tracking down a critical problem to code you added help track down critical problems.)
I believe MSDev allows you to set break points when an exception is thrown.
Alternatively put the break point on the constructor of your exception object.
If you're debugging from the IDE, go to Debug->Exceptions, click Thrown for C++ exceptions.
Other languages? Well, in Java you call e.printStackTrace(); It doesn't get much simpler than that.
In case anyone is interested, a co-worker replied to this question to me via email:
Artem wrote:
There is a flag to MiniDumpWriteDump() that can do better crash dumps that will allow seeing full program state, with all global variables, etc. As for call stacks, I doubt they can be better because of optimizations... unless you turn (maybe some) optimizations off.
Also, I think disabling inline functions and whole program optimization will help quite a lot.
In fact, there are many dump types, maybe you could choose one small enough but still having more info
http://msdn.microsoft.com/en-us/library/ms680519(VS.85).aspx
Those types won't help with call stack though, they only affect the amount of variables you'll be able to see.
I noticed some of those dump types aren't supported in dbghelp.dll version 5.1 that we use. We could update it to the newest, 6.9 version though, I've just checked the EULA for MS Debugging Tools -- the newest dbghelp.dll is still ok to redistribute.
I use my own exceptions. You can handle them quite simple - also they contain text. I use the format:
throw Exception( "comms::serial::serial( )", "Something failed!" );
Also I have a second exception format:
throw Exception( "comms::serial::serial( )", ::GetLastError( ) );
Which is then converted from a DWORD value to the actual message using FormatMessage. Using the where/what format will show you what happened and in what function.
By now, it has been 11 years since this question was asked and today, we can solve this problem using only standard C++11, i.e. cross-platform and without the need for a debugger or cumbersome logging.
You can trace the call stack that led to an exception
Use std::nested_exception and std::throw_with_nested
This won't give you a stack unwind, but in my opinion the next best thing.
It is described on StackOverflow here and here, how you can get a backtrace on your exceptions inside your code without need for a debugger or cumbersome logging, by simply writing a proper exception handler which will rethrow nested exceptions.
It will, however, require that you insert try/catch statements at the functions you wish to trace (i.e. functions without this will not appear in your trace).
You could automate this with macros, reducing the amount of code you have to write/change.
Since you can do this with any derived exception class, you can add a lot of information to such a backtrace!
You may also take a look at my MWE on GitHub, where a backtrace would look something like this:
Library API: Exception caught in function 'api_function'
Backtrace:
~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed
~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"