Access violation after catching dll exception - c++

I have to load modules as dlls dynamically at runtime as they are not known ahead of time, just that they conform to a class interface. What I noticed is that after I catch an exception thrown by the dll (in the main program in the main thread), the right destructors are called and the modules destroyed and dll's unloaded, but then as the } at the end of the catch block is reached by the Visual Studio C++ debugger when stepping line by line, I get another exception which crashes the program with
First-chance exception at 0x68ad2377 (msvcr90d.dll) in xxxxx.exe: 0xC0000005: Access violation reading location 0x02958f14.
If I enable breaking on exceptions, breaking on this second exception shows the location as
msvcr90d.dll!__DestructExceptionObject(EHExceptionRecord * pExcept=0x0017ee4c, unsigned char fThrowNotAllowed=0) Line 1803 + 0xf bytes
but it looks like the frame stack may be corrupt. I can't figure out why this exception is thrown.
A simplified version of my code structure is as follows:
A very simplified structure of the program:
//shared header:
class Module
{
public:
virtual void Foo(void) = 0;
};
//dll:
class SomeSpecificModule : public Module
{
public:
virtual void Foo(void);
};
void SomeSpecificModule::Foo(void)
{
throw 1;
}
extern "C" __declspec(dllexport) Module* GetModule()
{
return new SomeSpecificModule;
}
//program:
typedef ptrGetModule* (*GetModule)();
int main(void)
{
HANDLE hMod = LoadLibrary("SomeSpecificModule.dll");
ptrGetModule GetModule = (ptrGetModule)GetProcAddress(hMod, "GetModule");
try
{
Module *d = GetModule();
d->Foo();
}
catch (...)
{
cout << '!' << endl;
}
return 0;
}

The thing to remember is that each copy of C runtime library has its own states. If SomeSpecificModule.dll is linking statically to the C runtime library, this kind of problem may happen. If that's the case, try linking with DLL version of of C runtime library. You also have to make sure SomeSpecificModule.dll is compiled and linked exactly the same way as your main module.
You mentioned DLL being unloaded and correct destructors were called, it sounded like your real program has a lot more going on than the sample you posted. If you unloaded SomeSpecificModule.dll in your try block, you've unloaded the exception record for SomeSpecificModule::Foo(), and I guess that's how you got the crash at msvcr90d.dll!__DestructExceptionObject(EHExceptionRecord * ...
However, in general throwing exception across DLL boundaries is asking for trouble. If you're throwing non POD object, you may run into issue with memory allocated by different C runtime library in different heap, different compiler setting, STL version...you get the point.
Change you code so you don't throw across DLL boundaries. One day someone from your team change the compiler setting or a third party header #define changed and your program start crashing you're going to have a very hard time tracing down the root cause.
Anyway, without seeing the real code, I'm just trying to guess what might go wrong. Hope it helps.

Much of the stack unwinding code that needs to be called when your DLL throws an exception is in the DLL. If you unload the DLL, how is that code to be called?
Don't throw exceptions across dynamically linked module boundaries.

Are you cathing the exception by value in your actual code? In this case there may be an exception in the destructor of the copied exception object at the end of catch block.

I don't see in this code where the DLL is unloaded (as you say it is). Can you please post the relevant code?
The DLL's unloading may be crucial, since your DLL contains the code necessary for destructing objects, unwinding the stack, etc. and it isn't clear from what you posted at which point the DLL is unloaded.

Check poject settings, if your application is multithreaded then you should link to multithreaded DLL

Canopus: when I throw an int as the exception, the same thing happens.
TK___: I am linking to multithreaded dll in all projects.
Assaf and Shing Yip: The dll's are indeed unloaded by FreeLibrary() in the destructor of a wrapper for them, as the wrapper objects I push into a vector of tr1::shared_ptr (as the wrapper itself is noncopyable as a resource holder and so can't be put in an STL vector) existing only in the try{} scope. It seemed like the right thing to do, so I can make sure cleanup including DLL unloading when there is an error situation, and I tend to prefer RAII-style design. If this is the source of the problem, then I'm wondering what sort of design to use that would operate correctly and still look good from a software engineering perspective.
What makes me suspect this may not be the problem, however, is that when I step through the destructor calls that occur when the exception is thrown, FreeLibrary() runs with no error, and I can continue stepping until I get to the closing } of the catch{}.
Magnus Skog: In release mode I also get a crash rather than catching the exception then continuing execution normally.
Dynamic memory is handled with 1) operator new in a few cases, 2) tr1::shared_ptr, and 3) _mm_malloc/_mm_free where I need alignment.

This might be a shot in the dark, but worth checking out.
Your application seems to be compiled in DEBUG since the error shows up in msvcr90d.dll. Are the dlls you are using also compiled in DEBUG? Creating memory with msvcr90.dll and freeing with msvcr90d.dll or vice versa is a common problem when using dlls.
I think your function pointer typedef looks a little suspicious. I'd write it like this:
typedef Module* (*moduleFnType)();
int main(void)
{
HANDLE hMod = LoadLibrary("SomeSpecificModule.dll");
moduleFnType GetModule = (moduleFnType)GetProcAddress(hMod, "GetModule");
try
{
Module *d = GetModule();
d->Foo();
}
catch (...)
{
cout << '!' << endl;
}
return 0;
}
Your typedef doesn't say anything about the return type of the function GetModule.

Related

Can a thrown exception be accessed in a C++ catch(...) block

