I've the following code:
try {
// do some stuff
}
catch(const my_exception_type& e) {
LOG("Exception %s", e.what());
throw;
}
The problem is that in debug build the LOG is defined as #define LOG(...) real_logger(...), but in release build is defined as #define LOG(...) \\ do nothing.
Of course when I'm compiling my release code in Visual Studio, I'm getting the warning C4101: 'e' : unreferenced local variable.
What is the best practice to handle exception logging without generation any unnecessary warnings?
P.S
I'm doing nothing with the exception except logging and re-throwing it.
You can mark the object as "used" by casting it to void.
It has no influence on the generated machine code, but it will suppress the compiler warning.
try {
// do some stuff
}
catch(const my_exception_type& e) {
(void)e;
LOG("Exception %s", e.what());
throw;
}
You can #ifdef each catch line (very invasive) or add just a line in each catch block:
catch(const my_exception_type& e) {
UNREFERENCED_PARAMETER(e);
LOG("Exception %s", e.what());
throw;
}
And the warning is gone. Or, you can #define MY_EXCEPTION_CATCH(...) to define the e parameter only in debug build.
Related
I am using MSVC2019 and COM and compiling using /EHa
getting a SEH from ntdll.dll from TppRaiseInvalidParameter that I am trying to catch but seem unable to. I know exactly why the exception is thrown, but that is not the issue here.
I tried using all the mechanisms described in the MSDN docs (__try/__except, _set_se_translator, SetUnhandledExceptionFilter), but none seem to trigger in this case.
I also tried raising exceptions using RaiseException and RtlRaiseException (used by TppRaiseInvalidParameter) and those seem to be caught no problem in the __except handler.
The only thing I've been able to spot in TppRaiseInvalidParameter is that it calls __SEH_prolog4_GS at the beginning, but from what I've read that is normal code generated by the compiler for SEHs, but I'm new to SEHs in general.
My questions are: why can't I catch that exception? Is there any way to catch it?
Minimal code for reproduction
extern "C"
{
void (WINAPI* TppRaiseInvalidParameter)();
}
void func()
{
__try
{
HMODULE ntdll;
GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "ntdll.dll", &ntdll);
TppRaiseInvalidParameter = reinterpret_cast<decltype(TppRaiseInvalidParameter)>((LONG)ntdll + 0x104EBDL); // it's not an exported function and your offset may be different
TppRaiseInvalidParameter();
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
puts("exception caught");
}
}
In my iOS project, I use a C++ module. The C++ module throws exception for some cases and the Objective C++ wrapper fails to catch it. For instance
Here is my HelloWorld.h
#include <string>
using namespace std;
class HelloWorld{
public:
string helloWorld();
};
#endif
Implementation HelloWorld.cpp
#include "HelloWorld.h"
string HelloWorld::helloWorld(){
throw (std::runtime_error("runtime_error")); // Throwing exception to test
string s("Hello from CPP");
return s;
}
Objective C++ wrapper HelloWorldIOSWrapper.h
#import <Foundation/Foundation.h>
#interface HelloWorldIOSWrapper:NSObject
- (NSString*)getHello;
#end
#endif /* HelloWorldIOSWrapper_h */
Implementation HelloWorldIOSWrapper.mm
#import "HelloWorldIOSWrapper.h"
#include "HelloWorld.h"
#implementation HelloWorldIOSWrapper
- (NSString*)getHello{
try {
HelloWorld h;
NSString *text=[NSString stringWithUTF8String: h.helloWorld().c_str()];
return text;
} catch (const std::exception & e) {
NSLog(#"Error %s", e.what());
}
return nil;
}
#end
#import "HelloWorldIOSWrapper.h" is added to the Bridging-Header
And now, when I try to invoke getHello() from controller, app crashes leaving the below message in log
libc++abi: terminating with uncaught exception of type std::runtime_error: runtime_error
dyld4 config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/Developer/usr/lib/libBacktraceRecording.dylib:/Developer/usr/lib/libMainThreadChecker.dylib:/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib
terminating with uncaught exception of type std::runtime_error: runtime_error
I expect that the exception must be caught in the wrapper, but, no idea why is it not caught leading to app crash. What do I miss?
C++ Interoperability
In 64-bit processes, Objective-C exceptions (NSException) and C++
exception are interoperable. Specifically, C++ destructors and
Objective-C #finally blocks are honored when the exception mechanism
unwinds an exception. In addition, default catch clauses—that is,
catch(...) and #catch(...)—can catch and rethrow any exception
On the other hand, an Objective-C catch clause taking a dynamically
typed exception object (#catch(id exception)) can catch any
Objective-C exception, but cannot catch any C++ exceptions. So, for
interoperability, use #catch(...) to catch every exception and #throw;
to rethrow caught exceptions. In 32-bit, #catch(...) has the same
effect as #catch(id exception).
#try {
}
#catch (...) {
}
I use pcl 1.7 tracking code and In some cases this method:
tracker_->compute ();
Gives me these errors:
[pcl::ApproxNearestPairPointCloudCoherence::initCompute] PointCloudCoherence::Init failed.
[pcl::ApproxNearestPairPointCloudCoherence::compute] Init failed.
I now know that error is thrown and I would like to catch exactly this error to tell the program what to do if this error occurs. I tried like this:
try
{
tracker_->compute ();
}
catch (...)
{
std::cout<<"inside the exception"<<std::endl;
}
To catch all the errors but it did not work..... And also with
catch(pcl::ApproxNearestPairPointCloudCoherenceException &e)
my program did not even compile....
So any ideas what I do wrong?
I browsed the source in order to look for the location where the error is raised, and found out that in your specific case it is raised by
if (!PointCloudCoherence<PointInT>::initCompute ())
{
PCL_ERROR ("[pcl::%s::initCompute] PointCloudCoherence::Init failed.\n", getClassName().c_str());
return (false);
}
so you see, there is no throw xxx here but only a macro which hides the actual error handling from us.
To find out what exactly was happening, I then searched for a definition of PCL_ERROR and the search yielded that it is defined in the file print.h as
#define PCL_ERROR(...) pcl::console::print (pcl::console::L_ERROR, __VA_ARGS__)
with pcl::console::print being a function simply printing the error, not throwing an exception.
So, you cannot catch the error because it is not an exception, but rather only plain text written to the console.
I export a function from d to c++ with extern(C++). The d code has a try catch statement on the highest level.Whenever the d code throws a exception the program aborts. I have c++ objects on the call stack and call the function in d. Then there is the d try catch statement and then the d exception throw.
The d code:
extern (C++) void ThrowEx() {
try {
throw new Exception("hello");
} catch (Exception ex) {
}
}
The c++ code:
extern "C" int rt_init();
void ThrowEx();
void func() {
rt_init();
ThrowEx();
}
When I change ThrowEx to not throw an exception everything works as expected. The d code gets executed and no error occurs.
When the program crashes the following output is generated:
dwarfeh(224) fatal error
uncaught exception
I'm currently working on a game with a plugin based architecture. The executable consists mostly of a shared library loader and a couple of interface definitions. All the interesting stuff is happening in dynamic shared libraries which are loaded at start up.
One of the library classes throws an exception under certain circumstances. I would expect to be able to catch this exception and do useful stuff with it but this is where it gets weird. See following simplified example code:
main.cpp
int main()
{
try
{
Application app;
app.loadPlugin();
app.doStuffWithPlugin();
return 0;
}
catch(const std::exception& ex)
{
// Log exception
return 1;
}
}
Application.cpp
...
void doStuffWithPlugin()
{
plugin.doStuff();
}
...
Plugin.cpp
...
void doStuff()
{
throw exception_derived_from_runtime_error("Something is wrong");
}
...
Plugin.cpp exists in a dynamic shared library which is successfully loaded and which has afterwards created an object of class Plugin. The exception_derived_from_runtime_error is defined in the application. There is no throw() or noexcept.
I would expect to catch the exception_derived_from_runtime_error in main but that doesn't happen. Compiled with GCC 4.8 using C++11 the application crashes with This application has requested the Runtime to terminate it in an unusual way..
I replaced catch(const std::exception& ex) with catch(...) but that didn't make any difference. The weird part is if i catch the exception in doStuffWithPlugin() it works. If i rethrow it using throw; it fails again but it can be caught if i use throw ex;:
Application.cpp
void doStuffWithPlugin()
{
try
{
plugin.doStuff();
}
catch(const exception_derived_from_runtime_error& ex)
{
// throw; <- Not caught in main().
// throw ex; <- Caught in main().
}
}
Hopefully somebody has an idea. Thanks for every help you can give.
As mentioned in the comments this seems to be a problem with shared libraries on Windows. The behavior occurs if the library is unloaded and an object created in this libraries remains in memory. The application seems to crash immediately. The only reference to this problems are found if gcc as an cross compiler or MinGW is used. See also https://www.sourceware.org/ml/crossgcc/2005-01/msg00022.html