#1 2014-05-12 13:12:42

ComingNine
Member
Registered: 2010-07-29
Posts: 294

How to make TSynLog give "all" line numbers ?

Source code

unit Unit1;

interface

uses
  SynCommons,
  Windows, Messages, SysUtils, Variants, Classes, Graphics, 
  Controls, Forms, Dialogs;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  ILog: ISynLog;
  sl: TStringList;
begin
  with TSynLog.Family do
  begin
    Level := LOG_VERBOSE;
    PerThreadLog := ptIdentifiedInOnFile;
    RotateFileCount := 5;
    RotateFileSizeKB := 20*1024; // rotate by 20 MB logs
  end;
  ILog := TSynLog.Enter(self,'FormCreate');

  // 1
  // sl.Add(''); // <--- GPF

end;

end.

Problem description

Without the "GPF" line, the log is as below. Note the line number for FormCreate is not shown. On Page 105 of latest SAD 1.18, the line number for TestLog is shown.

20140512 14502252  +    TForm1(00762674).FormCreate
20140512 14502252  -    00.000.001

With the "GPF" line, the log is as below. Note the line number for where the exception occurs is not shown.

20140512 15083546  +    TForm1(00762674).FormCreate
20140512 15083546 EXCOS 	EAccessViolation (C0000005) at  stack trace API 0002D204 SynCommons.SynRtlUnwind (30796) 00002F6C System.@HandleAnyException (9574) 00058EFF Forms.TCustomForm.DoCreate (2648) 00058BDF Forms.TCustomForm.AfterConstruction (2576) 0006029C Forms.TApplication.CreateForm (6947) 00061D00 VCL (13) 
20140512 15083546  -    00.000.165

Settings for Delphi 7 and Delphi XE.

D7 Compiler WENCxlJ.png
D7 Linker laZBkNo.png

DXE Compiler BTdaxvD.png
DXE Linker TGm3mDK.png

Last edited by ComingNine (2014-05-12 17:11:02)

Offline

#2 2014-05-12 13:27:35

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,661
Website

Re: How to make TSynLog give "all" line numbers ?

You can enable stack frames.

Offline

#3 2014-05-12 13:32:55

ComingNine
Member
Registered: 2010-07-29
Posts: 294

Re: How to make TSynLog give "all" line numbers ?

Thank you for your help! Enable "stack frames" under "Compiler" for D7 does not help. Furthermore, "Stack frames" under "Compiler" for DXE is already enabled.

Could you help to comment ?

Offline

#4 2014-05-12 16:47:38

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,661
Website

Re: How to make TSynLog give "all" line numbers ?

Did you rebuild the whole project, after applying the settings?
wink

I just added to the MainDemo:

procedure TMainForm.FormCreate(Sender: TObject);
var P: integer;
begin
  with TSQLLog.Family do begin
    Level := LOG_VERBOSE;
    //HighResolutionTimeStamp := true;
    //RotateFileCount := 5; RotateFileSizeKB := 20*1024; // rotate by 20 MB logs
  end;
  TSQLLog.Enter;
  Ribbon.ToolBar.AddPage(nil);
{$ifdef DEBUGINTERNALSERVER}
 ...

And the log is as such when compiled with Delphi 7:

20140512 18433353  +    0018824C FileMain.TMainForm.FormCreate (295) 
20140512 18433353 EXCOS 	EAccessViolation (C0000005) at 00188257 FileMain.TMainForm.FormCreate (296)  stack trace API 0009B7D0 SynCommons.SynRtlUnwind (32164) 000022B0 System.@HandleAnyException 00078CCB Forms.TCustomForm.DoCreate 00078932 Forms.TCustomForm.Create 00080284 Forms.TApplication.CreateForm 00188824 SynFile (20) 
20140512 18433353  -    00.000.126

And with Delphi XE4 with Win32 as target platform:

20140512 18455932  +    0037BD08 FileMain.TMainForm.FormCreate (295) 
20140512 18455932 EXCOS 	EAccessViolation (C0000005) at 0037BD13 FileMain.TMainForm.FormCreate (296)  stack trace API 00227230 SynCommons.SynRtlUnwind (38253) 00009868 System.@HandleAnyException 001DF4AF Vcl.Forms.TCustomForm.DoCreate 001DF027 Vcl.Forms.TCustomForm.Create 001E9F85 Vcl.Forms.TApplication.CreateForm 
20140512 18455932  -    00.000.150

And with Delphi XE4 with Win32 as target platform:

20140512 18470549  +    00000000004B105B FileMain.TMainForm.FormCreate (295) 
20140512 18470549 EXCOS 	EAccessViolation (00000000C0000005) at 00000000004B106E FileMain.TMainForm.FormCreate (296) 
20140512 18470549  -    00.000.132

Offline

#5 2014-05-12 16:54:45

ComingNine
Member
Registered: 2010-07-29
Posts: 294

Re: How to make TSynLog give "all" line numbers ?

Oh ! Thank you very much for your help !

It seems that using TSQLLog from mORMot.pas instead of TSynLog from SynCommons.pas gives line number ! big_smile

