6

I'm using a method from 3rd party dll and it throws "Access violation reading location 0x00000000" exception. I cannot dig in so I'm only wondering if there is anyway to catch it so not collapse the application. I tried the following 4 methods but none of them works.

1,

try
    {
    sts = resFilter->initialize(m_JPEG2000File); // it throws that exception
    }
    catch (...){
        printf("Gotcha0...");
        int a = 34;
    }

2, 3 and 4

LONG WINAPI CrashHandler1(EXCEPTION_POINTERS * a/*ExceptionInfo*/)
{  std::cout << "Gotcha1!" << std::endl;
return 0;
}

void CrashHandler2()
{    std::cout << "Gotcha2!" << std::endl;}

void CrashHandler3()
{    std::cout << "Gotcha3!" << std::endl;}

// in Main()
::SetUnhandledExceptionFilter(CrashHandler1);
std::set_terminate (CrashHandler2);
std::set_unexpected( CrashHandler3 );

Test(); // It would throw "Access violation reading location 0x00000000" exception 

If I debug it, exception would be thrown. If I run it in run time, "Gotcha1!" would be displayed in the console but the application would still collapse. Is there any way I can eat this exception?

Thanks in advance,

Ben

Edit:

@Adriano Repetti mentioned __try and __except can catch this exception.

Thanks for all you guys heads-up for not eating that exception!

I have an external C# executable calling this project. I want to catch this exception so I have chance to log the error and do not collapse the C# application. I would still terminate this very c++ process. I'm looping the data in C# which would start a new C++ process from scratch every time, so it would be a new C++ instance. So Adriano's approach works for me.