I have GDB attached to a process that is currently inside a catch(...) block.
Is there a known technique to access that thrown exception?
The program in question is a gcc/x86-64 binary, but I'm also curious about other builds.
As you say, you can re-throw it, so you can re-throw it inside another try/catch block with more specific clauses to extract the exception (and another ... if you want as well). You can even do this inside another function so you can centralize your exception handling.
Edit: I misunderstood the importance of gdb in your question, but you can apply the idea I described. Make a function that re-throws the exception you can set a breakpoint in:
void
helper()
{
try {
throw;
} catch (int i) {
// anything that won't get optimized away
volatile int j = i; // breakpoint here
}
}
Then in gdb just do call helper(). I just tested this to be sure it worked.
Further edit: If you literally mean I'm running a program under gdb right now and you are not exiting gdb until you are sure you can't get the exception, then it's time to look at eh_throw.cc and friends in the gcc source. __cxa_rethrow starts with:
__cxa_eh_globals *globals = __cxa_get_globals ();
__cxa_exception *header = globals->caughtExceptions;
You will have to examine all of those structures to figure out what's buried inside.
I have not tested this - but the exception (or at least a pointer to it) should probably be on the stack somewhere close to the head. I guess the exact position and format is implementation dependent, but you should be able casting different addresses in this area of the stack to your exception type (or at least to std::exception) and see if you get meaningful results.

MS Visual Studio 2005 C++ exception handling

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.

Crash with new/delete, but not with malloc/free in C++ code

My developement environment is [Windows 7; visual studio 2010; x86].
I have a dll that was built for server 2003 long time back. When I use it in my project and follow new/delete sequence to use a class, application crashes during delete call. I verified the same even without any other call between new and delete. When I replace new/delete with malloc/free, there is no crash. If I simply declare an instance of the class without new, no crash happens when scope is exited.
Any idea what may be going wrong? This is internal library of our company, so I will not be able to name it and other such stuff.
Additional Information:
To use this library in first place, I had to turn off VS feature "Treat wchar_t as built-in type".
Code is simple
{
CLogger * myLog = new CLogger();
delete myLog; // Crash happens here
}
{ // No crash here
CLogger MyLog;
}
{
CLogger * myLog = (CLogger *) malloc (sizeof(CLogger));
free (myLog); // This does not crash.
}
This being proprietary library, I cannot post constructor and destructor.
delete does more than just freeing memory: it also calls the destructor before. That means that there must be something bad in the destructor of that class.
If an uncaught exception occurs in a destructor the whole process exits (*).
As commented below (thanks for the good feedback) this is over-simplified here is a good link for more details:
throwing exceptions out of a destructor
I would recommend you to put a
try {} catch (std::exception& e){} catch(...) {}
inside the destructor and log out what is going on, or better let it go through the debugger with the option to stop at the place where the exception is thrown.
Then it should be easy to identify what is different. Just a guess from me, it may be some registry access or file access rights, where some changes were introduced from server 2003 to windows 7.
I apply my psychic debugging skills to suggest that you are using delete where you should be using delete[].
Reasoning: if you were able to trivially replace new with malloc, you're probably allocating an array of primitive types rather than an object, and naively using delete in place of free on the assumption that object allocation and array allocation are the same in C++. (They're not.)

Does getting random SIGTRAP signals (in MinGW-gdb) is a sign of memory corruption?

I wrote my own reference counted memory manager c++ (for fun) and I'm sure it isn't perfect ;) . And now when I'm trying to use it I got random SIGTRAP signals. If I comment out every line which are in connection with that memory manager everything runs fine. Getting SIGTRAP-s instead of SIGSEGV is quite strange.
I know that SIGTRAP-s are thrown when the program hits a breakpoint, but no breakpoint is set. I read in an other thread that debug builds of the exe's and dll's must be up to date. They are up to date and so it is not the reason.
Does anyone know why is this happening?
After searching on Google I realized that those sigtraps are same as those warnings you get in MSVC++ saying "Windows has triggered a breakpoint in xxxx.exe. This may be due to a corruption of the heap, and indicates a bug blahblahblah"...
So it seems yes, unexpected sigtraps can indicate memory corrupction (quite strange...)
And I found my bug too. The MM is in a static library which is linked to a dll. And that static lib and the dll is linked to my exe. So there were two memory managers, one in my exe and one in my dll. If call the initaialization method of the MM. It initialized the MM in my exe but not in the dll so the dll went without init. I solved this by not linking my exe against that static library.
I'd throw in a guess that you might be calling mismatched new/delete or malloc/free implementations - So something was allocated by your memory manager but when the memory is released you end up with the default delete/free implementation.
Set a breakpoint on the signal and see whether there is free() or operator delete on the stack and whether that is the implementation of said function which you would expect.

How applications can be protected from errors in DLL module

I have DLL and application that will call some function in this dll. For example...
DLL function:
char const* func1()
{
return reinterpret_cast<char const*>(0x11223344);
}
Application code:
func1 = reinterpret_cast<Func1Callback>(::GetProcAddress(hDll, "func1"));
blablabla
char const* ptr = func1();
cout << ptr;
That DLL is not under my control (plugin)..
Same code will cause access violation in my application, so... Is there any mechanism that will allow to determine such errors?
Since the DLL can do anything your program could do the only reliable way is to load it into a separate worker lightweight process and once anything bad happens just restart the process. You'll need some protocol to pass data into the worker process and receive results.
The dll is loaded into your process address space. If it accesses some invalid memory location your process will crash. I don't see any way around it other than not using this dll at all.
If a DLL is returning junk memory addresses to your application, I'd say you shouldn't be using it, because it isn't performing its intended/desired function.
Also, don't try to guard against it by using the Win32 IsBad*Ptr class of functions, as the MSDN documentation states (see also this post by Raymond Chen for a good description of why not).
You can enclose function call into try catch block, it'll help not to crush entire application right at function call, but nobody can garantee, that dll loaded will not alter memory somwhere in your code, in this case yo'll get hard to debug crash in other place. So you can probably raise some protection for just access violation, but anyway cannot fully protext you application for some side effects.