I wonder is this by design ? Is TSynLog not to be used if one wants line numbers ?

Sorry for the misinformation !

TSynLog.Enter; gives the line number.

procedure TForm1.FormCreate(Sender: TObject);
var
  ILog: ISynLog;
begin
  with TSynLog.Family do
  begin
    Level := LOG_VERBOSE;
  end;
  TSynLog.Enter;

ILog := TSynLog.Enter(self,'FormCreate'); does not give the line number.

procedure TForm1.FormCreate(Sender: TObject);
var
  ILog: ISynLog;
begin
  with TSynLog.Family do
  begin
    Level := LOG_VERBOSE;
  end;
  ILog := TSynLog.Enter(self,'FormCreate');

I wonder if this is by design ?

Furthermore, could you help to comment about TSQLLog and TSynLog (for example, best practices) ? big_smile

Last edited by ComingNine (2014-05-12 17:06:20)

Offline

#6 2014-05-12 17:00:49

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,661
Website

Re: How to make TSynLog give "all" line numbers ?

Weird.
Both classes are the almost same - TSQLLog inherit from TSynLog, and add some more advanced JSON serialization...

{ TSQLLog }

procedure TSQLLog.CreateLogWriter;
begin
  if integer(fFamily.EchoToConsole)=0 then // force fWriter=TTextWriterEcho
    fWriter := TJSONSerializer.Create(nil,fFamily.BufferSize);
  inherited CreateLogWriter;
  fWriter.Stream := fWriterStream;
end;

But no change about line numbers AFAIK.

In fact, TSQLog is to be used when you link mORMot.pas in your application.
Or, to be more precise, not directly the class, but the following SQLite3Log global variable:

var
  /// TSQLLog class is used for logging for all our ORM related functions
  // - this global variable can be used to customize it
  SQLite3Log: TSynLogClass = TSQLLog;

Offline

#7 2014-05-12 17:09:10

ComingNine
Member
Registered: 2010-07-29
Posts: 294

Re: How to make TSynLog give "all" line numbers ?

Thank you for your knowledgeable comments on TSQLLog and TSynLog !

About the line number, please see my previous post with correct information ... big_smile

Offline

#8 2014-05-12 17:12:58

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,661
Website

Re: How to make TSynLog give "all" line numbers ?

On my computer:

procedure TMainForm.FormCreate(Sender: TObject);
var P: integer;
  ILog: ISynLog;
begin
  with TSynLog.Family do
  begin
    Level := LOG_VERBOSE;
  end;
  ILog := TSynLog.Enter;
  ....

in fact DOES show the line number!
sad

I do not understand what's wrong here!

Perhaps check your .map file content...

Offline

#9 2014-05-12 17:21:27

ComingNine
Member
Registered: 2010-07-29
Posts: 294

Re: How to make TSynLog give "all" line numbers ?

Thank you for your time !

Now, it seems to me that TSynLog.Enter; and ILog := TSynLog.Enter; gives line number, but ILog := TSynLog.Enter(self,'FormCreate'); does not. Could you help to comment ... big_smile

Offline

#10 2014-05-12 18:03:41

ComingNine
Member
Registered: 2010-07-29
Posts: 294

Re: How to make TSynLog give "all" line numbers ?

Further observations with Delphi 7, "Compiler"->"Use Debug DCUs" and "Stack frames", "Linker"->"Detailed Map" and "TD32", XXXLog.Enter without parameters :

Could you help to comment on the different behaviors ?

1. For MainDemo
(1) You have used the line below to trigger an exception. The line number can indeed be recorded, whether "Compiler"->"Optimization" is on or off...

 Ribbon.ToolBar.AddPage(nil); 

Could you use an uninitialized TStringList to trigger the exception (shown as below) ? I have tried and the line number of the exception cannot be recorded, whether "Compiler"->"Optimization" is on or off...

 var sl: TStringList; 
...
sl.Add('')

2. For an simple Console project, source code shown as below, the line number of the method and the exception can be recorded, whether "Compiler"->"Optimization" is on or off.

program Console;

{$APPTYPE CONSOLE}

uses
  SynCommons, Classes, SysUtils;

var sl: TStringList;
begin
  TSynLog.Family.Level := LOG_VERBOSE;
  TSynLog.Enter;

  sl.Add('');
end.

3. For an simple VCL project where everything happens in FormCreate, source code shown as below, the line number of the method and the exception can be recorded, only when the "Compiler"->"Optimization" is off. Furthermore, when the "Compiler"->"Optimization" is on, the with statement has to be used instead of the line above it, otherwise no method or exception will be recorded.

procedure TForm1.FormCreate(Sender: TObject);
var  sl: TStringList;
begin
  // TSynLog.Family.Level := LOG_VERBOSE;
  with TSynLog.Family do begin Level := LOG_VERBOSE; end;
  
  TSynLog.Enter;

  sl.Add('');
end;

Last edited by ComingNine (2014-05-12 18:15:43)

Offline

Board footer

Powered by FluxBB