уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Не так уж и давно столкнулся с пренеприятнейшей ошибкой AV при работе с Indy. Если бы дело касалось сугубо меня я бы, не сильно переживая, переписал бы за часик код под Synapse и жил бы счастливо, но было оговорено заранее — вся работа с HTTP через  Indy. Бился над ошибкой два дня с переменным успехом. В итоге ошибка вообще стала проявляться как-то хаотично — повторяю тика-в-тику все действия в программе и один раз есть AV второй раз — нету. В общем жуть да и только. Вообще я стараюсь со своими проблемами часто друзей и знакомых не доставать обычно попадал SeregaAltmer и то потому, что давненько знакомы — можно и подоставать =), а тут всё-таки решил попросить помощи потому как мозг закипал конкретно. Первый кто пришел на ум по части поиска и обработки исключений в Delphi — GunSmoker. Вот он-то и посоветовал мне воспользоваться madExcept‘ом, за что ему (Александру) — большое спасибо, т.к. с того момента для меня практически отпала проблема поиска ошибок в коде, приводящих к самым различным последствием. Ну, а что бы и у Вас не было проблем с отловом AV в Ваших проектах я решил сегодня немного поделиться своим скромным опытом работы с madExcept.
 Что из себя madExcept?

madExcept — это трейсер исключений в ваших Delphi-проектах. Смысл работы инструмента сводится к следующему: каждый раз как в Вашей программе происходит исключение MadExcept его перехватывает, обрабатывает, собирает максимум полезной информации и выдает Вам в виде удобного багрепорта.

Но сказать так и закончить пост — это значит практически ничего не сказать про madExcept. Давайте посмотрим, что этот инструмент может на деле — проведем, так сказать, маленький тест-драйв =) Все же практический пример использования будет нагляднее, чем сухое перечисление всех опций инструмента.

Проект с madExcept.

Итак, качаем бесплатную версию инструмента тут. Устанавливаем и запускаем Delphi. Создаем новый проект и в меню Project жмем опцию «madExcept settings…«:

Жмем на опцию и в открывшемся окне настроек инструмента ставим галочку «enable madExcept»:

Теперь, если вы посмотрите в исходник проекта, то увидите, что в списке uses на первом месте появились сразу несколько новых модулей, имя которых начинается с «mad..». Собственно, пока простого включения использования madExcept нам будет достаточно, чтоб взглянуть на его работу.

Теперь напишем, что-нибудь в проекте такое из-за чего 100% вылетит птичка исключение, например, такое:

procedure TForm3.FormCreate(Sender: TObject);
var S1, S2: TStringStream;
begin
  S1.LoadFromStream(S2)
end;

Тут к гадалке не ходить — будет AV, а нам сейчас только этого и надо. Запускам проект. Если бы мы не включили madExcept мы бы получили что-то наподобие вот такого сообщения:

Что бы мы могли сказать про ошибку? Что это AV, произошедший где-то в программе, а вот где произошла ошибка — это уже надо копаться в коде. С MadExcept все становится намного проще. В результате возникновения ошибки мы получаем вот такое удобное сообщение:

Здесь мы уже можем:

  • продолжить выполнение приложения
  • перезапустить приложение
  • остановить работу приложения
  • отправить багрепорт на почту
  • сохранить багрепорт в файл
  • просмотреть багрепорт
Что касается отправки/сохранения багрепорта — то на этих опциях мы остановимся позднее, а вот просмотр багрепорта мы сделаем прямо сейчас, т.к. эта возможность madExcept’а, думаю, самая что ни есть полезная. Итак, не закрываем окошко с сообщением и жмем кнопку «show bug report»  и видим вот такой красиво и понятно оформленный отчёт об ошибке:
Из этого отчёта мы можем получить максимум полезной информации о том как, где и когда произошла ошибка. При этом вся информация распределена по нескольким вкладкам:
  • general — общая информация о компьютере на котором запускалась программа: кто пользователь, его привилегии, время возникновения ошибки, информация о ЦП, класс исключения (в нашем случае это EAccessViolation) и сообщение об исключении (то самое, которое показана в первом скрине с ошибкой без использования madExcept’а).
  • call stack — эта вкладка сегодня для нас будет наиболее полезна. Здесь содержится информация по адресам и, что самое важно по модулям и методам в результате вызова которых произошло исключение. О содержимом этой вкладки мы ещё поговорим ниже.
  • modules — список модулей, которые были загружены ОС в момент возникновения ошибки.
  • processes — процессы, запущенные в ОС в момент возникновения ошибки.
  • hardware — основное железо компьютера на котором была запущена программа
  • cpu regs — регистры ЦП
  • stack dump — дамп памяти
  • disasm — дизасемблированый код программы в месте возникновения исключения.
В общем видите сами — больше информации собрать по-видимому уже некуда. Есть всё, что угодно. Но для нас сегодня наиболее интересна вкладка call stack. Теперь посмотрим на неё более пристально. Что может сразу бросится в глаза (лично мне бросилось) —   это столбики lines и rel. То есть madExcept не только говорит о том в каком модуле и методе произошел сбой, но и, грубо говоря, тыкает пальцем «вот тут вот на этой самой строке сбой!». Более того, вам даже не надо скролить весь модуль в поисках строки — просто делаем двойной клик по строке в отчёте где заполнен lines и попадаем аккурат на ту самую строку в модуле.
В моем примере ошибка произошла (см. скрин с открытой вкладкой) на 28 строке модуля unit3, которая (строка) в свою очередь является первой (см. значение rel) в методе TForm3.FormCreate. И произошла эта ошибка по причине того, что мы попытались вызвать метод LoadFromStream потока, а в LoadFromStream мы «споткнулись» на установке позиции в потоке.
Круто? Думаю, что не искушенные в делах работы с такими инструментами читатели, должны быть приятно удивлены — толи тыкаться по F4/F7 по модулям программы, а то — открыл отчёт, сделал двойной клик и радуйся жизни.
Другое дело, что иногда можно в программе такого наворотить, что и трейсер устанет разбирать исключение =), но это уже на совести каждого из нас.
Что ещё следует знать про madExcept для первого раза? Наверное стоит упомянуть то, что madExcept можно также использовать и в DLL и в потоках, единственное, что немного придётся пописать ручками. Например, чтобы madExcept отлавливал исключения в вашем TThread необходимо заключить код вот в такую конструкцию:
try
// тут ваш код
except HandleException end;

