에 대한 스택 트레이스를 얻기 위해 노력 :델파이 - 나는 로그 파일에 모든 예외를 기록 예외 로거가 예외
class function TLogger.LogException (ACaller: String; E: Exception): Boolean;
var
LogFilename, tmp: string;
LogFile: TextFile;
appsettings: TApplicationSettings;
begin
// prepare log file
appsettings:=TApplicationSettings.Create;
try
tmp:=appsettings.ErrorLogsLocation;
finally
FreeAndNil(appsettings);
end;
if NOT (DirectoryExists(tmp)) then
CreateDir(tmp);
//We create a new log file for every day to help with file size issues
LogFilename:=IncludeTrailingPathDelimiter (tmp) + 'LJErrors_' + FormatDateTime('yyyy-mm-dd', Now) +'.log';
try
AssignFile (LogFile, LogFilename);
if FileExists (LogFilename) then
Append (LogFile) // open existing file
else
Rewrite (LogFile); // create a new one
// write to the file and show error
Writeln(LogFile, CRLF+CRLF);
Writeln (LogFile, 'Application Path: ' + ExtractFilePath(ParamStr (0)));
Writeln (LogFile, 'Application Version: ' + TUtility.GetAppVersionString);
Writeln (LogFile, 'Operating System: ' + TUtility.GetOSInfo);
Writeln (LogFile, 'Error occurred at: ' + FormatDateTime ('dd-mmm-yyyy hh:nn:ss AM/PM', Now));
Writeln (LogFile, 'Logged By: ' + ACaller);
Writeln (LogFile, 'Unit Name: ' + E.UnitName);
Writeln (LogFile, 'Error Message: ' + E.Message);
Writeln (LogFile, 'Error Class: ' + E.ClassName);
Writeln (LogFile, 'Base Exception Error: ' + E.BaseException.Message);
Writeln (LogFile, 'Base Exception Class: ' + E.BaseException.ClassName);
Writeln (LogFile, 'Stack Trace: ' + E.StackTrace);
Result:=True;
finally
// close the file
CloseFile (LogFile);
end;
end;
가 Exception.StackTrace
을 사용하려면에 설명 된대로 내가 JCLDebug을 사용하고 있습니다 : https://blog.gurock.com/working-with-delphis-new-exception-stacktrace.
컴파일 : 내가 프로젝트 옵션에서 다음 옵션 활성화
unit StackTrace;
interface
uses
SysUtils, Classes, JclDebug;
implementation
function GetExceptionStackInfoProc(P: PExceptionRecord): Pointer;
var
LLines: TStringList;
LText: String;
LResult: PChar;
begin
LLines := TStringList.Create;
try
JclLastExceptStackListToStrings(LLines, True, True, True, True);
LText := LLines.Text;
LResult := StrAlloc(Length(LText));
StrCopy(LResult, PChar(LText));
Result := LResult;
finally
LLines.Free;
end;
end;
function GetStackInfoStringProc(Info: Pointer): string;
begin
Result := string(PChar(Info));
end;
procedure CleanUpStackInfoProc(Info: Pointer);
begin
StrDispose(PChar(Info));
end;
initialization
// Start the Jcl exception tracking and register our Exception
// stack trace provider.
if JclStartExceptionTracking then
begin
Exception.GetExceptionStackInfoProc := GetExceptionStackInfoProc;
Exception.GetStackInfoStringProc := GetStackInfoStringProc;
Exception.CleanUpStackInfoProc := CleanUpStackInfoProc;
end;
finalization
// Stop Jcl exception tracking and unregister our provider.
if JclExceptionTrackingActive then
begin
Exception.GetExceptionStackInfoProc := nil;
Exception.GetStackInfoStringProc := nil;
Exception.CleanUpStackInfoProc := nil;
JclStopExceptionTracking;
end;
end.
디버그 정보, 현지 기호, 기호 참조 정보, 사용 디버그 .dcus은 사용 데이터 참조를
연결 중 수입 : 디버그 정보
그러나 예외를 트리거하면 GetExceptionStackInfoProc
이 실행 되더라도 Exception.StackInfo
은 항상 빈 문자열입니다. 내가 누락 된 부분에 대한 아이디어가 있습니까?
업데이트 20170504 : 솔루션에 대한 Stefan Glienke에게 감사드립니다. 당신이 할 수있는 인스턴스에
TJclStackInfoList.Create(True, 7, p.ExceptAddr, False, nil, nil);
: 당신은 스스로 (무료로) 만들 필요가
function GetExceptionStackInfoProc(P: PExceptionRecord): Pointer;
var
LLines: TStringList;
LText: String;
LResult: PChar;
jcl_sil: TJclStackInfoList;
begin
LLines := TStringList.Create;
try
jcl_sil:=TJclStackInfoList.Create(True, 7, p.ExceptAddr, False, nil, nil);
try
jcl_sil.AddToStrings(LLines, true, true, true, true);
finally
FreeAndNil(jcl_sil);
end;
LText := LLines.Text;
LResult := StrAlloc(Length(LText));
StrCopy(LResult, PChar(LText));
Result := LResult;
finally
LLines.Free;
end;
end;
감사합니다. @stefanglienke -이 작품! 파일 크기를 최소로 유지하면서 배포 (prod) exe에이 기능을 포함시킬 수있는 방법에 대한 권장 사항이 있습니까 (예 : 동일한 출력을 얻기 위해 프로젝트 옵션에서 설정하는 최소한의 플래그는 무엇입니까?). – Rohit