У меня есть следующее сообщение «исключение первого шанса», которое исходит из написанной мной библиотеки DLL, которая выполняется внутри исполняемого файла, который я не писал. То есть DLL - это плагин. Когда это исключение возникает в первый раз, попытка открыть файл карты общей памяти завершается ошибкой. Если я игнорирую исключения первого шанса и просто запускаю, приложение в конечном итоге зависает или вылетает.
First-chance exception at 0x76a7c41f in notmyexe.exe: Microsoft C++ exception: boost::interprocess::interprocess_exception at memory location 0x002bc644..
По прошествии нескольких часов кажется, что это вызвано блоком кода, который зацикливается до тех пор, пока не будет устранено ожидаемое условие исключения. Оказывается, если он никогда не очищается, то, в конце концов, это исключение превращается в другое условие-исключение низкого уровня и / или превращается в повреждение кучи. Все это сделано для того, чтобы открыть общую область памяти с помощью Boost :: interprocess.
Первое, что усложняет ситуацию, это то, что в моем проекте на основе Visual C ++ 2008 первое boost::interprocess::interprocess_exception
исключение первого шанса не генерируется и не идентифицируется как место, откуда оно появилось, потому что компилятор Visual C ++ 2008 не может найти сложный код шаблонов с расширенным вкусом. обсуждаемый. Однако, пройдя один раз через представление на языке ассемблера, я обнаружил, что код взрывается.
Строка верхнего уровня моего собственного кода, в которой все начинает портиться:
segment = new managed_shared_memory( open_or_create
, MEMORY_AREA_NAME
, SHARED_AREA_SIZE );
Вышеупомянутый класс managed_shared_memory
взят из interprocess_fwd.hpp и является стандартной частью API / заголовков совместной памяти boost. Поскольку это основано на шаблоне, приведенное выше расширяется примерно до 2Kchars-длинного выражения шаблона Boost C ++, которое усекается на разную длину компоновщиком и отладчиком. Visual C ++ 2008 больше не имеет возможностей отладки исходного кода, кажется, когда действуют эти ограничения.
Например, когда он взрывается, я получаю такой стек вызовов:
KernelBase.dll!76a7c41f()
[Frames below may be incorrect and/or missing, no symbols loaded for KernelBase.dll]
KernelBase.dll!76a7c41f()
> msvcr90d.dll!_malloc_dbg(unsigned int nSize=2290875461, int nBlockUse=264, const char * szFileName=0x01fcb983, int nLine=1962999808) Line 160 + 0x1b bytes C++
8bfc4d89()
В приведенном выше дампе стека отсутствуют фактические исходные функции, написанные конечным пользователем.
Как мне отладить это? Во-вторых, есть ли известная проблема с межпроцессным ускорением в Visual C ++ 2008? В-третьих, что делает приведенный ниже код повышения и почему он должен бесконечно зацикливаться?
boost::interprocess::basic_managed_shared_memory<char,
boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family,
boost::interprocess::offset_ptr<void,int,unsigned int,0>,0>,
boost::interprocess::iset_index>::basic_managed_shared_memory<char,boo...
Дальше слоями вниз мы получаем:
basic_managed_shared_memory (open_or_create_t,
const char *name, size_type size,
const void *addr = 0, const permissions& perm = permissions())
: base_t()
, base2_t(open_or_create, name, size, read_write, addr,
create_open_func_t(get_this_pointer(),
ipcdetail::DoOpenOrCreate), perm)
{}
В любом случае, не пытайтесь отлаживать это дома, дети, вот что происходит:
Наконец, используя мою ниндзя-подобную способность одиночного перехода через несколько миллионов строк на языке ассемблера, я победил злые ограничения отладчика Visual C ++ 2008 и нашел рассматриваемый код.
Вот что взрывается на самом деле: create_device<FileBased>(dev...
.
Некоторый контекст здесь: managed_open_or_create_impl.h строка 351 ...
else if(type == DoOpenOrCreate){
//This loop is very ugly, but brute force is sometimes better
//than diplomacy. If someone knows how to open or create a
//file and know if we have really created it or just open it
//drop me a e-mail!
bool completed = false;
while(!completed){
try{
create_device<FileBased>(dev, id, size, perm, file_like_t()); // <-- KABOOM!
created = true;
completed = true;
}
catch(interprocess_exception &ex){
if(ex.get_error_code() != already_exists_error){
throw;
}
else{
try{
DeviceAbstraction tmp(open_only, id, read_write);
dev.swap(tmp);
created = false;
completed = true;
}
catch(interprocess_exception &e){
if(e.get_error_code() != not_found_error){
throw;
}
}
catch(...){
throw;
}
}
}
catch(...){
throw;
}
thread_yield();
}
}