I require the use of LoadLibrary
and GetProcAddress
to call functions from some dlls (which plug into my app), but I don't want them to be able to hang my program by containing an infinite loop or hanging themselves, so I'm trying to use boost::thread
(no experience) to circumvent that. However, if a function does hang, I crash with ACCESS_DENIED (0x00000005) when calling FreeLibrary
to clean up.
Here's a minimal DLL (mydll.dll
) that reproduces the problem:
extern "C" {
void __declspec(dllexport) foo() {
for(;;); //<-- infinite loop
}
}
And here's a minimal cpp that crashes. I've left out error checking for brevity, but I can assure you no errors are given:
#include <boost/thread.hpp>
#include <iostream>
#include <windows.h>
int main() {
using FuncType = void (*)();
HMODULE dll = LoadLibrary("mydll.dll");
FuncType func = (FuncType)GetProcAddress(dll, "foo");
boost::thread thr = [func] {func();};
if (!thr.timed_join(boost::posix_time::seconds(1))) {
std::cout << "Timed out.";
//thr.detach();
FreeLibrary(dll);
}
for (;;);
}
Upon running this, "Timed out." is printed and the call stack (gdb on CodeBlocks) at the crash is as follows:
#0 00000000 0x6c1c1214 in ??() (??:??)
#1 0040133E operator() (__closure=<optimized out>) (C:\...\thread test.cpp:17)
#5 00000000 0x00000000 in ??() (??:??)
Without optimizations, that becomes:
#0 00000000 0x6c1c1214 in ??() (??:??)
#1 00401348 operator() (__closure=0x898f90) (C:\...\thread test.cpp:17)
#2 00401780 boost::detail::thread_data<main()::<lambda()> >::run(void)(this=0x898f70) (c:/.../boost/thread/detail/thread.hpp:62)
#5 00000000 0x00000000 in ??() (??:??)
The first thing I tried was adding in the thr.detach();
line that I commented out above, but that produced the same result.
I've also tried the following to no avail:
FreeLibrary
line --- works fine, but I'd rather free it after loading it, even if it is reference-based. I'm also cautious about that kind of behaviour working later on.LoadLibrary
or anything and inlining the infinite loop --- works fine, but I need to use DLLs:boost::thread thr = []{for (;;);};
The DLL and cpp were both compiled on Windows 7 64-bit using GCC 4.7.1 with 32-bit output types. My version of Boost is 1.49.0. If memory serves, I think I got one or two tests in on Windows XP 32-bit (same compiler etc) before moving to a different computer as well.
Why is this crashing? How can I ensure a function I call dynamically doesn't hang my program?
Fundamentally, you can't do that. Threads don't provide that kind of isolation. Use processes if you need that.