Как определить причину исключения?
От: Linuxoid  
Дата: 16.02.05 07:13
Оценка:
Есть блок кода, в котором возникает исключение (довольно большой). Блок защищен оператором try, исключение перехватывается в catch(...) (других catch нет). Неизвестно что вызывает исключение и в каком конкретно месте оно возникает. Как получить более подробную информацию и локализовать проблемное место?
Re: Как определить причину исключения?
От: korzhik Россия  
Дата: 16.02.05 07:33
Оценка:
Здравствуйте, Linuxoid, Вы писали:

L>Есть блок кода, в котором возникает исключение (довольно большой). Блок защищен оператором try, исключение перехватывается в catch(...) (других catch нет). Неизвестно что вызывает исключение и в каком конкретно месте оно возникает. Как получить более подробную информацию и локализовать проблемное место?


ну во первых попробовать catch(std::exception& e), а во вторых скажите в какой системе разработки вы работаете
Re: Как определить причину исключения?
От: bkat  
Дата: 16.02.05 08:27
Оценка:
Здравствуйте, Linuxoid, Вы писали:

L>Есть блок кода, в котором возникает исключение (довольно большой). Блок защищен оператором try, исключение перехватывается в catch(...) (других catch нет). Неизвестно что вызывает исключение и в каком конкретно месте оно возникает. Как получить более подробную информацию и локализовать проблемное место?


Если это .NET студия,
то запусти приложение в дебагере.
Затем открой диалог "Debug/Exception..."
и поставь "Break into the debugger" для C++ Exceptions.
Впрочем для других исключений можешь это тоже выставить.

В VS 6.0 такая возможность тоже есть.

Или ты про что-то иное?
Re: Как определить причину исключения?
От: MaximE Великобритания  
Дата: 16.02.05 09:02
Оценка: 174 (26)
Linuxoid wrote:

> Есть блок кода, в котором возникает исключение (довольно большой). Блок защищен оператором try, исключение перехватывается в catch(...) (других catch нет). Неизвестно что вызывает исключение и в каком конкретно месте оно возникает. Как получить более подробную информацию и локализовать проблемное место?


Если сорс код доступен, то переносимый способ — это задефайнить throw:

#include <cstdio>
#include <stdexcept>

struct throw_site
{
     throw_site(char const* file, int line)
         : file_(file), line_(line)
     {}

     char const* file_;
     int line_;
};

template<class exception>
struct wrapper : exception, throw_site
{
     wrapper(exception const& e, throw_site const& s)
         : exception(e), throw_site(s)
     {}
};

template<class exception>
void operator+(throw_site const& s, exception const& e)
{
     throw wrapper<exception>(e, s);
}

#define throw throw_site(__FILE__, __LINE__) +

int main()
{
     try
     {
         throw std::runtime_error("oops");
     }
     catch(std::exception& e)
     {
         if(throw_site* s = dynamic_cast<throw_site*>(&e))
         {
             fprintf(stderr, "thrown at %s:%d\n", s->file_, s->line_);
         }
     }
}


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

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[2]: Как определить причину исключения?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 16.02.05 09:56
Оценка:
Круто!!!

Но, тогда, наверное, можно еще проще:

#include <iostream>

#define throw (std::cout << "throw at: " << __FILE__ << ":" << __LINE__ << std::endl),throw

const int    bad_thing = 1;

void
test()
    {
        std::cout << "test 1" << std::endl;

        throw bad_thing;

        std::cout << "test 2" << std::endl;

    }

int
main()
    {
        try
            {
                test();
            }
        catch( ... )
            {
                std::cout << "Some exception caught..." << std::endl;
            }

        return 0;
    }


В момент выдачи исключения на стандартный поток вывода будет выдано имя файла и номер строки. И позволяет обрабатывать исключения, где используются не классы, а например int-овые константы.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: Как определить причину исключения?
От: Linuxoid  
Дата: 16.02.05 10:08
Оценка:
Здравствуйте, korzhik, Вы писали:

K>ну во первых попробовать catch(std::exception& e), а во вторых скажите в какой системе разработки вы работаете


Что такое "система разработки"? Если имеется в виду среда разработки, то VC++ 6.0
Re[2]: Как определить причину исключения?
От: Linuxoid  
Дата: 16.02.05 10:09
Оценка:
Здравствуйте, bkat, Вы писали:

