Разъяснение по обработке исключений в C ++ / CLI в смешанных собственных / управляемых сценариях

У нас есть приложение, которое использует собственные библиотеки и написано на C ++ / CLI.

В наших собственных библиотеках есть собственный класс исключений C ++ ErrorException.

Код структурирован таким образом, что основной цикл приложения находится в машинном коде, который затем вызывает (управляемый) код приложения, который, в свою очередь, иногда вызывает обратно в собственную библиотеку.

Собственные библиотеки скомпилированы с / EHsc (за исключением той, которая скомпилирована с / EHa, что мне кажется неправильным из-за проблемы, когда catch (...) улавливает структурированные исключения, такие как нарушения доступа!).

Что я сделал, так это то, что я обернул (большинство) функций в код C ++ / CLI, который (я считаю) может генерировать управляемые исключения в макросах _1 _ / _ 2_, как определено ниже:

#define MANAGED_TRY_START try {
#define MANAGED_TRY_END \
    } \
    catch(System::Runtime::InteropServices::SEHException^) { \
        throw; \
    } \
    catch(System::Exception^ ex) { \
        ConvertAndThrowSystemException(ex); \
        throw NULL; \
    } \

где ConvertAndThrowSystemException является функцией, которая превращает System :: Exception в ErrorException и выбрасывает его.

Теперь мой вопрос: этого достаточно? Я спрашиваю, потому что это конкретное приложение часто демонстрирует нестабильность и проблемы с памятью, и я боюсь, что в этом виноваты исключения.

Кстати, мы используем dr.memory в качестве замены Valgrind в Windows для нативного кода, но, похоже, он не любит .Net. Есть ли у кого-нибудь рекомендации по использованию аналогичного инструмента? Мы попробовали Deleaker и получили довольно странные результаты, например, утверждение, что объекты, выделенные стеком, утекают.

В частности, допустим, что стек выглядит так: foo () [native] bar () [managed] foobar () [native] ...

а foo () вызывает исключение C ++. Вызов foobar () к foo находится в блоке try с соответствующим блоком catch () для типа, сгенерированного foo (). foobar () был скомпилирован с помощью / Ehsc.

В каком из следующих случаев foobar () перехватывает исключение, когда все промежуточные объекты стека C ++ уничтожаются должным образом, если это происходит?

  • bar () не имеет команды try / catch
  • содержимое bar () заключено в мои макросы _5 _ / _ 6_

person Bwmat    schedule 18.03.2015    source источник


Ответы (1)


/EHa не проблема. Проблема заключается в использовании catch (...).

/EHa - это единственный способ как иметь исключения ОС (исключения .NET включены в эту категорию), так и правильно разворачивать фреймы стека C ++, а исключения C ++ должным образом разворачивать фреймы стека .NET.

person Ben Voigt    schedule 25.03.2015
comment
Большинство экземпляров catch(...) в библиотеке, о которой я упоминал, предназначены для предотвращения пересечения исключениями C ++ границ dll / языка, и для этой цели не так много замены AFAIK - person Bwmat; 27.03.2015