Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Получить стек вызовов в момент исключения 
V
    Опции темы
semibug
Дата 24.9.2010, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 323
Регистрация: 27.3.2009

Репутация: нет
Всего: нет




При возникновении исключения хотелось бы записать в лог не только данные о месте (получаю макросами __FILE__, __LINE__ ), но и стек вызовов.
Сейчас добавляю в начало каждой функции макрос, который записывает в самодельный стек вызовов имя функции (получаю через __FUNCTION__). В нем же (в этом макросе) создается объект, в деструкторе которого находится выборка последнего значения из стека вызовов (чтобы не делать это вручную).
При возникновении исключения (свой тип) теперь могу сохранить в лог полностью стек вызовов.
Все вроде ничего, да только писать в начало каждой функции макрос как-то не кошерно.
Есть ли другие способы получить информацию о стеке вызовов?


PM   Вверх
boostcoder
Дата 24.9.2010, 17:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



кстати сам часто нуждаюсь в подобном. интересно, есть ли какие способы?

semibug, покажи свой препроцессорный велосипед.
PM WWW   Вверх
semibug
Дата 24.9.2010, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 323
Регистрация: 27.3.2009

Репутация: нет
Всего: нет



Сильно не бить:
Код

#pragma once

#define EXCEPTION( d )        CException( d, __FILE__, __LINE__ )
#define CALL_STACK_PUSH()                            \
        CExceptionAutoPoper ExceptionAutoPoper;        \
        CException::PushCallStack( __FUNCTION__ );    \


class CException
{
public:

    CException( std::string description, std::string file, int line )
    {
        std::stringstream desc;
        desc << SVN_COMMITED_REV_NUM << ":" << file << ":" << line << " " << description;

        what_string = desc.str();



        std::ofstream log_file( "error.log" );

        log_file << std::endl << std::endl;
        log_file << "EXCEPTION" << std::endl;
        log_file << what_string << std::endl;
        log_file << "CALL STACK" << std::endl;
        for ( size_t i = 0; i < call_stack.size(); i++ )
            log_file << "    " << call_stack[ i ] << std::endl;
        log_file << std::endl;
    }

    const char *what()
    {
        return what_string.c_str();
    }

    static void PushCallStack( std::string text )
    {
        call_stack.push_back( text );
    }
    static void PopCallStack()
    {
        call_stack.pop_back();
    }

private:

    std::string what_string;
    static std::vector<std::string> call_stack;
};

class CExceptionAutoPoper
{
public:
    ~CExceptionAutoPoper()
    {
        CException::PopCallStack();
    }
};


Добавлено через 12 минут и 53 секунды
Ещё круче было бы если и параметры вызовов тоже как-то залогировать. И вообще полный замороженный образ перед возникновением исключения (с пошаговой отмоткой назад/вперед). Пахнет научно-популярной фантастикой.

PM   Вверх
xvr
Дата 24.9.2010, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Windows - MiniDumpWriteDump, Linux - abort() (и не забыть установить отличный от 0 лимит для core файла)
Потом полученные core dump'ы загружаешь в дебагер и вуаля!

Цитата(semibug @  24.9.2010,  17:11 Найти цитируемый пост)
Ещё круче было бы если и параметры вызовов тоже как-то залогировать. И вообще полный замороженный образ перед возникновением исключения (с пошаговой отмоткой назад/вперед). Пахнет научно-популярной фантастикой.
Нет, реальность  smile 


PM MAIL   Вверх
jonie
Дата 24.9.2010, 19:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118





--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
semibug
Дата 24.9.2010, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 323
Регистрация: 27.3.2009

Репутация: нет
Всего: нет



jonie, спасибо за ссылку, очень юзабельная вещь.

PM   Вверх
djamshud
Дата 25.9.2010, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 8
Всего: 39



Есть специальный ГНУ экстеншн: man backtrace.

Это наверное скорее бусткодеру на заметку:).


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
boostcoder
Дата 25.9.2010, 20:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(djamshud @  25.9.2010,  19:19 Найти цитируемый пост)
Есть специальный ГНУ экстеншн: man backtrace.

ух ты! никогда про такое не слышал.

Добавлено через 4 минуты и 43 секунды
симпотно выглядит:
Код

backtrace() returned 8 addresses
./prog(myfunc3+0x5c) [0x80487f0]
./prog [0x8048871]
./prog(myfunc+0x21) [0x8048894]
./prog(myfunc+0x1a) [0x804888d]
./prog(myfunc+0x1a) [0x804888d]
./prog(main+0x65) [0x80488fb]
/lib/libc.so.6(__libc_start_main+0xdc) [0xb7e38f9c]
./prog [0x8048711]

взято из мана.
PM WWW   Вверх
Леопольд
Дата 28.9.2010, 10:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(boostcoder @  25.9.2010,  20:02 Найти цитируемый пост)
ух ты! никогда про такое не слышал.
Это вроде чисто С-ишная фича, нет? Как будет работать с кодом на С++? У меня, например, все имена функций просто "опустил" и получился такой, неинформативный, вывод:
Код
/home/andrey/proj/console/bin/Debug/console() [0x80496b1]
/home/andrey/proj/console/bin/Debug/console() [0x80496b1]
/home/andrey/proj/console/bin/Debug/console() [0x80496b1]
/home/andrey/proj/console/bin/Debug/console() [0x80496b1]
/home/andrey/proj/console/bin/Debug/console() [0x80496b1]
/home/andrey/proj/console/bin/Debug/console() [0x80496b1]
/home/andrey/proj/console/bin/Debug/console() [0x80496b1]
/home/andrey/proj/console/bin/Debug/console() [0x80496b1]
/home/andrey/proj/console/bin/Debug/console() [0x80496b1]
/home/andrey/proj/console/bin/Debug/console() [0x80496b1]
/home/andrey/proj/console/bin/Debug/console() [0x80496b1]
/home/andrey/proj/console/bin/Debug/console() [0x80496b1]
/home/andrey/proj/console/bin/Debug/console() [0x80496b1]
/home/andrey/proj/console/bin/Debug/console() [0x80496b1]
/home/andrey/proj/console/bin/Debug/console() [0x80496b1]
/home/andrey/proj/console/bin/Debug/console() [0x80496b1]
/home/andrey/proj/console/bin/Debug/console() [0x80494fe]
/home/andrey/proj/console/bin/Debug/console() [0x8048c7d]




--------------------
вопросов больше чем ответов
PM MAIL   Вверх
djamshud
Дата 28.9.2010, 10:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 8
Всего: 39



Леопольд, внимательно читаем ман, там написано, как компилировать. Потом читаем man gcc на предмет -rdynamic и -export-dynamic и пытаемся понять, как это работает.

Добавлено через 1 минуту и 47 секунд
Код

backtrace() returned 10 addresses
./test(_Z7myfunc3v+0x1f) [0x8048993]
./test [0x8048a24]
./test(_Z6myfunci+0x21) [0x8048a47]
./test(_Z6myfunci+0x1a) [0x8048a40]
./test(_Z6myfunci+0x1a) [0x8048a40]
./test(_ZN4shit4callEv+0x13) [0x8048ad7]
./test(_ZN4shitC1Ev+0x11) [0x8048ac1]
./test(main+0x5a) [0x8048aa3]
/lib/libc.so.6(__libc_start_main+0xe5) [0xb74e1a65]
./test [0x80488c1


Вызывается конструктор shit, из него метод shit::call, а дальше также, как в приме из мана.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1982 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.