Ben
  • 73
  • 1
  • 1
  • 6
  • 3
    try with `__try` and `__except` (access violation isn't something _known_ by C++) but I'd suggest to do **not** do it. You don't know what did happen, you don't know what has been executed, memory (and data!) may be corrupted even in YOUR code. – Adriano Repetti Jun 12 '15 at 15:03
  • BTW it may even be your code that corrupted their data... – Adriano Repetti Jun 12 '15 at 15:09
  • 1
    If you use MSVC++ then you can simply change a compile option, use /EHa and catch (...) will eat. Don't run that code again, it will eat your lunch. A telephone will forever be the best way to deal with this, be sure to have a small repro project available when you call the programmer of this library. – Hans Passant Jun 12 '15 at 15:27
  • Thanks Adriano and Hans, I will try right away. if I load another file everything works fine so I'm sure the exception is thrown internally from their assembly. I was opening all the files in a folder, and if one has issues I just want to skip it and get to the next. So I think "eat" the exception is relatively safe for me. – Ben Jun 12 '15 at 15:36
  • @Adriano Repetti, Thanks __try works. – Ben Jun 12 '15 at 15:58

2 Answers2

5

Do not "eat" access violations; that way abject madness lies.

It seems to me that you're trying to dereference a null pointer. Perhaps simply do not do that!

if (!resFilter) {
   // do something else; e.g. did you fail to initialise the library properly?
   throw "Yikes!";
}

// OK; pointer is not NULL at least: let's go!
sts = resFilter->initialize(m_JPEG2000File);

Now, if you get an access violation from that, then the library is exceedingly buggy and you should cease using it immediately unless a fix or patch is available.

Since you're on Windows, if all you want to do is detect the problem for logging purposes, you can use Visual Studio's non-standard __try/__catch construct, but be sure to immediately terminate the process after logging the problem, because your process (particularly the state of the library) will be unstable and nothing you do with it after that will have any meaning!

__try  { 
    sts = resFilter->initialize(m_JPEG2000File);
} 
__except(
   GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION
   ? EXCEPTION_EXECUTE_HANDLER
   : EXCEPTION_CONTINUE_SEARCH) { 
    std::cerr << "OMG!\n";
    exit(-1);
}
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • I checked all the pointer I can reach and none of them is NULL. Also if I load another file everything works fine. So I'm sure the exception is thrown internally in the 3rd party assembly. I was opening all the files in a folder, and if one has issues I just want to skip it and get to the next. That's why I want to "eat" the exception to not collapse the entire app. – Ben Jun 12 '15 at 15:33
  • 1
    @Ben: _"if one has issues I just want to skip it and get to the next"_ That's really unlikely to go well. If you're "skipping over" a NULL pointer dereference of all things, you should consider the process unstable after that. You know at that point that at least one critical precondition does not hold. Nothing that happens after that can be relied upon, so it's pretty pointless moving on to "the next" issue when you've probably just caused loads yourself. :) – Lightness Races in Orbit Jun 12 '15 at 15:48
  • Thanks for the heads up! I understand the risk but there is nothing else I can do. It's in the 3rd party dll and I cannot fix it. I'm thinking catch the exception, clean all the resources and start over everything before moving to the next, that should be safe and good enough for me. Thanks to Adriano Repetti, __try works! – Ben Jun 12 '15 at 15:58
  • @Ben: It's not "risk": it's completely pointless. You are literally defeating the object of doing what you're trying to do. As I've already explained, it is _not_ safe and it is _not_ good enough for you! – Lightness Races in Orbit Jun 12 '15 at 16:01
  • what's your suggestion then? Given I cannot change that 3rd party dll and I just want to skip loading the file with issues. – Ben Jun 12 '15 at 16:03
  • 1
    @Ben I completely agree with LRiO! Your own data may be completely corrupted (you see a crash when it access 0x00 but it may first destroy half your code segment). Even if they're not...process is in a undefined state. It may crash later and you'll try to debug a perfectly valid code. Do not do it. If there is this case then **run an EXTERNAL process FOR EACH file you have to process** and check its return code to see if that DLL can be loaded or not. If it's safe then load it in your own app. – Adriano Repetti Jun 12 '15 at 16:04
  • @Ben: Well, you're either using the library wrong or it has a horrific bug in it. Since you cannot do much about the latter beyond talking to its developers (this is worth doing!), focus on the former for now. What preconditions might you be breaking? Are you not adequately checking for error codes? If you rule out all of these then yes you are in a difficult position, but arbitrarily "eating up" access violations is going to make that position worse, not better. – Lightness Races in Orbit Jun 12 '15 at 16:15
  • Thanks for your comments LRiO and Adriano! I catch this exception so I have chance to log the error, I would still terminate this very process. I have an external C# process to loop the data and it would start a new C++ process from scratch every time, so it would be a new complete instance. Sorry for not have made it clear. Thanks Adriano __try works. and I would update the 3rd party dll see if they have fixed that. – Ben Jun 12 '15 at 16:36
  • @Ben: Oh well that makes a bit more sense :) Good luck. – Lightness Races in Orbit Jun 12 '15 at 17:33
  • @Ben: I have added a code solution bearing this in mind. – Lightness Races in Orbit Jun 12 '15 at 17:40
  • @LightnessRacesinOrbit: until today, I thought undefined behavior is something that happens on compiler level. I.e. you have code that might cause UB -> you can't trust your program at all (from the beginning). Now you say it's ok until UB is actually invoked, i.e. until the Access Violation actually occurred? – Thomas Weller Jan 18 '21 at 15:21
1

__try and __except can catch this exception. Thanks to @Adriano Repetti!

Here is a good post about it: C++, __try and try/catch/finally

Community
  • 1
  • 1
Ben
  • 73
  • 1
  • 1
  • 6
  • `__try`, `__except` and such is not C++. It is not possible to catch such "exceptions" in C++. In fact, from the C++ pint of view there's no exception here at all. The code is simply broken and produces undefined behavior. Trying to "suppress" such errors in a "3rd party dll" with `__try` and `__except` is a completely pointless endeavor. – AnT stands with Russia Jun 12 '15 at 17:02
  • I had not to mention that...Ben, do not do it like that. Seriously! – Adriano Repetti Jun 12 '15 at 17:26
  • Guys, I catch this exception so I have chance to log the error, I would still terminate this very process. I have an external C# process to loop the data and it would start a new C++ process from scratch every time, so it would be a new complete instance. So it works for me. Sorry for not have made it clearer, and thanks for your input! – Ben Jun 12 '15 at 17:58