Повышение исключительных ситуаций приводит к повреждению указателя стека (Ошибка проверки времени выполнения #0 ...)
В небольшом проекте я использую несколько буст-пакетов (asio, property_tree, файловая система и т. Д.) И должен был заметить, что все работает нормально, пока где-то в буст-пакетах не возникнет исключение. Это происходит во всех этих пакетах, но теперь я смог свести его к следующей минимальной программе:
#include <iostream>
#include "boost/throw_exception.hpp"
int main(int argc, char* argv[])
{
boost::throw_exception(std::exception("foo")); // <-- this will produce the problem
throw std::exception("foo"); // <-- this works as expected
return 0;
}
Исключение выдается нормально, но когда программа завершается, я получаю
Run-Time Check Failure #0 - The value of ESP was not properly
saved across a function call ...
Я попытался отладить это (я использую Boost 1.49.0 в Visual Studio 2010 Express с CRT статически связаны), но проблема возникает, когда весь видимый код уже выполнен. Я вижу, что деструктор std:exception не прошел, но после этого ("в" операторе возврата моей программы) открывается окно сообщения.
РЕДАКТИРОВАТЬ: Некоторые дополнительные данные:
- В приведенной выше минимальной программе boost использует только заголовки
- Никакие другие lib-файлы не задействованы
- Только ntdll.dll и kernel32.dll загружаются программой
- Никакие дополнительные темы не создаются
- Проблема также появляется, когда я связываюсь динамически против CRT
EDIT2: опять больше информации:
- добавил, включает в программу выше
- проблема появляется также, когда я бросаю runtime_error вместо
- проблема исчезает, когда я ловлю исключение с помощью (...) или (std::exception)
- проблема даже остается вылеченной, когда я отбрасываю исключение
1 ответ
Можете ли вы попробовать использовать динамическое время выполнения, чтобы и Boost, и ваша программа использовали один и тот же? Если вы статически связываетесь со средой выполнения, то в процесс может быть загружено две среды выполнения, что может вызвать проблемы. В последний раз, когда я увидел эту проблему, она была вызвана различными соглашениями о вызовах между программой и DLL (например, cdecl / fastcall / pascal). Просто использование статической среды выполнения не должно иметь никакого значения.
Кстати: есть простой тест, который вы можете сделать, чтобы выяснить, где ошибка. Если вы включите соответствующий код из Boost в свою программу, вы фактически получите на месте скомпилированный, статически связанный Boost. Если это работает, то вы можете быть уверены, что проблема заключается в том, как вы строите или связываете вещи.