B>Здравствуйте, Linuxoid, Вы писали:


B>В VS 6.0 такая возможность тоже есть.


Этот метод подойдет для сервиса, работающего в real-time ?
Re[2]: Как определить причину исключения?
От: Linuxoid  
Дата: 16.02.05 10:17
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Если сорс код доступен, то переносимый способ — это задефайнить throw:


<skipped>

Может я чего-то не допонял, но каким образом мне это поможет? Я же не кидаю исключение руками, оно генерится программой неизвестно где и почему (известен только блок кода).
Re: Как определить причину исключения?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 16.02.05 10:33
Оценка:
Здравствуйте, Linuxoid, Вы писали:

L>Есть блок кода, в котором возникает исключение (довольно большой). Блок защищен оператором try, исключение перехватывается в catch(...) (других catch нет). Неизвестно что вызывает исключение и в каком конкретно месте оно возникает. Как получить более подробную информацию и локализовать проблемное место?


Из ваших постов не понятно, располагаете ли вы таки исходными текстами вашего сервиса. Если раполагаете, то хороший способ подсказал MaximE
Автор: MaximE
Дата: 16.02.05
: переопределив throw через define вы можете получить в catch информацию о месте, откуда исключение было порождено. А далее наводняете это место отладочными печатями и т.д. и т.п.

