Link to home
Start Free TrialLog in
Avatar of HARMPIER
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
 
Avatar of Mohammed Nasman
Mohammed Nasman
Flag of Palestine, State of image

Hello

  Try MadExecpt it's free for non-commercial use.
http://www.madshi.net
Avatar of sfock
sfock

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.OutputDebugString(output);
end;

constructor TDdbgOutput.create(FilePathName: String);
begin
  if not FileExists(FilePathName) then
     FileClose(FileCreate(FilePathName));
  FStream := TFileStream.Create(FilePathName, fmOpenWrite     or fmShareDenyWrite);
  FStream.Seek(0,soFromEnd);
end;

function TDdbgOutput.DebugOutput(output: String) : string;
var
  o: String;
begin
  Result := '';
  o := #13#10 +TimeToStr(now)+
    ' TID:'+IntToStr(GetCurrentThreadID)+
    ' PID:'+IntToStr(GetCurrentProcessId)+' '+
  output;
  Result := o;
  FStream.Write(o[1],length(o));
end;

destructor TDdbgOutput.Destroy;
begin
  FreeAndNil(FStream);
  inherited;
end;

class function TDdbgOutput.OutputDebugString(output: String) : string;
begin
  Result := '';
  try
    Result := theMainDebugOutput.DebugOutput(output);
  except
    on E: Exception do
    begin
      Result := 'not possible exception occured : ' + e.ClassName+'-->'+e.Message;
    end; // Don'T allow any Exception here!
  end;
end;

initialization
  CreateDir(LogBasePath);
  theMainDebugOutput := TDdbgOutput.create(LogBasePath+'Debug.out');
  theMainDebugOutput.DebugOutput('-------STARTED Application------'#13#10);

finalization
  theMainDebugOutput.DebugOutput('-------ENDED Application------'#13#10);
  FreeAndNil(theMainDebugOutput);
end.
Avatar of HARMPIER

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.
ASKER CERTIFIED SOLUTION
Avatar of sfock
sfock

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I forgot to set the right set of options in the jclStackTrackingOptions variable.

Now all works well.

Thanks a lot.

Pierre.
you're welcome :-)