Прерывание выполнения C -функции и возвращение к C ++ -вызывающему

StackOverflow https://stackoverflow.com/questions/4136788

Вопрос

В настоящее время у меня есть проблема с реализацией следующего сценария, используя следующую конфигурацию: GCC 3.4, Linux.

Я написал инструмент (в C ++), который загружает общую библиотеку (написанную в C). У этой библиотеки есть ошибка, на которую я не могу повлиять на исправление. Проблема в том, что он считывает некоторый вход и записывает декодированный выход. Иногда, если ввод неверен, эта библиотека без каких -либо проверок начинает декодировать следующие области памяти. Это вызывает сегфо.

Первоначально моя идея заключалась в том, чтобы поместить ввод в страничную память (Linux MMAP-Sycall) и защитить (Mprotect) на последнюю страницу от доступа. Установив собственный обработчик SIGSEGV, мой C ++-приложение может добавить исключение (при составлении с помощью флага GCC -Fnon-Call-Call-Exceptions). Это исключение прертит чтение C LIB. Я знал, что эта LIB не выделяет никаких памяти (или других ресурсов), которая может быть потеряна во время выполнения стека. Весь сценарий работал нормально в моих модульных тестах, где все было одно приложение C ++. Но теперь, когда код C из LIB называется моим приложением только что заканчивается ... Нужно ли мне восстановить это C-SO с флагом -фнон-call-exceptions? Я не могу скомпилировать эту LIB, но только переосмыслить его, так как у меня есть доступ только к файлам OBJ.

Вот картина среды исполнения:

+------------C++ APP----------+
|                             |
| Install SIGSEGV handler     |
| code calling C SO functions |
|                             |
|   +----------C SO Functions------------+
|   |   execute producing SIGSEGV        |
|   +------------------------------------+
|                             |
| SIGSEGV Handler called      |
|   => throw Exception        |
|      to stop execution of   |
|      C function             |
+-----------------------------+

Другие предложения приветствуются.

Большое спасибо,

Ованес


PS Я вижу некоторые предложения и критики, но все они не оптин. Вот почему: у меня есть только один интерфейс, где я могу ссылаться на библиотеку. Библиотека используется для декодирования структур данных. Проблема в том, что если у меня есть массив с длиной -1, библиотека начинает декодировать массив длины 0xffffff (на 32 -битной системе). Ожидание, пока LIB не сбой в отдельном процессе, на мой взгляд, не вариант. Прежде всего, декодирование займет последовательный размер времени с одной стороны и производит много мусора с другой. Поскольку мой инструмент должен надежно показывать вывод декодированного вывода для пользователей. И они все еще должны иметь возможность понять следы.

Я не вижу смысла здесь работать вокруг SIGSEGV. Прежде всего, библиотека считывает данные и записывает их в направленность файла, которую я передавал раньше. Я могу настроить, как написать на эту ручку (буферизацию или нет). Кроме того, я точно знаю, что это не выделяет никаких данных или ресурсов. И, наконец, он пытается получить доступ к памяти, которую мое приложение защищало, чтобы избежать таких ошибок. С точки зрения пользователя, я не могу никому сказать: извините, бинарная трасса была лишь наполовину декодируемой, потому что некоторые данные были непоследовательными. Я знаю, что эти данные были неубедительными, и я точно знаю, как справиться с этим несоответствием. Так что я могу изящно выздороветь. Я думаю, что постараюсь использовать функции SigSetJmp/Siglongjmp Posix и надеюсь, что они будут лучше в качестве исключения. Действительно, SetJmp/Longjmp или SigsetJmp/Siglongjmp используются для реализации исключений.

Да, я отладил свое приложение и вижу, что стек вызовов действителен.

Это было полезно?

Решение 3

Хорошо, парни,

Я сделал это с sigsetJmp/siglongjmp. Работает как шарм. Я могу перепрыгнуть через функцию в стек функции вызывающего абонента и выполнить обработку ошибок там.

Спасибо за все предложения.

Наилучшие пожелания,

Ованес

Другие советы

К сожалению, у меня нет ответа на проблему, как указано - вы пробовали запустить свое приложение под отладчиком, чтобы увидеть, где именно она завершается?

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

Это может быть глупым вопросом, но нужно изучить основной файл? Или запустить приложение в отладчике?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top