После этого, если в потоке возникнет исключение, то madExcept вам его обработает и выдаст отчёт.

Пара слов о настройках madExcept

На скринах работы инструмента я постарался вывести Вам аксимум возможностей инструмента. Однако Вы можете настроить вид отчёта и способы его отправки как вам будет угодно. Так, например, на странице «exception box settings» Вы можете настроить внешний вид окна с исключением — включить/отключить кнопки:

А на странице «bug repotr settings» настроить содержимое отчёта об ошибке — убрать ненужные вкладки, указать форму отчёта по вызовам, размер дизасемблированного участка и т.д.:

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

Что можно в целом сказать по поводу madExcept? Поработав с ним некоторое время, пусть и достаточно поверхностно, могу сказать, что инструмент этот мне очень понравился. Не могу сказать, что он «самый-самый» и вообще, т.к. по большому счёту с другими трейсерами исключений дел особых не имел, но то, что madExcept очень помогает избавиться от багов в проектах в минимальный срок и с минимальными усилиями — для меня это стало фактом.

Ну и раз уж я решил закончить пост таким образом, то не могу пройти мимо ещё одного похожего инструмента — EurekaLog. Что касается использования EurekaLog, то информацию по нему Вы можете найти в блоге e GunSmoker‘а — там информации предостаточно.

Думаю, что для первого раза информации по инструменту хватит. Если Вы ещё не использовали madExcept — скачайте и испробуйте его в работе, если уже работали, но отказались от использования — тоже нормально =) Расскажите почему отказались и в пользу какого инструмента? Думаю, что как положительные так и отрицательные отзывы об инструменте будут полезны для читателей.

Книжная полка

Описание Подробно рассматривается библиотека FM, позволяющая создавать полнофункциональное программное обеспечение для операционных систем Windows и OS X, а также для смартфонов и планшетных компьютеров, работающих под управлением Android и iOS
купить книгу delphi на ЛитРес
Описание: Рассмотрены практические вопросы по разработке клиент-серверных приложений в среде Delphi 7 и Delphi 2005 с использованием СУБД MS SQL Server 2000, InterBase и Firebird. Приведена информация о теории построения реляционных баз данных и языке SQL. Освещены вопросы эксплуатации и администрирования СУБД.
купить книгу delphi на ЛитРес

0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
16 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
Kirill
Kirill
10/09/2011 05:30

Отличный пост! Как раз был необходим такой компонент.

Sky
Sky
10/09/2011 12:01

Спасибо! Интересная и самое главное очень полезная вещь. Интересует вот что, целесообразность использования этого дополнения в готовом приложении, в том смысле что на этапе разработки всегда бывают ошибки, но ошибки могут возникнуть когда приложение отошло конечному пользователю, так вот вопрос какие последствия могут возникнуть если оставить это дополнение в релизе программы (скорость работы, размер приложения, потребляемое ОЗУ)?

Дмитрий
Дмитрий
10/09/2011 19:16

Не раскрыто как madExcept помог найти причину «неуловимого» AV при работе с Indy

Keeper
11/09/2011 03:52

Может я криво что поставил, но включение модуля не добавляет юниты к файлу. И даже если я это делаю вручную, ошибка стандартная =(

m1sclick
11/09/2011 12:07

Эх, на сайте убрали бесплатную версию….
Может кто то выложит?

Keeper
11/09/2011 15:58

Ага, добавились. Забавно, что madExpert работает при исключениях самой bds, а вот мои не ловит )

Keeper
11/09/2011 23:59

Vlad, никаких dll, обычный проект. Галочку в enabled поставил. Delphi XE. try..except ведь мешать не должен?

Keeper
12/09/2011 02:41

ААА, HandleException. Спасибо! Шикарная вещь, буду смотреть )

angryvitum
angryvitum
12/09/2011 08:08

Vlad, у меня вопрос: чтобы madExpert показывал место возникновения исключения в коде, нужно ли собирать исполняемый файл с включением отладочной информации и созданием map-файлов?

Я пользуюсь JvExceptionDialog из библиотеки JVCL, но нигде еще не видел сравнительной таблицы по возможностям EurekaLog, madExpert и JvExceptionDialog. Чем не тема для очередного поста?

Александр
02/04/2012 12:22

> Чем не тема для очередного поста?

Такое должен писать человек, хорошо знакомый с тремя инструментами. А где такого возьмёшь, кроме самих разработчиков этих инструментов (которые, само собой, хорошо в этом разбираются и знают конкурентов)? Но обзор тогда будет явно перекошен в сторону кого-то одного.

Кстати, есть ещё крайне малоизвестный и редко обновляемый Exception Magic от нашего разработчика. 

Василий
31/05/2012 23:50

Странный какой-то компонент. Это для тех, кто не умеет пользоваться отладчиком? Ни разу не встречал проблемы при отладке AV.

А если за него ещё и деньги платить — в помойку его!

Александр
01/06/2012 09:04

Трассировщики исключений в первую очередь предназначены для внедрения в программу, которая будет работать на конечной машине клиента, где отладчика нет (имеется в виду коробочный софт, а не корпоративное ПО).