2015-06-12 2 views
3

Я использую метод из сторонней библиотеки dll, и он выдает исключение «Исправление чтения с ошибкой 0x00000000». Я не могу копать, поэтому мне просто интересно, есть ли все равно, чтобы поймать его, чтобы не свернуть приложение. Я пробовал следующие 4 метода, но ни один из них не работает.Поймать исключение «Исправление ошибки доступа 0x00000000»

1,

try 
    { 
    sts = resFilter->initialize(m_JPEG2000File); // it throws that exception 
    } 
    catch (...){ 
     printf("Gotcha0..."); 
     int a = 34; 
    } 

2, 3 и 4

LONG WINAPI CrashHandler1(EXCEPTION_POINTERS * a/*ExceptionInfo*/) 
{ std::cout << "Gotcha1!" << std::endl; 
return 0; 
} 

void CrashHandler2() 
{ std::cout << "Gotcha2!" << std::endl;} 

void CrashHandler3() 
{ std::cout << "Gotcha3!" << std::endl;} 

// in Main() 
::SetUnhandledExceptionFilter(CrashHandler1); 
std::set_terminate (CrashHandler2); 
std::set_unexpected(CrashHandler3); 

Test(); // It would throw "Access violation reading location 0x00000000" exception 

Если я его отладки, исключение будет брошено. Если я запустил его во время выполнения, «Gotcha1!» будет отображаться в консоли, но приложение все равно будет разрушено. Есть ли способ, которым я могу съесть это исключение?

Спасибо заранее,

Бен

Edit:

@Adriano Репетти упоминается __try и __except может поймать это исключение.

Спасибо за все, что вы, ребята, хедз-ап за то, что не едите это исключение!

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

+3

попробовать с '' __try' и __except' (нарушение прав доступа не то _known_ на C++), но я хотел бы предложить, чтобы сделать ** не ** делать Это. Вы не знаете, что произошло, вы не знаете, что было выполнено, память (и данные!) Может быть повреждена даже в вашем коде. –

+0

Кстати, это может быть ваш код, который испортил их данные ... –

+1

Если вы используете MSVC++, то вы можете просто изменить параметр компиляции, использовать/EHa и catch (...). Не запускайте этот код еще раз, он съест ваш обед.Телефон навсегда станет лучшим способом справиться с этим, не забудьте получить небольшой репрограммный проект, когда вы вызываете программиста этой библиотеки. –

ответ

2

Не допускайте «нарушения» доступа; таким образом, отвратительное безумие.

Мне кажется, что вы пытаетесь разыменовать нулевой указатель. Возможно, просто не делайте этого!

if (!resFilter) { 
    // do something else; e.g. did you fail to initialise the library properly? 
    throw "Yikes!"; 
} 

// OK; pointer is not NULL at least: let's go! 
sts = resFilter->initialize(m_JPEG2000File); 

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

Поскольку вы находитесь в Windows, если все, что вы хотите сделать, это обнаружить проблему для ведения журнала, вы можете использовать Visual Studio's non-standard __try/__catch construct, но обязательно немедленно прекратите процесс после регистрации проблемы, потому что ваш процесс (в частности, состояние библиотеки) будет неустойчивым, и с ним ничего не выйдет, после чего будет иметь смысл!

__try { 
    sts = resFilter->initialize(m_JPEG2000File); 
} 
__except(
    GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION 
    ? EXCEPTION_EXECUTE_HANDLER 
    : EXCEPTION_CONTINUE_SEARCH) { 
    std::cerr << "OMG!\n"; 
    exit(-1); 
} 
+0

Я проверил все указатели, которые я могу достигнуть, и ни один из них не равен NULL. Кроме того, если я загружаю другой файл, все работает нормально. Поэтому я уверен, что исключение выбрано внутри третьей стороны. Я открывал все файлы в папке, и если у меня есть проблемы, я просто хочу пропустить их и перейти к следующему. Вот почему я хочу «съесть» исключение, чтобы не свернуть все приложение. – Ben

+1

@Ben: _ «если у меня есть проблемы, я просто хочу пропустить его и перейти к следующему». Это вряд ли будет хорошо. Если вы перескакиваете «NULL-указатель» на разыменование всех вещей, после этого вы должны считать процесс неустойчивым. Вы знаете, что по крайней мере одно критическое условие не выполняется. Ничто из того, что происходит после этого, можно опираться, поэтому довольно бессмысленно перейти к «следующей» проблеме, когда вы, вероятно, только что вызвали нагрузки самостоятельно. :) –

+0

Спасибо за головы! Я понимаю риск, но больше ничего не могу сделать. Он находится в сторонней DLL, и я не могу это исправить. Я думаю, поймать исключение, очистить все ресурсы и начать все заново, прежде чем переходить к следующему, что должно быть безопасным и достаточно хорошим для меня. Благодаря Адриано Репетти, __try работает! – Ben

0

__try и __except могут поймать это исключение. Благодаря @Adriano Repetti!

Вот хороший пост об этом: C++, __try and try/catch/finally

+0

'__try',' __except' и такой не C++. Невозможно поймать такие «исключения» на C++. На самом деле, из пинты C++ нет никакого исключения здесь. Код просто сломан и вызывает неопределенное поведение. Попытка «подавить» такие ошибки в «третьей стороне dll» с помощью '__try' и' __except' является совершенно бессмысленной задачей. – AnT

+0

Я не должен был упоминать об этом ... Бен, не делай этого так. Шутки в сторону! –

+0

Ребята, я поймаю это исключение, поэтому у меня есть шанс зарегистрировать ошибку, я все равно прекратил бы этот процесс. У меня есть внешний процесс C#, чтобы зацикливать данные, и каждый раз он запускает новый C++-процесс, поэтому это будет новый полный экземпляр. Так оно работает для меня. Извините, что вы не поняли, и спасибо за ваш вклад! – Ben

Смежные вопросы