Motto

В тихом саду здравомыслия
Пусть на вас постоянно падают
кокосовые орехи пробужденности.
Чогьям Трунгпа РИНПОЧЕ


Версия для мобильного


четверг, 19 мая 2011 г.

Описание CnPack Wizards часть 18: cnDebug.pas

Продолжаю обзор CnWizards – бесплатного эксперта для Delphi с открытым исходным кодом от китайских программистов. В прошлый раз я рассказывал о CnDebugViewer-е – просмотрщике отладочных сообщений. Сегодня я расскажу как эти сообщения отправлять.

C помощью CnDebug из программы можно отправлять строковую информацию, integer, float, color и RTTI-информацию об объектах и компонентах. CnDebug также умеет записывать в журнал информацию о возникающих в программе исключениях, вместе с содержимым стека вызовов.

Файлы и директивы компилятора

Для работы CnDebug нам понадобятся файлы, расположенные в папке C:\Program Files\CnPack\CnWizards\Source\

  • cnDebug.pas – обязательно. Здесь объявлен основной класс отладчика: TCnDebugger.
  • CnPack.inc – обязательно. Здесь определяются директивы компилятора.
  • CnPropSheetFrm.pas и CnPropSheetFrm.dfm – опционально. Только если объявлена директива компилятора SUPPORT_EVALUATE (по умолчанию объявлена). В этом модуле описана форма инспектора CnDebug, предназначенной для изучения RTTI информации об объектах.

Директивы компилятора, влияющие на работу CnDebug:

  • USE_JCL включает использование кода из JCL юнитов JclDebug, JclHookExcept. Если эта директива включена, то CnDebugger будет автоматически отсылать в журнал сообщения о возникших в ходе работы программы исключениях.
  • DUMP_TO_FILE – в конструкторе CnDebugger-a включает опцию DumpToFile (по умолчанию выключена, как опция так и директива).
  • DEBUG – включает отправку сообщений с помощью методов LogЧто-нибудь.
  • RELEASE – отключает директиву DEBUG.
  • ALLDEBUG – включает отладочные директивы: DEBUG, SUPPORT_EVALUATE.
  • NDEBUG – полностью отключает вывод сообщений, и для методов LogЧто-нибудь и для методов TraceЧто-нибудь. Имеет самый высокий приоритет.

Ложка дёгтя

Единственное, что меня смущает во всём этом – это лицензия под которой распространяется код. На данный момент лицензия CnPack Wizards запрещает использовать код Мастеров в коммерческих продуктах. К сожалению, в лицензии нигде не указано что код модулей CnDebug.pas является исключением. Я зарегистрировал в трекер проекта запрос на изменение лицензии для этих файлов. Если вас заинтересовали возможности CnDebugger-a, прошу отметиться в комментариях к запросу.

Выдержка из лицензии CnWizards:

4. Исходный код CnPack IDE-Мастера может быть использован Вами в собственных проектах без оповещения команды CnPack. Все производные от CnPack IDE-Мастера приложения должны распространятся под совместимой с официальной свободной лицензией, которую Вы можете загрузить с сайта http://www.opensource.org/.

5. Вы не можете использовать исходный код CnPack IDE-Мастера для разработки проприетарного или коммерческого ПО без получения нашего официального разрешения. Чтобы получить такое разрешение, свяжитесь с командой CnPack.

Методы TCnDebugger

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

function CnDebugger: TCnDebugger;

Отправка сообщений

Для отправки сообщений TCnDebugger предлагает два типа методов: Log-что-то-там и Trace-что-то-там. Методы Log-что-то-там выполняются если модуль CnDebug.pas был скомпилирован с директивой DEBUG. Т.е. эти методы стоит использовать для отправки информации, доступной только в отладочной версии программы. А методы Trace-что-то-там будут выполнятся как в DEBUG, так и в RELEASE сборке. В дальнейшем тексте я буду указывать в качестве примера только методы с префиксом Log.

Чтобы отключить отправку сообщений с помощью обоих методов, при компиляции cbDebug.pas надо указать директиву NDEBUG.

В TCnDebuggger-е много методов для отправки текста, которые отличаются лишь параметрами. Все параметры отладочного сообщения можно видеть в методах LogFull и TraceFull. Все параметры этих методов могут использоваться для фильтрации в CnDebugViewer:

procedure LogFull(const AMsg: string; const ATag: string; ALevel: Integer; AType: TCnMsgType; CPUPeriod: Int64=0);
procedure TraceFull(const AMsg: string; const ATag: string; ALevel: Integer; AType: TCnMsgType; CPUPeriod: Int64 = 0);

Но чаще всего вы наверное будете пользоваться методами LogMsg/TraceMsg и LogFmt/TraceFmt: 

procedure LogMsg(const AMsg: string);
procedure LogFmt(const AFormat: string; Args: array of const);

Все отправленные сообщения в которых не указан параметр Level, будут иметь значение Level по умолчанию - 3.

Метод LogSeparator добавляет в журнал событий большую красную разделительную черту.

procedure LogSeparator;

Методы LogEnter и LogLeave могут использоваться для создания вложенной иерархии сообщений в дереве (списке) сообщений просмотрщика.

procedure LogEnter(const AProcName: string; const ATag: string = ''); 
procedure LogLeave(const AProcName: string; const ATag: string = '');

Методы для отправки информации о простых типах данных:

procedure LogAssigned(Value: Pointer; const AMsg: string = ''); 
procedure LogBoolean(Value: Boolean; const AMsg: string = ''); 
procedure LogColor(Color: TColor; const AMsg: string = ''); 
procedure LogFloat(Value: Extended; const AMsg: string = ''); 
procedure LogInteger(Value: Integer; const AMsg: string = ''); 
procedure LogChar(Value: Char; const AMsg: string = ''); 
procedure LogDateTime(Value: TDateTime; const AMsg: string = '' ); 
procedure LogDateTimeFmt(Value: TDateTime; const AFmt: string; const AMsg: string = '' ); 
procedure LogPointer(Value: Pointer; const AMsg: string = ''); 
procedure LogPoint(Point: TPoint; const AMsg: string = ''); 
procedure LogRect(Rect: TRect; const AMsg: string = ''); 
procedure LogStrings(Strings: TStrings; const AMsg: string = ''); 
procedure LogMemDump(AMem: Pointer; Size: Integer); 
procedure LogVirtualKey(AKey: Word); 
procedure LogVirtualKeyWithTag(AKey: Word; const ATag: string); 

Методы для отправки информации об объектах:

procedure LogObject(AObject: TObject); 
procedure LogObjectWithTag(AObject: TObject; const ATag: string); 
procedure LogCollection(ACollection: TCollection); 
procedure LogCollectionWithTag(ACollection: TCollection; const ATag: string); 
procedure LogComponent(AComponent: TComponent); 
procedure LogComponentWithTag(AComponent: TComponent; const ATag: string);

Метод LogLastError заносит в журнал код и описание ошибки полученной с помощью вызова GetLastError.

procedure LogLastError; 
procedure TraceLastError;

Работа с таймерами

Эти методы позволяют запустить/остановить таймер. В качестве идентификатора таймера выступает Tag.

procedure StartTimeMark(const ATag: Integer; const AMsg: string = ''); overload; 
procedure StopTimeMark(const ATag: Integer; const AMsg: string = ''); overload; 
procedure StartTimeMark(const ATag: string; const AMsg: string = ''); overload; 
procedure StopTimeMark(const ATag: string; const AMsg: string = ''); overload; 

Фильтрация исключений

CnDebugger умеет перехватывать возникающие в программе исключения и отправлять информацию о них в просмотрщик (см. директиву компиляторы USE_JCL). Для того, чтобы не засорять список сообщений ожидаемыми исключениями, в TCnDebugger-e предусмотрена возможность фильтрации исключений. Для этого предназначены следующие методы.

procedure AddFilterExceptClass(E: ExceptClass); overload; 
procedure RemoveFilterExceptClass(E: ExceptClass); overload; 
procedure AddFilterExceptClass(const EClassName: string); overload; 
procedure RemoveFilterExceptClass(const EClassName: string); overload;

С фильтрацией исключений есть один нюанс баг. Я столкнулся с ним при написании этого поста. Фильтрация будет работать, только если исключение было добавлено непосредственно через функцию CnDebugger. Если вы создадите своего наследника и будете работать с ним через свою переменную, то фильтры исключений работать не будут. Причина в том, что при проверке наличия исключения используется экземпляр TcnDebugger созданный в модуле CnDebug.pas.

procedure StartDebugViewer;

Запускает DebugViewer. Имя файла DebugViewer-а берётся из Registry из ключа: HKCU\Software\CnPack\CnDebug\CnDebugViewer, если оно не указано, то используется имя по умолчанию: CnDebugViewer.exe.

procedure EvaluateObject(AObject: TObject); overload; 
procedure EvaluateObject(APointer: Pointer); overload;

Открывает указанный объект в CnDebugInspector-е.

CnDebug Inspector

image2

месте CnPack Wizards поставляется модуль CnPropSheetFrm.pas содержащий инспектор объектов. С его помощью можно изучить свойства объекта в режиме исполнения. Для вызова инспектора в этом модуле объявлена глобальная функция:

function EvaluatePointer(Address: Pointer; Data: Pointer = nil; AForm: TCnPropSheetForm = nil): TCnPropSheetForm; 

p.s. Работа с cnDebug.pas описана в справке CnPack Wizards в статье “CnDebug Help”.

В следующей публикации читайте о настройках CnWizards.


  • Думаю, что не ошибусь если скажу, что Китай сейчас является одним из главных производителей техники на мировом рынке. Посмотреть каталог сайтов и почитать отзывы по теме китайские интернет магазины можно пройдя по ссылке. Сам же я, предпочитаю заказывать товары на Ebay-е, или через магазины продавцов, хорошо зарекомендовавших себя на ебэе. А чтобы заказывать было веселее, можно изучить такую тему, как "заработок в интернете метод", и, развлекая себя мыслью "заработать на рулетке - это миф, фикция или лудомания?", продолжить тратить свои кровно заработанные денежки. А если есть желание, то можно попробовать сделать "бизнес" на повышении стоимости квартиры за счёт выполнения такой операции как перевод жилого помещения в нежилое, что позволит повысить её стоимость.

4 комментария:

  1. Привет. Почему то у меня не получается работать с CnDebugViewer :( даже пример из их папки не совсем до конца работает.

    CnDebug Inspector открывается без проблем, но вот лога сообщений не ведет. Так же, если нажать на кнопку "Start", она сама отжимается :(

    ОтветитьУдалить
    Ответы
    1. Привет.

      Я не сталкивался с такой проблемой. Но cnPack IDE Wizards - это инструмент с открытым исходным кодом, а это значит, что с любой проблемой при желании можно разобраться самостоятельно.
      Исходники к CnDebugViewer можно найти здесь.


      Удалить
    2. У тебя как работает: надо нажать кнопку Start для начала ведения логов, или она сама нажимается?

      P.S. У меня XE2 и Win7 может как то с этим связано? :)

      Удалить
    3. Вчера не догадался, надо ее под администратором запустить, тогда работает. Правда свое приложение тоже надо под админом запускать :(

      Удалить

Постоянные читатели