2013-05-09 3 views
5

Я пытаюсь создать систему журналов в своей программе, которая будет регистрировать отладочные сообщения в текстовых файлах, и я хочу сохранить точное место в коде, в котором вызывается сообщение журнала, но я не хочу использовать функцию Assert, потому что он создает исключения, и эта система не предназначена для регистрации только исключений, также мне нужно написать некоторую информацию об отладке.Delphi: Как получить (текущая строка кода, текущий блок, текущая функция) без использования Assertion?

пример usning утверждают:

procedure AnyProcedure(); 
begin 
    try 
    Assert(1=0); 
    except 
    on E: Exception do 
     Log.AddLine('Log occurred is '+E.Message+' : Start');//Log occurred is "c:\progr~..jkdj.pas" at line [29] 
    end; 

    //....some code 
    try 
    Assert(1=0); 
    except 
    on E: Exception do 
     Log.AddLine('Log occurred is '+E.Message+' : Step1 done');//Log occurred is "c:\progr~..jkdj.pas" at line [37] 
    end; 

    //....some code 
    try 
    Assert(1=0); 
    except 
    on E: Exception do 
     Log.AddLine('Log occurred is '+E.Message+' : Step2 done');//Log occurred is "c:\progr~..jkdj.pas" at line [45] 
    end; 

    //....some code 
    try 
    Assert(1=0); 
    except 
    on E: Exception do 
     Log.AddLine('Log occurred is '+E.Message+' : Step3 done');//Log occurred is "c:\progr~..jkdj.pas" at line [53] 
    end; 

    //....some code 
    try 
    Assert(1=0); 
    except 
    on E: Exception do 
     Log.AddLine('Log '+E.Message+' : End');//Log occurred is "c:\progr~..jkdj.pas" at line [61] 
    end; 
end; 

это работает отлично, единственное, что она вызывает исключение, и код стал слишком большим, поэтому я не могу использовать функцию -см следующий пример функции LogMessage- и вызов это в другом месте, потому что линия будет такой же всегда и имя файла будет где функция LogMessage реализована:

не рабочий пример:

procedure LogMessage(AMessage: String); 
var AFile, ALine: String; 
begin 
    try 
    Assert(1=0);    //line 29 
    except 
    on E: Exception do 
    begin 
     AFile:= Copy(E.Message, Pos(' (', E.Message)+2, Pos(', line ', E.Message)-Pos(' (', E.Message)-2); 
     ALine:= Copy(E.Message, Pos(', line ', E.Message)+7, Pos(')', E.Message)-Pos(', line ', E.Message)-7); 
     ShowMessage('Log occurred in file "'+AFile+'" at line ['+ALine+'] : '+AMessage); 
    end; 
    end; 
end; 

procedure AnyProcedure(); 
begin 
    LogMessage('Start'); //Log occurred in file "c:\progr~....jkashdj.pas" at line [29] 
//.... 
    LogMessage('step1'); //Log occurred in file "c:\progr~....jkashdj.pas" at line [29] 
//.... 
    LogMessage('step2'); //Log occurred in file "c:\progr~....jkashdj.pas" at line [29] 
//.... 
    LogMessage('step3'); //Log occurred in file "c:\progr~....jkashdj.pas" at line [29] 
//.... 
    LogMessage('end'); 
end 

, пожалуйста, помогите, и спасибо заранее.

+5

Кстати, 1 = 0 не является самым простым выражением, которое вычисляется как False. Это было бы, ну, ложь. –

+0

Спасибо за выражение False, я написал код очень быстро, не подумав о том, как он будет выглядеть. Я помню, что я скопировал его из справки Delphi. –

ответ

10

Вы можете связать свою собственную процедуру TAssertErrorProc с переменной AssertErrorProc. Вы могли бы написать что-то вроде этого:

procedure OnAssert(const Message, Filename: string; LineNumber: Integer; 
    ErrorAddr: Pointer); 
begin 
    ShowMessage(Format('Assert in file "%s" at line %d.', [Filename, LineNumber])); 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    AssertErrorProc := OnAssert; 
end; 
+1

Я знаю, что этот ответ противоречит заданному вопросу (* Я не хочу использовать Assert *), но он решает причину, по которой OP не хочет ее использовать (* потому что он создает исключения *). – TLama

+0

Я думаю, что это решит проблему, я просто не знал, как использовать функцию утверждения. спасибо –

+0

Добро пожаловать! – TLama

9

Самый простой способ отображения из указателя команд на единицу имя и номер строки, чтобы использовать один из различных библиотек отладки: madExcept, EurekaLog, JclDebug и т.д.

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

+0

Я слышал об этих библиотеках, но у меня действительно нет времени попробовать их, но спасибо за ответ. –

+1

Ну, если у вас нет свободного времени, чтобы сделать это правильно, воспользуйтесь быстрым вариантом. –

+0

Требуется полная отладочная информация, представляющая обратные инженерные риски. Я всегда пропустил что-то вроде http://www.freepascal.org/docs-html/prog/progsu41.html#x47-460001.1.41 в Delphi. (способы включения файла и linenr в двоичный файл без debuginfo). У него есть недостаток, хотя вы должны передавать его каждый раз, когда он используется, поскольку он не может получить информацию, разворачивая стек –