Я разрабатываю программу на C ++ (Win32, MS Visual Studio 2008), которая создает виртуальную машину Java через JNI, как описано Вот. Долгое время он работал нормально, как с Java 6, так и с Java 7.
Сегодня я установил новую версию JRE; что-то пошло не так в установщике, и JRE испортился. Я заметил, что моя программа на C ++ не запускается и не выдает никаких предупреждающих сообщений. Отладка программы показала, что она успешно работает до JNI_CreateJavaVM
вызов; но звонит JNI_CreateJavaVM
вызывает мгновенное завершение программы. Нет возвращаемых значений, нет сообщений об ошибках, ничего.
Да, я знаю, что мне просто нужно переустановить JRE. Но тем не менее я хотел бы, чтобы моя программа на C ++ была готова к такой ситуации. Если не удается создать виртуальную машину Java, должно появиться сообщение «Пожалуйста, переустановите JRE». Но у меня нет возможности показать это сообщение, потому что вся программа заканчивается.
Есть ли способ обнаружить ошибки такого типа в JRE или, в более общем случае, в сторонней библиотеке? Я пытался использовать C ++ try/catch
конструкции, я попытался с помощью сигнал функция — ничего не помогает; программа исчезает без вызова каких-либо обработчиков catch или signal.
Есть ли способ обнаружить такой сбой JRE? Или: есть ли способ надежно обнаружить сбой или завершение работы в сторонней библиотеке?
Если вы используете Linux / Unix: я обычно начинаю с этого:
struct sigaction sa;
sa.sa_handler = bt_sighandler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
sigaction(SIGSEGV, &sa, NULL);
sigaction(SIGUSR1, &sa, NULL);
Если вы используете Microsoft C ++ в Windows: _пытаться/_except обычно сделает свое дело. Это расширение MSVC (вы можете сказать это из двойного подчеркивания), которое расширяет стандартный try / catch.
Try / catch перехватывает исключения C ++, _пытаться/_except перехватит все остальные необработанные исключения (COM, Win32, …). Например, он обнаружит проблемы с обращением к памяти, связанные с нулевой разыменовкой, которые, вероятно, являются причиной вашего сбоя. Читать Вот
В противном случае, вдовы, попробуйте SetUnhandledExceptionFilter
РЕДАКТИРОВАТЬ: так как подход, использующий SEH, кажется, терпит неудачу, вы можете подняться на один уровень вверх и использовать Vectored Exception Handling. В соответствии с этот пост в блоге на MSDN, VEH регистрируется для каждого процесса и проверяется перед SEH.
Если все не получается, не отчаивайтесь 🙂 вы все равно можете превратить ваше приложение в пару отладчик / debugee. Это даст вам полный контроль над событиями, жизнью и смертью процесса отладки. Как правило, это не стоит проблем, но это дополнительное решение, которое мне приходилось использовать в прошлом. Это также не так сложно, как может показаться; если что-то не получится, дайте мне знать, и я выкопаю старый код.
Других решений пока нет …