Прерывание выполнения C -функции и возвращение к C ++ -вызывающему
-
30-09-2019 - |
Вопрос
В настоящее время у меня есть проблема с реализацией следующего сценария, используя следующую конфигурацию: 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. Работает как шарм. Я могу перепрыгнуть через функцию в стек функции вызывающего абонента и выполнить обработку ошибок там.
Спасибо за все предложения.
Наилучшие пожелания,
Ованес
Другие советы
К сожалению, у меня нет ответа на проблему, как указано - вы пробовали запустить свое приложение под отладчиком, чтобы увидеть, где именно она завершается?
Тем не менее, альтернативный подход, который пришел мне на голову, заключается в том, чтобы использовать использование неисправной библиотеки в отдельную программу, запустить ее из вашего приложения и передавать данные через трубу.
Это может быть глупым вопросом, но нужно изучить основной файл? Или запустить приложение в отладчике?