2013-05-09 11 views
5

Ich versuche, ein Protokollsystem auf meinem Programm zu erstellen, das Debugging-Nachrichten auf Textdateien protokolliert, und ich möchte den genauen Ort in dem Code speichern, wo die Protokollnachricht aufgerufen, aber ich möchte Assert Funktion nicht verwenden, weil es erzeugt Ausnahmen und dieses System ist nicht nur für die Protokollierung von Ausnahmen, ich muss auch einige Debugging-Informationen schreiben.Delphi: Wie bekomme ich (aktuelle Codezeile, aktuelle Einheit, aktuelle Funktion) ohne Assertion zu verwenden?

Beispiel usning assert:

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; 

das funktioniert gut die einzige Sache, dass es eine Ausnahme und den Code zu groß geworden erhöht, so kann ich nicht eine Funktion -siehe nächstes Beispiel Funktion LogMessage- und Call es an einem anderen Ort, da die Leitung die gleiche sein wird, immer auch wird der Dateiname sein, wo die LogMessage Funktion implementiert:

nicht funktionierendes Beispiel:

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 

bitte helfen, und danke im voraus.

+5

Übrigens ist 1 = 0 nicht der einfachste Ausdruck, der zu False ausgewertet wird. Das wäre, nun, Falsch. –

+0

Danke auch für den Falschen Ausdruck, ich habe den Code sehr schnell geschrieben, ohne darüber nachzudenken, wie es aussehen wird - ich erinnere mich, dass ich es aus der Delphi-Hilfe kopiert habe. –

Antwort

10

Sie können Ihre eigene TAssertErrorProc Prozedur an die AssertErrorProc Variable binden. Man könnte so etwas schreiben:

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

Ich weiß, diese Antwort ist gegen die gestellte Frage (* Ich möchte nicht Assert *), aber es löst den Grund, warum OP es nicht verwenden will (* weil es Ausnahmen * erstellt). – TLama

+0

Ich denke, das wird das Problem lösen Ich wusste nur nicht, wie die Assertion-Funktion zu verwenden. danke –

+0

Gern geschehen! – TLama

9

Der einfachste Weg, aus den Befehlszeigern auf Gerätenamen und die Zeilennummer zur Karte ist eine der verschiedenen Debug-Bibliotheken zu verwenden: MadExcept, Eurekalog, JclDebug usw.

Diese Tools basieren alle auf der detaillierten Kartendatei, die vom Linker erstellt wird. Obwohl diese Bibliotheken am besten für die Erstellung von Fehlerberichten aus unerwarteten Ausnahmen bekannt sind, verfügen sie über alle Funktionen, die Sie benötigen.

+0

Ich habe von diesen Bibliotheken gehört, aber ich habe wirklich keine Zeit sie auszuprobieren, aber danke für die Antwort. –

+1

Nun, wenn Sie keine freie Stunde haben, um es richtig zu machen, dann nehmen Sie die schnelle Option. –

+0

Es erfordert vollständige Debug-Informationen, die Reverse-Engineering-Risiken darstellen. Ich habe immer etwas wie http://www.freepascal.org/docs-html/prog/progsu41.html#x47-460001.1.41 in Delphi verpasst. (Möglichkeiten, Datei und Leinen in die Binärdatei ohne Debuginfo aufzunehmen). Es hat jedoch den Nachteil, dass Sie es jedes Mal weitergeben müssen, wenn es verwendet wird, da es die Informationen nicht durch Abwickeln des Stapels erhalten kann. –

Verwandte Themen