Еще один способ, если исходники доступны: отключать по очереди участки большого кода (коментируя их или через #if 0/#endif). Если у вас есть test case в котором исключение постоянно появляется, то повторяя этот test case на разных фрагментах вы найдете ситуацию, когда исключение не возникает. Далее таким же образом можно обработать найденый фрагмент и т.д.

Еще один способ, если исходники доступны: вставлять отладочную печать перед каждым throw. А затем смотреть, где чего выскочило. Если отладочные печати не удовлетворяют по соображениям скорости (был упомянут real-time), то можно поступить так: завести буфер, в который записывать какие-то метки (строки или целочисленные константы). Перед каждым throw вставить добавление в этот буфер уникальной метки (например, переопеделив throw через define). А в catch посмотреть, что за метка оказалась в буфере.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: Как определить причину исключения?
От: k. Россия  
Дата: 16.02.05 11:39
Оценка:
Здравствуйте, MaximE, Вы писали:

VC7 выдает следующее:

d:\repository\SyncServer\Client-Side\qqq\qqq.cpp(20) : error C2512: 'std::runtime_error' : no appropriate default constructor available

в то же время, если поправить вот так, то работает:

template<class T>
struct wrapper : T, throw_site
{
     wrapper(T const& e, throw_site const& s)
         : T(e), throw_site(s)
     {}
};


не подскажите в чем дело и как это со стандартом соотносится?
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[3]: Как определить причину исключения?
От: MaximE Великобритания  
Дата: 16.02.05 11:49
Оценка:
Linuxoid wrote:

> Здравствуйте, MaximE, Вы писали:

>
> ME>Если сорс код доступен, то переносимый способ — это задефайнить throw:
>
> <skipped>
>
> Может я чего-то не допонял, но каким образом мне это поможет? Я же не кидаю исключение руками, оно генерится программой неизвестно где и почему (известен только блок кода).

Исходники тебе доступны?

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[3]: Как определить причину исключения?
От: MaximE Великобритания  
Дата: 16.02.05 11:52
Оценка:
k. wrote:

> Здравствуйте, MaximE, Вы писали:

>
> VC7 выдает следующее:
>
> d:\repository\SyncServer\Client-Side\qqq\qqq.cpp(20) : error C2512: 'std::runtime_error' : no appropriate default constructor available
>
> в то же время, если поправить вот так, то работает:
>
>
> template<class T>
> struct wrapper : T, throw_site
> {
>      wrapper(T const& e, throw_site const& s)
>          : T(e), throw_site(s)
>      {}
> };
>

>
> не подскажите в чем дело и как это со стандартом соотносится?

Случаем перед этим не написано где-то using namespace std; ?

Если нет, то это, возможно, глюк студии.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[4]: Как определить причину исключения?
От: k. Россия  
Дата: 16.02.05 11:54
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Случаем перед этим не написано где-то using namespace std; ?


нет, подобное я само собой проверил.

ME>Если нет, то это, возможно, глюк студии.


спасибо.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[3]: Как определить причину исключения?
От: Awaken Украина  
Дата: 16.02.05 11:58
Оценка:
L>Может я чего-то не допонял, но каким образом мне это поможет? Я же не кидаю исключение руками, оно генерится программой неизвестно где >и почему (известен только блок кода).

определить тип исключения программно в рантайме можно только если есть предположения о его типе
тогда ставим несколько catch-ей для каждого предполагаемого базового класса исключения

или речь не об этом?
Re[4]: Как определить причину исключения?
От: Linuxoid  
Дата: 16.02.05 12:00
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Linuxoid wrote:


>> Здравствуйте, MaximE, Вы писали:

>>
>> ME>Если сорс код доступен, то переносимый способ — это задефайнить throw:
>>
>> <skipped>
>>
>> Может я чего-то не допонял, но каким образом мне это поможет? Я же не кидаю исключение руками, оно генерится программой неизвестно где и почему (известен только блок кода).

ME>Исходники тебе доступны?


Да, доступны. Кстати, это только у меня глюк — не могу добавить в избранное твое сообщение?
Re[5]: Как определить причину исключения?
От: MaximE Великобритания  
Дата: 16.02.05 12:10
Оценка:
Linuxoid wrote:

[]

>>> Может я чего-то не допонял, но каким образом мне это поможет? Я же не кидаю исключение руками, оно генерится программой неизвестно где и почему (известен только блок кода).

>
> ME>Исходники тебе доступны?
>
> Да, доступны.

Ты можешь подключить во все исходники хедер с тем кодом и перед catch(...) добавить catch(throw_site&) ?

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[4]: Как определить причину исключения?
От: MaximE Великобритания  
Дата: 16.02.05 12:11
Оценка:
Awaken wrote:

>

> L>Может я чего-то не допонял, но каким образом мне это поможет? Я же не кидаю исключение руками, оно генерится программой неизвестно где >и почему (известен только блок кода).
>
> определить тип исключения программно в рантайме можно только если есть предположения о его типе
> тогда ставим несколько catch-ей для каждого предполагаемого базового класса исключения

Достаточно catch(throw_site&).

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[5]: Как определить причину исключения?
От: Кодт Россия  
Дата: 16.02.05 12:28
Оценка: 12 (2)
Здравствуйте, MaximE, Вы писали:

ME>Достаточно catch(throw_site&).


А вот такой вопрос:
class the_wrapper : public the_exception, public throw_site
{
  ...
};

int main()
{
  try
  {
    throw the_wrapper;
  }
  catch(the_exception& e)
  {
  }
  catch(throw_site& s)
  {
  }
}

В какой из блоков мы прилетим, и зависит ли это от порядка баз и от порядка блоков?
Перекуём баги на фичи!
Re[6]: Как определить причину исключения?
От: MaximE Великобритания  
Дата: 16.02.05 12:35
Оценка:
Кодт wrote:

> Здравствуйте, MaximE, Вы писали:

>
> ME>Достаточно catch(throw_site&).
>
> А вот такой вопрос:
>
> class the_wrapper : public the_exception, public throw_site
> {
>   ...
> };
>
> int main()
> {
>   try
>   {
>     throw the_wrapper;
>   }
>   catch(the_exception& e)
>   {
>   }
>   catch(throw_site& s)
>   {
>   }
> }
>

> В какой из блоков мы прилетим, и зависит ли это от порядка баз и от порядка блоков?

Отличный вопрос. Чешу репу...

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[6]: Как определить причину исключения?
От: Костя Ещенко Россия  
Дата: 16.02.05 13:45
Оценка: 86 (7) +2
Кодт wrote:

> А вот такой вопрос:

>
> class the_wrapper : public the_exception, public throw_site
> {
>   ...
> };
> 
> int main()
> {
>   try
>   {
>     throw the_wrapper;
>   }
>   catch(the_exception& e)
>   {
>   }
>   catch(throw_site& s)
>   {
>   }
> }
>

> В какой из блоков мы прилетим, и зависит ли это от порядка баз и от порядка блоков?

Сначала показалось, что это один из темных углов С++, а ответ-то простой — прилетим в в the_exception. Там ведь ищется не наиболее подходящий обработчик, а первый подходящий.
Posted via RSDN NNTP Server 1.9
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.