On 15/12/2016 20:46, Niall Douglas wrote:
Also, I'm not sure about other compilers, but with MSVC thrown exceptions always carry a stack trace with them anyway; it's possible to extract the stack trace from any exception with some platform-dependent code (without any decoration on the throw -- and depending on build options, it can even work for null references and other CPU exceptions, although some misguided people dislike that).
I was not aware that this is the case except when /EHa is used. Indeed, I had thought one of the big optimisations of /EHs was precisely the fact that backtraces are *not* captured, thus making C++ exception throws vastly faster than Win32 structured exception throws and the point of using /EHs.
I don't think so. The docs simply indicate that it reduces the locations where it captures unwind info and does some checks. This does increase performance by reducing code size (and thus the working set) and removing some conditional logic, but it comes at the cost of failing to execute some destructors if an exception does get thrown/raised. (Which is probably ok if the process is going to be terminated by an uncaught exception anyway, but less so if not.) I didn't see anything about changing the actual implementation of exceptions. The following code *does* print "caught exception" (in both Debug and Release) even when compiled with /EHsc. Granted I suppose this doesn't explicitly prove that a stack trace was captured, but I think it proves that C++ exceptions are still internally implemented as SEH exceptions, and so GetExceptionInformation (among other things) can probably still be used to extract the stack context. void badfn() { throw std::runtime_error("error"); } template<typename F> void seh_wrapper(F fn) { __try { fn(); } __except (EXCEPTION_EXECUTE_HANDLER) { std::cout << "caught exception" << std::endl; } } int main(int argc, char* argv[]) { seh_wrapper(&badfn); std::cout << "completed" << std::endl; return 0; }