HARMPIER
asked on
Exception handler (Callstack like)
Hi,
Does anybody know if their is a easy way to retreive and save debugging informations (i.e Callstack info) when an application crashes ??
I have to develop it by myself and do not use "external" components.
Thanks a lot.
HarmPier
Does anybody know if their is a easy way to retreive and save debugging informations (i.e Callstack info) when an application crashes ??
I have to develop it by myself and do not use "external" components.
Thanks a lot.
HarmPier
to retrieve the callstack information i'd use the JCL (Jedi Code Library) wich is not a component set.
You can download it at http://www.delphi-jedi.org
As an example on how to get the info's look at this tread
https://www.experts-exchange.com/questions/20522255/Jedi-Code-Library-Runtime-Call-Stack.html
at last the storage:
create a new unit lets say myDebug and add code like the following:
unit myDebug;
interface
uses classes;
type
TDdbgOutput = class(TObject)
private
FStream: TFileStream;
public
constructor create(FilePathName: String);
Destructor Destroy; override;
function DebugOutput(output: String) : string; overload;
class function OutputDebugString(output: String) : string;
end;
function OutputDebugString(output: String) : string;
implementation
uses
SysUtils, JCLDebug, JCLSynch, Windows, COMObj;
var
theMainDebugOutput : TDdbgOutput;
LogBasePath : String;
function OutputDebugString(output: String) : string;
begin
Result := TDdbgOutput.OutputDebugStr ing(output );
end;
constructor TDdbgOutput.create(FilePat hName: String);
begin
if not FileExists(FilePathName) then
FileClose(FileCreate(FileP athName));
FStream := TFileStream.Create(FilePat hName, fmOpenWrite or fmShareDenyWrite);
FStream.Seek(0,soFromEnd);
end;
function TDdbgOutput.DebugOutput(ou tput: String) : string;
var
o: String;
begin
Result := '';
o := #13#10 +TimeToStr(now)+
' TID:'+IntToStr(GetCurrentT hreadID)+
' PID:'+IntToStr(GetCurrentP rocessId)+ ' '+
output;
Result := o;
FStream.Write(o[1],length( o));
end;
destructor TDdbgOutput.Destroy;
begin
FreeAndNil(FStream);
inherited;
end;
class function TDdbgOutput.OutputDebugStr ing(output : String) : string;
begin
Result := '';
try
Result := theMainDebugOutput.DebugOu tput(outpu t);
except
on E: Exception do
begin
Result := 'not possible exception occured : ' + e.ClassName+'-->'+e.Messag e;
end; // Don'T allow any Exception here!
end;
end;
initialization
CreateDir(LogBasePath);
theMainDebugOutput := TDdbgOutput.create(LogBase Path+'Debu g.out');
theMainDebugOutput.DebugOu tput('---- ---STARTED Application------'#13#10);
finalization
theMainDebugOutput.DebugOu tput('---- ---ENDED Application------'#13#10);
FreeAndNil(theMainDebugOut put);
end.
You can download it at http://www.delphi-jedi.org
As an example on how to get the info's look at this tread
https://www.experts-exchange.com/questions/20522255/Jedi-Code-Library-Runtime-Call-Stack.html
at last the storage:
create a new unit lets say myDebug and add code like the following:
unit myDebug;
interface
uses classes;
type
TDdbgOutput = class(TObject)
private
FStream: TFileStream;
public
constructor create(FilePathName: String);
Destructor Destroy; override;
function DebugOutput(output: String) : string; overload;
class function OutputDebugString(output: String) : string;
end;
function OutputDebugString(output: String) : string;
implementation
uses
SysUtils, JCLDebug, JCLSynch, Windows, COMObj;
var
theMainDebugOutput : TDdbgOutput;
LogBasePath : String;
function OutputDebugString(output: String) : string;
begin
Result := TDdbgOutput.OutputDebugStr
end;
constructor TDdbgOutput.create(FilePat
begin
if not FileExists(FilePathName) then
FileClose(FileCreate(FileP
FStream := TFileStream.Create(FilePat
FStream.Seek(0,soFromEnd);
end;
function TDdbgOutput.DebugOutput(ou
var
o: String;
begin
Result := '';
o := #13#10 +TimeToStr(now)+
' TID:'+IntToStr(GetCurrentT
' PID:'+IntToStr(GetCurrentP
output;
Result := o;
FStream.Write(o[1],length(
end;
destructor TDdbgOutput.Destroy;
begin
FreeAndNil(FStream);
inherited;
end;
class function TDdbgOutput.OutputDebugStr
begin
Result := '';
try
Result := theMainDebugOutput.DebugOu
except
on E: Exception do
begin
Result := 'not possible exception occured : ' + e.ClassName+'-->'+e.Messag
end; // Don'T allow any Exception here!
end;
end;
initialization
CreateDir(LogBasePath);
theMainDebugOutput := TDdbgOutput.create(LogBase
theMainDebugOutput.DebugOu
finalization
theMainDebugOutput.DebugOu
FreeAndNil(theMainDebugOut
end.
ASKER
sfock,
I downloaded a version of the JCL and used it as you shown in the previous ExpertExchange query.
But I have some problems when I try to retreive debbuging information i.e. the function MapOfAddr doesn't return any information, the function JCLLastExceptFrameList always return NIL.
I think that I don't set the right compiler or linker option.
Do you know which options I must use ??
Thanks.
I downloaded a version of the JCL and used it as you shown in the previous ExpertExchange query.
But I have some problems when I try to retreive debbuging information i.e. the function MapOfAddr doesn't return any information, the function JCLLastExceptFrameList always return NIL.
I think that I don't set the right compiler or linker option.
Do you know which options I must use ??
Thanks.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I forgot to set the right set of options in the jclStackTrackingOptions variable.
Now all works well.
Thanks a lot.
Pierre.
Now all works well.
Thanks a lot.
Pierre.
you're welcome :-)
Try MadExecpt it's free for non-commercial use.
http://www.madshi.net