![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| NYX |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 165 Регистрация: 9.1.2007 Где: Россия, Москва Репутация: нет Всего: нет |
Всем привет. Не так давно возникла потребность (личная, не коммерческая) в создании простой, но эффективной системы отчета о событиях. Сначала задался писать простенькие процедуры и функции, затем все переросло в класс, потом в два класса, которые в целом позволяют делать отчеты с описанием и без описания + разные навороты с версиями и прочее прочее. В общем в итоге все обросло таким мусором, что хочется плюнуть на это все и... растереть! В общем, после недолгих мозговых потугов до меня дошла определенная идея. Может идея и бредовая (так полагаю в плане производительности она не айс), но наверно это то, что вполне может меня удовлетворить
Вот некоторая концепция: * Система отчета является базовым классом, который методом простеньких и не очень хаков, позволит произвести протоколирование маршрутов вызовов * Каждая вызываемая функция дает знать о том что ее вызвали * В итоге, не сильно сложный класс, занимающийся отловом известных ошибок, в случае возникновения ошибки класс как то хитро выдергивает МАРШРУТ вызовов и соответственно вставляет соответствующую информацию в лог ошибок. Дабы не раскрывать секреты исходных кодов, можно например записывать маршрут вызовов на подобии такого: 00-12-46-03-11 ERROR #1039 "Произошло что то ужасное!" Вот. За коим фигом я обращаюсь на форум? Хотелось бы услышать: 1) Какие средства мне могут ваще поспособствовать написанию подобного бреда 2) Не в коем случае не интересуюсь иными методами, и посты типа - оставь свой велосипед и goto КАКАЯ_ТО_ЛИБА 3) Как можно реализовать базовый класс, позволяющий произвести отчет о вызовах? Ну грубо говоря - обертка, дает определенный номер (для начала int 4 байта) каждой функции, и при вызовах\завершению функции, пихать\извлекать номер вызываемой функции (как в стек прям!). Вот. В общем, добрые человеки, у кого возникнет свободное время, было бы интересно пообсуждать, потрепаться об ентом (!) может даже можно поразмышлять о бинарных деревьях Это сообщение отредактировал(а) NYX - 13.6.2012, 19:22 --------------------
'long long long' is too long for GC |
|||
|
||||
| NYX |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 165 Регистрация: 9.1.2007 Где: Россия, Москва Репутация: нет Всего: нет |
Наверно нужна посредственность вызовов функций. Что то вроди оболочки, которая своевременно делала бы отпечаток в анналах при вызове и завершении. Чисто вот гепотетически... да-не, даже практически, на асме это реализуемо. Вот как бы блин вывернуть сустав компилятору (и самое главное какой из них) чтоб такое заделать...? Не у кого мыслишек нет?
--------------------
'long long long' is too long for GC |
|||
|
||||
| alexvs11 |
|
|||
|
hell is here ![]() ![]() Профиль Группа: Участник Сообщений: 518 Регистрация: 21.8.2010 Репутация: 6 Всего: 10 |
NYX, если речь идет про gcc, то там есть backtrace
http://www.gnu.org/software/libc/manual/ht...Backtraces.html http://www.linuxjournal.com/article/6391 используется во многих линуксовых программах для диагностики все что собственно делает - распечатывает стек вызовов я видел и более экзотическое решение - с аттачем gdb и выводом его бектрейса Это сообщение отредактировал(а) alexvs11 - 13.6.2012, 21:51 |
|||
|
||||
| NYX |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 165 Регистрация: 9.1.2007 Где: Россия, Москва Репутация: нет Всего: нет |
Ща зафигурим.... интересно...
Я никогда не философствовал для себя на тему отчета об ошибках, но счас реально внапряг стало выискивать ошибки через дебаггер, да и система отчета типо ->
<- дает посредственное описание. Один фиг все через дебаггер прогонять приходится. Если пользователь вышлет лог с такими ошибками, это ооочень долго разбираться Это сообщение отредактировал(а) NYX - 13.6.2012, 22:04 --------------------
'long long long' is too long for GC |
|||
|
||||
| Randajad |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 15.3.2012 Репутация: 8 Всего: 8 |
backtrace под виндами не работает, что увы.
Добавлено через 1 минуту и 5 секунд Под виндами можно заюзать StackWalk. Только название функций через него не получить, ибо гцц не умеет пдбшки делать. Но основная задача - адреса функций - вполне. |
|||
|
||||
| NYX |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 165 Регистрация: 9.1.2007 Где: Россия, Москва Репутация: нет Всего: нет |
Под виндузятину бэктрейс походу отсутствует
по крайней мере не инклудится <execinfo.h> как бы я его не взывал! По причине отсутствия.... эх! Прощайте мечты о светлом будущем! Это сообщение отредактировал(а) NYX - 13.6.2012, 22:22 --------------------
'long long long' is too long for GC |
|||
|
||||
| Randajad |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 15.3.2012 Репутация: 8 Всего: 8 |
Афтар не успел.
Я выше как раз написал об этом. Это сообщение отредактировал(а) Randajad - 13.6.2012, 22:18 |
|||
|
||||
| NYX |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 165 Регистрация: 9.1.2007 Где: Россия, Москва Репутация: нет Всего: нет |
тока тока гугль меня на StackWalk послал... тока с пометкой об MSVC
--------------------
'long long long' is too long for GC |
|||
|
||||
| Randajad |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 15.3.2012 Репутация: 8 Всего: 8 |
Кусочек из моего логгера:
Так сказать псевдокод. Чистое winapi. |
|||
|
||||
| NYX |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 165 Регистрация: 9.1.2007 Где: Россия, Москва Репутация: нет Всего: нет |
Блин под gcc (MinGW) такого нет.
Но смысл примерно ясен. А вот еще, тут про ANSI дефолты прочел, что типо можно так:
Можно заместо throw что то свое подставить? не знаю как сформилуровать мыслю на счет throw. Да и ваще если бы можно было бы обойтись без постоянной реализации однотогоже кода в теле функции было бы круто... потому что throw как бы... в общем эт так, мысли в слух... Это сообщение отредактировал(а) NYX - 13.6.2012, 22:29 --------------------
'long long long' is too long for GC |
|||
|
||||
| Randajad |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 15.3.2012 Репутация: 8 Всего: 8 |
Что за блин? Это винапи и писалось под гцц. Работает на любом компиляторе.
Добавлено через 1 минуту и 53 секунды Нельзя так, увы. |
|||
|
||||
| NYX |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 165 Регистрация: 9.1.2007 Где: Россия, Москва Репутация: нет Всего: нет |
Окей, тогда по порядку.
STACKFRAME - не нашлось не в одном хидере, искал по содержимому. StackWalk - аналогично. Да к тому же под MinGW не одного засвета. Тока под VC нашлось типо... у гугля нет ассоциаций таких с этими двумя весчами Это сообщение отредактировал(а) NYX - 13.6.2012, 22:36 --------------------
'long long long' is too long for GC |
|||
|
||||
| Randajad |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 15.3.2012 Репутация: 8 Всего: 8 |
У меня заинклюдены:
Где-то тут. И еще бы я посоветовал уделять внимание не только логгерам, но и качеству кода, дабы меньше ошибок было. Это сообщение отредактировал(а) Randajad - 13.6.2012, 22:42 |
|||
|
||||
| NYX |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 165 Регистрация: 9.1.2007 Где: Россия, Москва Репутация: нет Всего: нет |
Черт побери. Есть такие. Не уж то винда 7я в корень оскотинилась ищет кое как :( дать бы поддых тому кто виндус придумал
Работает... Поторопился. StackWalk по прежнему не работает... Это сообщение отредактировал(а) NYX - 13.6.2012, 22:48 --------------------
'long long long' is too long for GC |
|||
|
||||
| Randajad |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 15.3.2012 Репутация: 8 Всего: 8 |
Поиск в вянде всегда был неадекватным, это да.
Кстати, чтобы функции Sym* работали нужно делать до вызова сий выше приведенной функции это: SymInitialize(hProc, 0, TRUE); И после надо бы: SymCleanup(hProc); Везде, где hProc - хэндл текущего процесса. Хотя на другие тоже можно натравить... Добавлено @ 22:52 Я с планшета в кроватке, мне тяжело искать. Завтра поищу, если не разберешься. Может WINVER=0x501 забыл или еще что? Это сообщение отредактировал(а) Randajad - 13.6.2012, 22:54 |
|||
|
||||
| NYX |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 165 Регистрация: 9.1.2007 Где: Россия, Москва Репутация: нет Всего: нет |
Это само собой --------------------
'long long long' is too long for GC |
|||
|
||||
| Randajad |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 15.3.2012 Репутация: 8 Всего: 8 |
А у гцц оказывается есть милый параметр!
Это сообщение отредактировал(а) Randajad - 14.6.2012, 10:34 |
|||
|
||||
| NYX |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 165 Регистрация: 9.1.2007 Где: Россия, Москва Репутация: нет Всего: нет |
Это практически то, что я и искал! Счас буду ковырять!
Randajad, честь и хвала тебе! Очень здорово помог! Так! Нашел вполне себе компилируемый экземпляр...
Результат скомпилился, но вывода нет. Полагаю надо какие то дополнительные параметры компилятору кинуть? Нашел вроди бы установку параметров в виде: -finstrument-fnctions для g++ однако с такими параметрами отказывается компилить, типо unrecognized и все такое ВСЕ! РАБОТАЕТ! Я ща помру от радости! ВАХ-ВАХ-ВАХ! Randajad, спасибо тебе огромное еще раз! Очень здорово помог. Теперь буду ковыряться с найденными тобой декларациями, что да как. Думаю весьма мощная штуковина, можно не только отчет для стека вызовов делать, но и еще какие то навороты, например подготовка объектов и зачистка всякого рода. В общем и в целом одним слово ВЕЩЬ! Это сообщение отредактировал(а) NYX - 14.6.2012, 16:14 --------------------
'long long long' is too long for GC |
|||
|
||||
| NYX |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 165 Регистрация: 9.1.2007 Где: Россия, Москва Репутация: нет Всего: нет |
Интересно, а можно ли сделать это не для всех функций, а например только для функций класса или модуля или namespace?
--------------------
'long long long' is too long for GC |
|||
|
||||
| Randajad |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 15.3.2012 Репутация: 8 Всего: 8 |
Можно. Там ключики есть.
StackWalk - разобрался? Днем руки его объявление найти не дошли. Это сообщение отредактировал(а) Randajad - 14.6.2012, 19:24 |
|||
|
||||
| NYX |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 165 Регистрация: 9.1.2007 Где: Россия, Москва Репутация: нет Всего: нет |
to
Со StackWalk так и не разобрался. По дефолту у меня винвер 0x400 редефайнил на 501 ничего не дало O_o Если честно я даже не знал что его стоит передефайнить. Я думал установщик сам проставляет нужные дефайны исходя из системы на которую ставит... В общем не удалось мне запустить тот самый код и твоего примера. Я как за комп сяду напишу какие траблы возникли, попробую расковыряться в чем дело. А можно подробнее про ключики? Ваще где их глянуть можно (в каком разделе gcc мануала)? Это сообщение отредактировал(а) NYX - 14.6.2012, 20:09 --------------------
'long long long' is too long for GC |
|||
|
||||
| Randajad |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 15.3.2012 Репутация: 8 Всего: 8 |
Я - волшебник?
Работает. Это весь код main.cpp. С целью проверить компиляцию воткнул. Добавлено через 25 секунд Ключики смотреть в гуглике. Этот я именно там нашел. |
|||
|
||||
| NYX |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 165 Регистрация: 9.1.2007 Где: Россия, Москва Репутация: нет Всего: нет |
удивительный день волшебства!
еще на подходе красным подчеркивает нетбинс. Ну ради прикола попытался откомпилить... выдал ругачку undefined reference to `__imp__StackWalk@36' зачит всеж имеется онное (ну онное имеется безусловно, видел я это в хидере). Но что самое удивительное, именно такую ругачку вижу впервые при попытке откомпилить. Значит судя по сему надобно: * либо статически чота прилинковать * либо создать какой то объект * либо переобъявить Что из трех надо сделать буду ковырять в гугле
В этом даже сомнений не возникало понять других людей, при всей сложности собеседника (в лице меня дубалома-любителя) Это сообщение отредактировал(а) NYX - 14.6.2012, 23:00 --------------------
'long long long' is too long for GC |
|||
|
||||
| Randajad |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 15.3.2012 Репутация: 8 Всего: 8 |
Ну да, прилинковать надо, как бы ругается и на что.
imagehlp либа, к сведению. |
|||
|
||||
| NYX |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 165 Регистрация: 9.1.2007 Где: Россия, Москва Репутация: нет Всего: нет |
Работает
прилинковал соответвтующий *.a Счас бошка не соображает мальца. Я утром протестирую, хотя в общем то примерно я понял как оно работает Это сообщение отредактировал(а) NYX - 15.6.2012, 03:11 --------------------
'long long long' is too long for GC |
|||
|
||||
| NYX |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 165 Регистрация: 9.1.2007 Где: Россия, Москва Репутация: нет Всего: нет |
Тока я чот не совсем понял, там судя по всему перечисляются не имена функций и имена файлов, в которых списком обозначены имена функций (дабы что бы не брахлить опшенцы длиннющими списками. Наверно так... А, кстати! Для исключения функций указывается аттрибут __attribute__((no_instrument_function)), собственно если убрать строки деклараций с атрибутами для _cyg_profile_func_* то получается вечная рекурсия. Соответственно для всех функций входящих в состав "пользовательских \ объявленных пользователем" можно установить такой аттрибут и функция будет исключена. Так что нафиг списки в опциях. Все пользовательские функции которые являются подвызовом _cyg_profile_function_* надо изолировать аттрибутом. Иначе будет вечная рекурсия. Кстати если использовать например внутри *_enter и *_exit векторы с их push_back \ pop_back, то получается так же самая рекурсия. Так что выход наверно такой, не заморачиваться с вектором и сделать свой стек простенький для протоколирования вызовов. В общем под это дело можно целый-отдельный модуль выделить, где первоначально объявляются все эти дебаггерские дела и функции "страдающие" производительностью (напр. рендеры или функции связанные со временем или может даже потоки... всех их можно заблаговременно изолироваться от инструментария функционала простым аттрибутом. Это просто грандиозно! Это сообщение отредактировал(а) NYX - 15.6.2012, 20:29 --------------------
'long long long' is too long for GC |
|||
|
||||
| NYX |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 165 Регистрация: 9.1.2007 Где: Россия, Москва Репутация: нет Всего: нет |
Товарищи, а как на ваш взгляд, имеет ли смысл реализовывать такую стратегию отчета об ошибках?
Программа реализована в виде двух модулей. Первый модуль исполняемый, второй модуль отчетный. В исполняемом модуле имеется некий класс-прокси, который отвечает за вызов модуля отчета, в т.ч. обеспечение ожидания в случае множественных вызовов из разных потоков. Класс-прокси является так же синглтоном и имеет в своем теле функцию __stdcall предназначеную для переопределения SetUnhandledExceptionFilter. Далее, для определения логической ошибки, производится вызов функции класса-прокси с указанием базовых данных в виде __FUNCTION__ и кода ошибки. В случае runtime ошибки так же производится вызов модуля отчета, но уже с более полной информацией о сбое. Производится вызов модуля отчета под средством CreateProcess. Модуль отчета имеет обработку аргументов из cmd строки, которые позволяют: очистить лог записать лог Далее, для чего такой костыль? Я вот так подумал, я же ведь могу получить доступ из одного процесса к другому процессу? Может быть мне будет проще сделать дамп слетевшего процесса из внешнего + это будут два раздельных процесса и у каждого своя виртуальная память, не разделяемая. В случае тотального пипца модуль отчета будет жив как не крути. В случае если надо будет просмотреть стек вызовов, то в том же олли могу поставить брейкпоинт на вызове функции прокси-класса и в момент завершения\слета посмотреть в олльге стек вызовов. Этого будет достаточно думаю. А дамп и прочее можно будет потом дописать в модуле отчета, как бы со временем дополняя функционал. А модуль исполняемый как есть, так и есть. Все что он может сделать, так это выполнять код. Модуль отчета можно например отдать на рабработку члену группы, какому нибудь системщику которые с асмом дружит как пчела с цветком ВАХ! Самый прикол в том, что я написал уже некую заготовку такой штуковины, вполне работает, модуль отчетности занимает копейки и прежде чем полностью повесить проц, надо запустить ну что то около нцати сотен экземпляров близкому к тыщячи Есть ли где нибудь описание опдобного метода? Насколько взрослым является такой метод? Это сообщение отредактировал(а) NYX - 1.8.2012, 20:55 --------------------
'long long long' is too long for GC |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |