Есть ли с ++ эквивалент Java
try {
...
}
catch (Throwable t) {
...
}
Я пытаюсь отладить код Java / jni, который вызывает собственные функции Windows, и виртуальная машина продолжает падать. Нативный код прекрасно работает в модульном тестировании и, похоже, вылетает при вызове через jni. Общий механизм перехвата исключений оказался бы чрезвычайно полезным.
Ответы:
поймает все исключения C ++, но это следует считать плохим дизайном. Вы можете использовать новый механизм current_exception в c ++ 11, но если у вас нет возможности использовать c ++ 11 (устаревшие системы кода, требующие перезаписи), то у вас нет указателя именованного исключения, который можно использовать для получения сообщения или имени , Возможно, вы захотите добавить отдельные предложения catch для различных исключений, которые вы можете поймать, и поймать только все внизу, чтобы записать неожиданное исключение. Например:
источник
Кто-то должен добавить, что никто не может поймать «сбои» в коде C ++. Те не бросают исключения, но делают все, что им нравится. Когда вы видите сбой программы из-за разыменования нулевого указателя, он выполняет неопределенное поведение. Существует нет
std::null_pointer_exception
. Попытка поймать исключения не поможет там.На всякий случай кто-то читает эту ветку и думает, что может выяснить причину сбоя программы. Вместо этого следует использовать отладчик типа gdb.
источник
try { .. } catch(...) { ... }
для отлова сигнал / сигмацию, я бы не назвал это «отлавливанием» :) Если в обработчике сигнала программисту относительно сложно узнать, где в коде произошел сбой (я говорю о программном обнаружении этого), по сравнению с try / catch.Вот как вы можете перепроектировать тип исключения изнутри,
catch(...)
если вам нужно (может быть полезно при поиске неизвестного из сторонней библиотеки) с помощью GCC:и если вы можете позволить себе использовать Boost, вы можете сделать секцию catch еще проще (снаружи) и потенциально кроссплатформенной
источник
Обратите внимание, что
...
внутриcatch
это настоящий эллипсис, т.е. три точкиОднако, поскольку исключения C ++ не обязательно являются подклассами базового
Exception
класса, нет никакого способа увидеть переменную исключения, которая выдается при использовании этой конструкции.источник
catch
спецификатор от существующего заполнителя кода в комментарии (// ...
), который явно не является синтаксисом C ++.невозможно (в C ++) перехватить все исключения в переносимой форме. Это потому, что некоторые исключения не являются исключениями в контексте C ++. Это включает в себя такие вещи, как деление на ноль ошибок и другие. Можно взломать и, таким образом, получить возможность генерировать исключения, когда такие ошибки случаются, но это нелегко сделать и, конечно же, нелегко получить правильную переносимость.
Если вы хотите перехватить все исключения STL, вы можете сделать
Который позволит вам использовать
e.what()
, который будет возвращатьconst char*
, который может рассказать вам больше о самом исключении. Это та конструкция, которая больше всего похожа на конструкцию Java.Это не поможет вам, если кто-то настолько глуп, чтобы выдать исключение, которое не наследуется
std::exception
.источник
Короче, пользуйся
catch(...)
. Тем не менее, обратите внимание, чтоcatch(...)
предполагается использовать вместе с вthrow;
основном:Это правильный способ использования
catch(...)
.источник
Foo
деструктор? Я думал, что в этом весь смысл RAII. Однако, если вам нужен указатель,Foo
а не просто создание вFoo
стеке, вам нужно будет обернуть указатель во что-то еще, что объявлено в стеке.это можно сделать, написав:
Но здесь есть очень незначительный риск: вы не можете найти точный тип ошибки, которая была выдана в
try
блоке, поэтому используйте этот тип,catch
когда вы уверены, что независимо от того, какой тип исключения, программа должна сохраняться в порядке, определенном вcatch
блоке.источник
Ты можешь использовать
но это очень опасно. В своей книге « Отладка Windows» Джон Роббинс рассказывает историю о действительно неприятной ошибке, которая была замаскирована командой catch (...). Вам гораздо лучше ловить конкретные исключения. Поймайте все, что, по вашему мнению, ваш блок try может разумно сгенерировать, но позвольте коду генерировать исключение выше, если происходит что-то действительно неожиданное.
источник
Позвольте мне упомянуть это здесь: Java
не может поймать все исключения! У меня на самом деле были подобные вещи раньше, и это провоцирует безумство; Исключение происходит от Throwable. В буквальном смысле, чтобы поймать все, вы не хотите ловить исключения; Вы хотите поймать Throwable.
Я знаю, это звучит странно, но когда вы потратили несколько дней, пытаясь выяснить, откуда появилось «необработанное исключение» в коде, который был окружен блоком try ... catch (Exception e) », он придерживается ты.
источник
catch(Exception)
может не перехватить все исключения в Java, вы путаете его с C # ... Java =catch(Thowable)
, C # =catch(Exception)
. Не путай их.CoderMalfunctionError
(который на самом деле является настоящимError
подклассом Java ... хотя это не значит, как это звучит.)Хорошо, если вы хотите перехватить все исключения, например, для создания минидампа ...
Кто-то сделал работу на Windows.
См. Http://www.codeproject.com/Articles/207464/Exception-Handling-in-Visual-Cplusplus. В этой статье он объясняет, как он узнал, как перехватывать все виды исключений, и предоставляет код, который работает.
Вот список, который вы можете поймать:
И использование: CCrashHandler ch; ch.SetProcessExceptionHandlers (); // сделать это для одного потока ch.SetThreadExceptionHandlers (); // за каждый тред
По умолчанию это создает мини-дамп в текущем каталоге (crashdump.dmp)
источник
Сомнительно. Вы уже знаете, что ваш код не работает, потому что он падает. Еда исключений может маскировать это, но это, вероятно, приведет к еще более неприятным, более тонким ошибкам.
То, что вы действительно хотите, это отладчик ...
источник
Можете ли вы запустить Java-приложение, использующее JNI, из окна консоли (запустить его из командной строки java), чтобы увидеть, есть ли какой-либо отчет о том, что могло быть обнаружено до сбоя JVM. При запуске непосредственно как оконное приложение Java вы можете пропустить сообщения, которые появятся, если вы запустите их из окна консоли.
Во-вторых, можете ли вы заглушить реализацию JNI DLL, чтобы показать, что методы в вашей DLL вводятся из JNI, вы возвращаетесь правильно и т. Д.?
На случай, если проблема заключается в неправильном использовании одного из методов интерфейса JNI из кода C ++, вы убедились, что некоторые простые примеры JNI компилируются и работают с вашей установкой? Я имею в виду, в частности, использование методов интерфейса JNI для преобразования параметров в собственные форматы C ++ и преобразования результатов функций в типы Java. Полезно заглушить их, чтобы убедиться, что преобразования данных работают, и вы не собираетесь потерпеть неудачу при COM-подобных вызовах в интерфейс JNI.
Есть и другие вещи, которые нужно проверить, но трудно что-либо предложить, не зная больше о том, каковы ваши нативные методы Java и что пытается сделать их реализация JNI. Не ясно, что перехват исключения из уровня кода C ++ связан с вашей проблемой. (Вы можете использовать интерфейс JNI, чтобы перебросить исключение как Java, но из того, что вы предоставляете, не ясно, что это поможет.)
источник
Для реальной проблемы невозможности правильно отладить программу, которая использует JNI (или ошибка не появляется при запуске его под отладчиком):
В этом случае часто помогает добавить обертки Java вокруг ваших вызовов JNI (т. Е. Все нативные методы являются частными, а ваши открытые методы в классе вызывают их), которые выполняют некоторую базовую проверку работоспособности (проверяют, что все «объекты» освобождены и «объекты»). не используются после освобождения) или синхронизации (просто синхронизируйте все методы из одной DLL в один экземпляр объекта). Пусть методы java-оболочки регистрируют ошибку и генерируют исключение.
Это часто помогает найти реальную ошибку (которая на удивление в основном в коде Java, который не подчиняется семантике вызываемых функций, вызывающих некоторые неприятные двойные освобождения или аналогичные) легче, чем попытка отладки массивно параллельной программы Java в родной отладчик ...
Если вы знаете причину, сохраните код в методах-обертках, чтобы избежать его. Лучше, чтобы ваши методы-оболочки генерировали исключения, чем ваш код JNI, приводящий к сбою виртуальной машины ...
источник
Ну, это действительно зависит от среды компилятора. GCC не ловит эти. Visual Studio и последний Borland, который я использовал, сделали.
Таким образом, вывод о сбоях заключается в том, что это зависит от качества среды разработки.
Спецификация C ++ говорит, что catch (...) должен перехватывать любые исключения, но это не во всех случаях.
По крайней мере, из того, что я пытался.
источник
Знать
ловит только языковые исключения, другие низкоуровневые исключения / ошибки, такие как
Access Violation
и неSegmentation Fault
будут пойманы.источник