Повышение исключительных ситуаций приводит к повреждению указателя стека (Ошибка проверки времени выполнения #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. Если это работает, то вы можете быть уверены, что проблема заключается в том, как вы строите или связываете вещи.

Другие вопросы по тегам