Связь и интернет Архив Программирование
   
Сделать стартовойСделать закладку            
   ПОИСК  
   
Главная / Pascal и Delphi / Учебник по Delphi 5 / Тестирование и отладка /
8  Perl
8  PHP
8  JavaScript
8  HTML
8  DHTML
8  XML
8  CSS
8  C / C++
8  Pascal и Delphi
8  Турбо Ассемблер
8  MySQL
8  CASE-технологии
8  Алгоритмы
8  Python
8  Обратная связь
8  Гостевая книга
Новости о мире


Силовая отладка - Программирование от RIN.RU
Силовая отладка




Под силовой отладкой (brute-force debugging), отладкой "в лоб", понимаются методы отладки, основанные не на возможностях отладчиков, а на трюках, родословная которых, пожалуй, восходит к временам Атанасова и Лебедева, создававших первые ЭВМ по обе стороны океана.


При разработке программ часто нет необходимости в полной отладке, просто хочется убедиться в том, что какая-либо функция работает так, а не иначе (я весьма часто попадаю в подобные ситуации, когда использую малознакомые функции API или плохо или вовсе недокументированные методы объектов, и мне надо провести эксперимент, чтобы выяснить, так ли я представляю работу функции).


В этих случаях проще забыть об отладчике и просто добавить пару строк кода для вывода информации. Для этого есть много путей, и о некоторых из них будет рассказано ниже.


ПРЕДОСТЕРЕЖЕНИЕ: Большинство таких методов - из серии "быстро и грязно", и я бы не рекомендовал заменять ими описанные ранее методы тестирования и отладки.


Вывод отладочной информации в форме.


Один из способов вывода такой информации - ее вывод непосредственно в форме. Обычно проще всего создать компонент TLabel или подобный ему для непосредственного вывода информации. В таком случае выведенная информация не потеряется даже при перерисовке формы.


Посмотрите на описания функций ExtractFileDir и ExtractFilePath в справочной системе Delphi 4. Я не берусь точно судить по документации о различии между этими функциями, но я знаю, что мне делать. Я создаю новое приложение (выбрав пункт меню File/New Application) и помещаю в главную форму элемент TButton и два элемента TLabel (форма будет выглядеть так, как на рис. 2.20).


Дважды щелкните на кнопке TButton и добавьте код к обработчику события OnClick.



procedure TFormI.ButtonlClick(Sender: TObject);
begin
Labell.Caption:= ExtractFileDir(Application.ExeName);
Label2.Caption:= ExtractFilePath(Application.ExeName);
end;




(Application. ExeName возвращает полное имя файла приложения). Нажмите клавишу для компиляции и запуска приложения и щелкните на кнопке. Теперь вам должно быть ясно, чем различаются эти две функции.


Недавно у меня возникла проблема с чужой DLL, исходного кода которой я, естественно, не имел. Странным было то, что эта DLL выцелела при загрузке и не освобождала большой фрагмент виртуальной памяти. Я создал маленькое приложение, в котором после каждого щелчка на кнопке сообщалось, сколько виртуальной памяти свободно. Мне хотелось сохранять предыдущие результаты, а потому, я использовал элемент управления TMemo и добавлял в него новые строки с результатами.


Чтобы посмотреть, как это делается, создадим новое приложение и разместим в форме элементы управления TMemo и TButton (и не забудем установить значение свойства TMemo.ScrollBars равным ssVertical).




В обработчик события OnClick добавьте следующий код.


procedure TFormI.ButtonlClick(Sender: TObject);
var
MemStat: TMemoryStatus;
begin
VirtualAlloc(nil, 1000000, MEM_RESERVE, PAGE_READWRITE);// 1
MemStat.dwLength:= SizeOf(TMemoryStatus); // 2
GlobalMemoryStatus(MemStat); // 3
Memol.Lines.Add(IntToStr(MemStat.dwAvailVirtual)); // 4
end;




Не беспокойтесь о деталях вызова API-функции VirtualAlloc в строке 1. Здесь ее вызов требует от операционной системы зарезервировать миллион байтов памяти для дальнейшего использования. API-функция GlobalMemoryStatus возвращает информацию об использовании памяти приложением и системой в целом. Информация возвращается в переменной MemStat, представляющей собой запись типа TMemoryStatus. Перед вызовом GlobalMemoryStatus вы передаете системе информацию о размере структуры, как в строке 2, а затем вызываете функцию (строка 3) и выводите информацию в TMemo в строке 4.


Скомпилируйте и запустите программу, щелкните несколько раз на кнопке - и увидите, что виртуальная память уменьшается примерно на один мегабайт при каждом щелчке, как и ожидалось.


Используя этот метод (без вызова VirtualAlloc), я выяснил, что на самом деле DLL затребовала около 60 Мбайт (!) виртуальной памяти при загрузке и не освободила ее. Даже притом, что Windows 95 предоставляет каждому приложению двухгигабайтовое адресное пространство, потерю 60 Мбайт сложно проигнорировать...


ShowMessage


Кроме вывода информации в форму, можно воспользоваться модальным диалоговым окном. Принципиальное отличие этого метода, в первую очередь, состоит в том, что модальное диалоговое окно останавливает выполнение программы, пока вы его не закроете. Таким образом, у вас имеется достаточно времени, чтобы прочесть и осмыслить полученную информацию.


Процедура ShowMessage (из модуля Dialogs) идеально подходит для этой цели Она позволяет вывести строку любой длины в простом модальном диалоговом окне. Вам только следует создать строку для вывода и передать ее процедуре (можно также использовать MessageDIg, но в нем слишком много шашечек и бантиков, которые требуют немалых усилий для достижения того же эффекта).


ShowMessage получает в качестве параметра одну строку, для создания которой я предпочитаю использовать функцию Format, она идеально подходит для этого, будучи одновременно простым и мощным инструментом в умелых руках.


Рассмотрим простой пример. Используем этот метод для вывода информации, получаемой от уже использовавшейся функции GlobalMemoryStatus.


Создадим новое приложение и поместим TButton в основную форму. Обработчик события OnClick будет выглядеть следующим образом.


procedure TFormI.ButtonlClick(Sender: TObject);
var MemStat: TMemoryStatus;
begin
MemStat.dwLength:= SizeOf(TMemoryStatus);
GlobalMemoryStatus(MemStat);
with MemStat do ShowMessage(Format('Memory load: %d%%'#13 +
'Total physical: %d'#13+'Available physical: %d'#13 +
'Total page file: %d'#13 + 'Available page file: %d'ftl3 +
'Total virtual: %d'#13 + 'Available virtual: %d',
[dwMemoryLoad, dwTotalPhys, dwAvailPhys, dwTotalPageFile,
dwAvailPageFile, dwTotalVirtual, dwAvailVirtual]));
end;




Заметьте, что я внес в строку несколько символов #13 (ASCII-символ возврата каретки). Это позволяет разбить строку при выводе на несколько строк, что существенно облегчает чтение информации.


Судя по результатам Memory load и Available physical, представленным на рисунке, мне стоит всерьез подумать о наращивании памяти своего компьютера.


Вперед  >>>
 1  2 


 8  Комментарии к статье  8 8  Обсудить в чате

 
  
  
    Copyright ©  RIN 2003 - 2004      * Обратная связь