Я требую использования LoadLibrary
а также GetProcAddress
вызывать функции из некоторых библиотек (которые подключаются к моему приложению), но я не хочу, чтобы они могли повесить мою программу, заключив в себе бесконечный цикл или повесив себя, поэтому я пытаюсь использовать boost::thread
(нет опыта), чтобы обойти это. Тем не менее, если функция зависает, я вызываю сбой с ACCESS_DENIED (0x00000005) при вызове FreeLibrary
очистить.
Вот минимальная DLL (mydll.dll
) что воспроизводит проблему:
extern "C" {
void __declspec(dllexport) foo() {
for(;;); //<-- infinite loop
}
}
И вот минимальный cpp, который вылетает. Я упустил проверку ошибок для краткости, но я могу заверить вас, что никаких ошибок не дано:
#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 (;;);
}
После запуска этого, «Тайм-аут». печатается и стек вызовов (gdb на CodeBlocks) при сбое выглядит следующим образом:
#0 00000000 0x6c1c1214 in ??() (??:??)
#1 0040133E operator() (__closure=<optimized out>) (C:\...\thread test.cpp:17)
#5 00000000 0x00000000 in ??() (??:??)
Без оптимизации это становится:
#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 ??() (??:??)
Первое, что я попробовал, было добавить в thr.detach();
Строка, которую я прокомментировал выше, но которая дала тот же результат.
Я также попробовал следующее безрезультатно:
FreeLibrary
line — работает нормально, но я бы предпочел освободить его после загрузки, даже если он основан на ссылках. Я также осторожен с таким поведением, которое будет работать позже.LoadLibrary
или что-нибудь и встраивание бесконечного цикла — работает нормально, но мне нужно использовать DLL:boost :: thread thr = [] {for (;;);};
DLL и cpp были скомпилированы в 64-битной Windows 7 с использованием GCC 4.7.1 с 32-битными типами вывода. Моя версия Boost 1.49.0. Если память работает, я думаю, что я получил один или два теста на 32-битной Windows XP (тот же компилятор и т. Д.), Прежде чем перейти на другой компьютер.
Почему это сбой? Как я могу гарантировать, что функция, которую я вызываю динамически, не вешает мою программу?
По сути, вы не можете этого сделать. Потоки не обеспечивают такую изоляцию. Используйте процессы, если вам это нужно.
Других решений пока нет …