Hi, Attached is a simple console application that outputs a hierarchy of log information. Under Delphi 7 we used to use a TInterfacedObject descendant to track the call stack. This same trick was very handy for changing and restoring the mouse cursor too.
When you create an instance it logs entry information, and increased the indentation level. When that interface instance went out of scope in decreased the indentation level and logs exit information. Unfortunately this doesn't have the same affect under FPC (tested with Windows and Linux). The problem is that under FPC, the Interface instances immediately goes out of scope. It seems Delphi held on to that instance even though you did not store it in a variable. Once the current procedure/method is complete, then only the Interface instance went out of scope. Why do I need this: ------------------- * Delphi compatibility of course ;-) * Due to the bad state of debugging under FPC[*] I am implementing (actually just extending the thread cached log-to-gui class of tiOPF) to recreated a product similar to Raize Components's CodeSite product. http://www.raize.com/DevTools/CodeSite/Default.asp http://www.ackerson.us/AckersonSoftware/Dev/CodeSite/CodeSiteEx/method_tracing.html * Allows for easier profiling like in 'fpprofiler' project. The CodeSiteEx product does this as well. http://www.ackerson.us/AckersonSoftware/Dev/CodeSite/CodeSiteEx/timer.html Can anybody shed some light on why this doesn't work in FPC, and if it is possible to make FPC delphi-compatible in this regard? Delphi 7 app output: -------------------------------------- Y:\tests\logger>Project1 >> Main Here I am >> TryMe i = 42 42 is the answer to everything << TryMe We are reaching the end << Main -------------------------------------- FPC 2.4.3 (Linux) app output: -------------------------------------- logger $ ./Project1 >> Main << Main Here I am >> TryMe << TryMe i = 42 42 is the answer to everything We are reaching the end -------------------------------------- FPC 2.4.3 (Windows) app output: -------------------------------------- Y:\tests\logger>project1 >> Main << Main Here I am >> TryMe << TryMe i = 42 42 is the answer to everything We are reaching the end -------------------------------------- Footnotes: [*] - Inconsistent results between FPC+GDB under 32-bit and 64-bit environments. - DbugIntf unit can't keep up to fast logging under Windows, and simply looses debug information - Can't debug expressions via GDB - Can't debug something as simple as AnsiString's under GDB. - Can't debug a character index into a ansistring with GDB. ...the list goes one... Regards, - Graeme - -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://opensoft.homeip.net:8080/fpgui/
program Project1; {$H+} {$IFDEF FPC} {$Mode ObjFPC} {$ELSE} {$APPTYPE CONSOLE} {$ENDIF} uses SysUtils, StrUtils; type TMethodLogger = class(TInterfacedObject) private FName: string; public constructor Create(const AName: string); destructor Destroy; override; end; var uIndent: integer = 0; function LogMethod(const AName: string): IInterface; begin Result := TMethodLogger.Create(AName); end; procedure Log(const AText: string); var s: string; begin s := DupeString(' ', uIndent); writeln(s + AText); end; procedure TryMe(i: integer); begin LogMethod('TryMe'); Log(Format('i = %d', [i])); Log(Format('%d is the answer to everything', [i])); end; { TMethodLogger } constructor TMethodLogger.Create(const AName: string); var s: string; begin inherited Create; FName := AName; s := DupeString(' ', uIndent); writeln(s + '>> ' + FName); inc(uIndent, 2); end; destructor TMethodLogger.Destroy; var s: string; begin dec(uIndent, 2); s := DupeString(' ', uIndent); writeln(s + '<< ' + FName); inherited; end; begin LogMethod('Main'); Log('Here I am'); TryMe(42); Log('We are reaching the end'); end.
_______________________________________________ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel