Что делать?
Начинаем думать. Везде ставить try-catch… вычислительный блок будет здорово тормозить. Значит, надо сделать отладочную версию. Значит, вводим
#define __TRY__DEBUG__
Ок. Хорошо. В подозрительных местах ставим
#ifdef __TRY__DEBUG__ try{ #endif //тело функции #ifdef __TRY__DEBUG__ catch(...){ fprintf(stderr,"Возникло исключение в функции %s. Сохраняю параметры\n",NameFunction); } #endif
Упс. функция вывода разбросана по разным местам. Не хорошо.
Рождается класс исключений
class DebugException:exception{}
Упс номер два. А что в нем хранить-то?
Так, нам нужно что? вывод в файл. Желательно всего, с чем работает функция в момент краша.
Т.е. нам нужны текстовые данные.
Ага.
struct Obj{ //! имя char* name; //! состояние char* State; //! объекты Obj** MyObj; //! количество объектов int namberOfObjects; //! конструктор Obj(char*nm,char* stt):name(nm),State(stt),MyObj(NULL),namberOfObjects(0){ }; };
Так, едем дальше. В чем хранить, придумали, думаем как получить все это дело из того объекта, с которым работаем.
Рождается метод Obj*GetState(); который прописывается в каждый класс.
Едем дальше.
Теперь внимание вопрос: а где выводить-то в файл?
Можно в том же месте, где и краш. Т.е. в конструкторе исключения… Ага, нехорошо.
В классе исключений появляется метод printf, выводящий весь объект в файл.
main начинает приобретать вид
#ifdef __TRY__DEBUG__ try{ #endif //тело функции #ifdef __TRY__DEBUG__ catch(DebugException ups){ ups.print(); } #endif
Так, а еще неплохо было бы собрать информацию о системе в целом. Так рождается конструктор вида
//! конструктор с именем функции, необходимой информацией и состоянием функции DebugException(char*NmFunc,char GetStates,Obj* FuncState);
В итоге — код увеличивается раза в два, но в случае краша можно узнать кто причиной, кто виной.
Плюсы
+гораздо меньше итоговой информации, чем при логировании. Особенно, если тестовая версия два дня отработала нормально, а на третий вышел краш.
+Есть возможность собрать абсолютно полную информацию о системе на момент краша.
+Не влияет на релизную версию.
Минусы
— Совершенно другая организация кода функций. Так как в блоке catch неизвестны переменные, объявленные в блоке try, то их приходится объявлять в начале функций, забыв про элегантность кода.
— Много отладочного кода
— Возможно, окажется упущена причина, приведшая к такому состоянию системы
ссылка на оригинал статьи http://habrahabr.ru/post/163393/
Добавить комментарий