SystemTimeToFileTime(SystemTime, FileTime);
EnterCriticalSection(LogCriticalSection);
WriteLn(LogFile, Format('%s %.8x%.8x %5',
[FormatDateTime('yy.mm.dd hh.inm.ss'. Now),
FileTime.dwHighDateTime, FileTime.dwLowDateTime, S]));
LeaveCriticalSection(LogCriticalSection);
end;
procedure Startup;
var
FileName: String;
begin
InitializeCriticalSection(LogCriticalSection);
FileName:= Format(«Log file for %s at %s.txf,
[ParamStr(O), DateTimeToStr(Now)]);
while Pos(':', FileName) 0 do
FileName[Pos(':', FileName)]:= '.';
while Pos('/', FileName) 0 do
FileName[Pos('/', FileName)]:= '-';
while Pos('\', FileName) 0 do
FileName[Pos('\', FileName)]:= '.';
AssignFile(LogFile, FileName);
Rewrite(LogFile);
end;
procedure Shutdown;
begin
CloseFile(LogFile);
DeleteCriticalSection(LogCriticalSection);
end;
initialization Startup;
finalization Shutdown;
end.
Этот модуль сам создает, открывает и закрывает файл протокола. Имя файла создается с учетом имени приложения и текущих даты и времени, что исключает возможность записи информации поверх существующего файла. Для использования модуля условно включите его, как показано ниже.
unit MyUnit;
interface
uses
($ifdef Debug} uLog, {$endif)
Windows, Messages, SysUtils, Classes,
. .
Затем используйте его приблизительно так.
{$ifdef Debug)
Log(Format('Entering the Foo procedure; Bar = %d',[Bar]));
{$endif}
He забывайте размещать вызов между директивами условной компиляции, иначе при компиляции коммерческой версии возникнет ошибка.
Модуль uLog обладает двумя интересными и полезными свойствами. Во-первых, каждая запись в файл предваряется информацией о дате, времени и шестнадцатеричным числом, соответствующим системному времени в миллисекундах. Эта информация может быть весьма полезной, особенно когда вы хотите отследить последовательность событий в приложении. Во-вторых, модуль использует критические разделы (critical section), что обеспечивает доступ к файлу только одной подзадачи в один момент времени.
На рис. 2.25 показан типичный файл протокола в программе Notepad.
Рис. 2.25.Пример отладочного файла протокола
Как правильно использовать файл протокола? Какую информацию в него записывать? Сколько программистов, столько и ответов на эти вопросы. Лично я предпочитаю придерживаться золотой середины между „записывай все“ и „записывай только то, что отлаживаешь“.
Обработка ошибок.
Прежде чем начать искать ошибки, стоит определить, где именно они водятся. Перед поиском ошибок скопируйте свой проект и работайте с копией. В крайнем случае, когда вы запутаетесь окончательно, вы сможете вернуться к тому, с чего начинали. Только не забудьте между исправлением ошибки и удалением рабочей копии проекта внести изменения в основной проект!
Не забывайте и о комментариях, которые позволяют если не найти ошибки, то хотя бы отследить, что и когда вы делали.
Учитесь у великих! Правило „Разделяй и властвуй“ еще никто не отменял. А потому разделяйте свою задачу на части и властвуйте. Найти ошибку или убедиться в ее отсутствии в части программы проще, чем во всей программе в целом, особенно когда появляется эффект интерференции ошибок, при котором ошибка начинает взаимодействовать с другой так, что отследить их становится очень сложно.
И, тем не менее, при отладке программисты нередко оказываются в почти безвыходной ситуации. Некоторые ошибки я и опишу в этом разделе и подскажу, как успешно их поймать.
Error Setting Debug Exception Hook
Если вы увидели сообщение, показанное рис. 2.26, значит, отладчик оказался в трудном и, главное, нестабильном положении, что обычно происходит после аварийной остановки отлаживаемого приложения. Что делать? Попробуйте воспользоваться командой Run/Program Reset и запустить приложение еще раз. Не помогло? Выполните команду Program/Build All. И это не дает результата? Тогда вам придется выйти из среды разработки и запустить ее еще раз. Самый последний совет — проделать то же и с операционной системой…
Рис. 2.26. Сообщение Error setting debug exception hook
Access Violation
Нарушение доступа — это ночной кошмар программистов, ужас, летящий на крыльях ночи… Весь ужас в том, что очень часто это — мина с часовым механизмом, внезапно взрывающаяся после сотен, а то и тысяч строк пройденного кода.
В действительности access violation — всего лишь простая ошибка, означающая, что ваше приложение „получило по рукам“ от операционной системы за попытку влезть в область памяти, ему не принадлежащей. Когда вы получаете сообщение об этом (рис. 2.28), вам рассказывают, кто (первое число) и куда (второе число) пытался залезть. Первое число предоставляет адрес инструкции, попытавшейся нарушить границы, а второе указывает, куда именно хотела обратиться инструкция-нарушительница.
Вернитесь в среду, выберите команду Search/Find Error, введите адрес ошибки (первое число в сообщении) в поле ввода диалогового окна, щелкните на кнопке ОК и читайте подходящую молитву. Если вам повезет, в окне появится строка, вызвавшая ошибку. Гораздо чаще этого не происходит, так как ошибка оказывается где-то в VCL или библиотеке, скомпилированной без отладочной информации, и вызывает ее передача неверного параметра в функцию, при
Последние комментарии
14 часов 47 минут назад
15 часов 1 минута назад
16 часов 9 минут назад
1 день 3 часов назад
1 день 3 часов назад
1 день 4 часов назад