Jump to content
Wagner Landgraf

Why there is no line number in debug information (using JclDebug)

Recommended Posts

Hi all, I'm getting call stack information using JclDebug.pas, and I can't get information about line number for my own units. In the (cropped) call stack below, you can see that there is line number information for Delphi units (System.pas, for example), but not for the other units.

 

I have set several compiler and linker options, like stack frames, debug information, map debug info, etc. (see screenshot). JclDebug settings is set to raw, but changing those doesn't seem to make any difference (didn't try too hard):.

 

  JclStackTrackingOptions := [stStack, stRawMode];

 

Does anyone have any idea why it can't get line number?

 

 

(01C9E319){producao.exe} [0214F319] fpdf.TFPDF.GetStringWidth + $E5
(01C9E314){producao.exe} [0214F314] fpdf.TFPDF.GetStringWidth + $E0
(00006566){producao.exe} [004B7566] System.ErrorAt (Line 5914, "System.pas" + 3) + $4
(000065AA){producao.exe} [004B75AA] System.Error (Line 5925, "System.pas" + 1) + $7

(01C9E314){producao.exe} [0214F314] fpdf.TFPDF.GetStringWidth + $E0
(01CB8FBA){producao.exe} [02169FBA] fpdf_ext.TFPDFExt.WordWrap + $15E
(01CB9A86){producao.exe} [0216AA86] fpdf_ext.TFPDFExt.TextBox + $1A2
(01CA46AC){producao.exe} [021556AC] fpdf.TFPDF._out + $5C

...

 

image.thumb.png.c80f22d55809edc7b5a0dcfc9766beee.png

 

image.thumb.png.fb14d8ec9d4a588e4a6573e3dd55c9dc.png

 

Share this post


Link to post

In your unit, is there a debug info directive? i.e. if you have {$D-} or {$DebugInfo Off}, it will not include debug info.

Share this post


Link to post
9 hours ago, Dave Nottage said:

In your unit, is there a debug info directive? i.e. if you have {$D-} or {$DebugInfo Off}, it will not include debug info.

Debug information has nothing to do with line numbers from jcldebug. Jcldebug only uses the map file for that.

 

I'm not that familiar with the inner workings, but what works for me for debug builds is turning on stack frames, turning off inlining and optimization and creating a detailed map file.

For release builds I only use that detailed map file. That gets me the line numbers in stack traces. 

 

BUT: My experience with that is still mostly based on Delphi 2007. It's possible that it does not work for later Delphi versions.

Share this post


Link to post
17 hours ago, Dave Nottage said:

In your unit, is there a debug info directive? i.e. if you have {$D-} or {$DebugInfo Off}, it will not include debug info.

No, there isn't.

 

Share this post


Link to post
8 hours ago, dummzeuch said:

BUT: My experience with that is still mostly based on Delphi 2007. It's possible that it does not work for later Delphi versions.

If that would be the case, it would not show line number information for Delphi units, isn't it? It's "modern" DCU. 

It just looks that Delphi DCUs have some additional information that my DCUs don't have, but I don't know what that would be.

Share this post


Link to post
45 minutes ago, Wagner Landgraf said:

If that would be the case, it would not show line number information for Delphi units, isn't it? It's "modern" DCU. 

It just looks that Delphi DCUs have some additional information that my DCUs don't have, but I don't know what that would be.

Since the dcu file format is not documented, I doubt that jcldebug uses it to get line number information.

Share this post


Link to post
1 minute ago, dummzeuch said:

Since the dcu file format is not documented, I doubt that jcldebug uses it to get line number information.

Sorry, by "DCU" I mean "debug information".

Share this post


Link to post
2 hours ago, dummzeuch said:

I doubt that jcldebug uses it to get line number information.

It doesn't; It uses the map file.

Share this post


Link to post
3 hours ago, Anders Melander said:

It doesn't; It uses the map file.

And why it can't retrieve the line number from generated map files from my units, but can from Delphi units?

Share this post


Link to post
Posted (edited)

I just tested a program in Delphi 10.2 and got the following call stack:

Exception at [0092DF9A] w_SigAbout.Tf_SigAbout.Execute (Line 79, "w_SigAbout.pas"):
Test
<begin call stack>
[0092DF95] w_SigAbout.Tf_SigAbout.Execute (Line 77, "w_SigAbout.pas" + 3) + $11
[0093D548] w_AnonymisierungRestApi.Tf_AnonymisierungRestApi.act_GetProgramInfoExecute (Line 2055, "w_AnonymisierungRestApi.pas" + 1) + $8
[004D0C0B] System.Classes.TBasicAction.Execute (Line 16901, "System.Classes.pas" + 3) + $7
[0052FE8A] Vcl.ActnList.TCustomAction.Execute (Line 260, "Vcl.ActnList.pas" + 19) + $35
[004D0A77] System.Classes.TBasicActionLink.Execute (Line 16812, "System.Classes.pas" + 2) + $7
[0060339B] Vcl.Menus.TMenuItem.Click (Line 2539, "Vcl.Menus.pas" + 17) + $7
[00604AFC] Vcl.Menus.TMenu.DispatchCommand (Line 3482, "Vcl.Menus.pas" + 5) + $4
[00605D8E] Vcl.Menus.TPopupList.WndProc (Line 4655, "Vcl.Menus.pas" + 4) + $E
[00605CDD] Vcl.Menus.TPopupList.MainWndProc (Line 4630, "Vcl.Menus.pas" + 2) + $5
[004D1970] System.Classes.StdWndProc (Line 17405, "System.Classes.pas" + 8) + $0
[0061E18B] Vcl.Forms.TApplication.ProcessMessage (Line 10641, "Vcl.Forms.pas" + 23) + $1
[0061E1CE] Vcl.Forms.TApplication.HandleMessage (Line 10671, "Vcl.Forms.pas" + 1) + $4
[0061E501] Vcl.Forms.TApplication.Run (Line 10809, "Vcl.Forms.pas" + 26) + $3
[0095195D] Anonymisierung.Anonymisierung (Line 36, "" + 4) + $7
<end call stack>

As you can see there are line numbers for the system units as well as for the ones of the program.

This is from the debug build.

 

But, if I compile with the release configuration, I get the following:

Exception at [0090B884] w_SigAbout.Tf_SigAbout.Execute:
Test
<begin call stack>
[0090B87F] w_SigAbout.Tf_SigAbout.Execute + $37
[0091AC2B] w_AnonymisierungRestApi.Tf_AnonymisierungRestApi.act_GetProgramInfoExecute + $7
[004D0763] System.Classes.TBasicAction.Execute + $F
[0052F88E] Vcl.ActnList.TCustomAction.Execute + $86
[004D05CF] System.Classes.TBasicActionLink.Execute + $13
[00602D77] Vcl.Menus.TMenuItem.Click + $93
[006044D8] Vcl.Menus.TMenu.DispatchCommand + $18
[0060576A] Vcl.Menus.TPopupList.WndProc + $82
[006056B9] Vcl.Menus.TPopupList.MainWndProc + $1D
[004D14C8] System.Classes.StdWndProc + $14
[0061DB67] Vcl.Forms.TApplication.ProcessMessage + $F3
[0061DBAA] Vcl.Forms.TApplication.HandleMessage + $A
[0061DEDD] Vcl.Forms.TApplication.Run + $C9
[0092E77D] Anonymisierung.Anonymisierung + $49
<end call stack>

As you can see, there are no line numbers, neither for system units nor for the ones of the program. I could have sworn it should have worked. The configuration for the map file is identical in both.

 

If I change the configuration to use debug dcus, I get line numbers for the system units:

Exception at [0090B87C] w_SigAbout.Tf_SigAbout.Execute:
Test
<begin call stack>
[0090B877] w_SigAbout.Tf_SigAbout.Execute + $37
[0091AC23] w_AnonymisierungRestApi.Tf_AnonymisierungRestApi.act_GetProgramInfoExecute + $7
[004D075B] System.Classes.TBasicAction.Execute (Line 16901, "System.Classes.pas" + 3) + $7
[0052F886] Vcl.ActnList.TCustomAction.Execute (Line 260, "Vcl.ActnList.pas" + 19) + $35
[004D05C7] System.Classes.TBasicActionLink.Execute (Line 16812, "System.Classes.pas" + 2) + $7
[00602D6F] Vcl.Menus.TMenuItem.Click (Line 2539, "Vcl.Menus.pas" + 17) + $7
[006044D0] Vcl.Menus.TMenu.DispatchCommand (Line 3482, "Vcl.Menus.pas" + 5) + $4
[00605762] Vcl.Menus.TPopupList.WndProc (Line 4655, "Vcl.Menus.pas" + 4) + $E
[006056B1] Vcl.Menus.TPopupList.MainWndProc (Line 4630, "Vcl.Menus.pas" + 2) + $5
[004D14C0] System.Classes.StdWndProc (Line 17405, "System.Classes.pas" + 8) + $0
[0061DB5F] Vcl.Forms.TApplication.ProcessMessage (Line 10641, "Vcl.Forms.pas" + 23) + $1
[0061DBA2] Vcl.Forms.TApplication.HandleMessage (Line 10671, "Vcl.Forms.pas" + 1) + $4
[0061DED5] Vcl.Forms.TApplication.Run (Line 10809, "Vcl.Forms.pas" + 26) + $3
[0092E77D] Anonymisierung.Anonymisierung + $49
<end call stack>

If I also include debug information, I get line numbers for both, system and program units:

Exception at [0090B878] w_SigAbout.Tf_SigAbout.Execute (Line 79, "w_SigAbout.pas"):
Test
<begin call stack>
[0090B873] w_SigAbout.Tf_SigAbout.Execute (Line 77, "w_SigAbout.pas" + 3) + $11
[0091AC1F] w_AnonymisierungRestApi.Tf_AnonymisierungRestApi.act_GetProgramInfoExecute (Line 2055, "w_AnonymisierungRestApi.pas" + 0) + $7
[004D075B] System.Classes.TBasicAction.Execute (Line 16901, "System.Classes.pas" + 3) + $7
[0052F886] Vcl.ActnList.TCustomAction.Execute (Line 260, "Vcl.ActnList.pas" + 19) + $35
[004D05C7] System.Classes.TBasicActionLink.Execute (Line 16812, "System.Classes.pas" + 2) + $7
[00602D6F] Vcl.Menus.TMenuItem.Click (Line 2539, "Vcl.Menus.pas" + 17) + $7
[006044D0] Vcl.Menus.TMenu.DispatchCommand (Line 3482, "Vcl.Menus.pas" + 5) + $4
[00605762] Vcl.Menus.TPopupList.WndProc (Line 4655, "Vcl.Menus.pas" + 4) + $E
[006056B1] Vcl.Menus.TPopupList.MainWndProc (Line 4630, "Vcl.Menus.pas" + 2) + $5
[004D14C0] System.Classes.StdWndProc (Line 17405, "System.Classes.pas" + 8) + $0
[0061DB5F] Vcl.Forms.TApplication.ProcessMessage (Line 10641, "Vcl.Forms.pas" + 23) + $1
[0061DBA2] Vcl.Forms.TApplication.HandleMessage (Line 10671, "Vcl.Forms.pas" + 1) + $4
[0061DED5] Vcl.Forms.TApplication.Run (Line 10809, "Vcl.Forms.pas" + 26) + $3
[0092E77D] Anonymisierung.Anonymisierung (Line 36, "" + 4) + $7
<end call stack>

Comparing the map files shows that the Line numbers are mostly missing from the release configuration's map file. These are the line numbers for w_SigAbout from the debug build:

Line numbers for w_SigAbout(w_SigAbout.pas) segment .text

    74 0001:0050A83C    75 0001:0050A843    76 0001:0050A854    77 0001:0050A862
    79 0001:0050A878    80 0001:0050A882    82 0001:0050A89A    84 0001:0050A8AF
    89 0001:0050A8CC    90 0001:0050A8FF    91 0001:0050A910    92 0001:0050A91E
    93 0001:0050A928    94 0001:0050A933    96 0001:0050A94B    98 0001:0050A960
   107 0001:0050A98C   108 0001:0050A9C2   110 0001:0050A9CC   112 0001:0050A9D9
   113 0001:0050AA96   116 0001:0050AAAF   118 0001:0050AB98   120 0001:0050AC97
   121 0001:0050AD98   123 0001:0050ADB1   125 0001:0050ADB9   127 0001:0050ADC1
   129 0001:0050ADD8   130 0001:0050ADE0   131 0001:0050ADF2   133 0001:0050AE07
   134 0001:0050AE23   135 0001:0050AE30   136 0001:0050AE41   137 0001:0050AE4A
   138 0001:0050AE5D   139 0001:0050AE66   140 0001:0050AE6F   141 0001:0050AE78
   142 0001:0050AE91   133 0001:0050AE94   145 0001:0050AE99   146 0001:0050AEAA
   147 0001:0050AEB3   148 0001:0050AEC6   149 0001:0050AECF   150 0001:0050AED8
   156 0001:0050B0F0   157 0001:0050B108   158 0001:0050B127   159 0001:0050B13B
   160 0001:0050B13F   161 0001:0050B155   162 0001:0050B159   163 0001:0050B166
   169 0001:0050B1E0   170 0001:0050B203   171 0001:0050B211   172 0001:0050B232
   173 0001:0050B240   174 0001:0050B250   175 0001:0050B31C   176 0001:0050B32D
   178 0001:0050B346   179 0001:0050B35A   177 0001:0050B371   186 0001:0050B396
   187 0001:0050B47B   190 0001:0050B566   191 0001:0050B657   192 0001:0050B748
   193 0001:0050B839   194 0001:0050B92A   195 0001:0050BA1B   196 0001:0050BB0C
   198 0001:0050BC0A   201 0001:0050BC31   202 0001:0050BC64   203 0001:0050BD36
   204 0001:0050BD47   205 0001:0050BD57   206 0001:0050BD67   208 0001:0050BE29
   211 0001:0050C074   212 0001:0050C0B1   213 0001:0050C0C1   214 0001:0050C199
   215 0001:0050C271   216 0001:0050C349   217 0001:0050C421   218 0001:0050C4F9
   219 0001:0050C5E1   226 0001:0050C75C   227 0001:0050C762   228 0001:0050C772
   230 0001:0050C777   231 0001:0050C78C   230 0001:0050C7A1   232 0001:0050C7A4
   233 0001:0050C7C2   234 0001:0050C7C9   236 0001:0050C7D5

That section is completely missing from the release build, even though both are set to write a detailed map file.

So I guess it does matter whether the units are compiled with debug information turned on or off as apparently the linker cannot write the line numbers to the map file if the dcus do do not contain debug information. But that's not because jcldebug reads them from the dcus / executable but because the linker does.

 

Edit: I just confirmed that with an empty console application project created with File -> New -> Console Application

Turning on the detailed map file for Win32, comiling for debug and release and then comparing the map files:

There are line numbers for the debug configuration and no line numbers for the release configuration.

Turning on debug information for a unit like this:

unit Unit1;
{$D+}
interface

implementation

procedure Test;
begin
  WriteLn('bla');
end;

end.

Creates line number entries for that unit even for the release build:

Line numbers for Unit1(Unit1.pas) segment .text

    12 0001:00000000

 

Google found this:

Debug information

Generates a line-number table for each procedure that maps object-code addresses into source text line numbers. Equivalent to the {$D+} Delphi compiler directive and the -V switch for DCC32.

Default = False

http://docwiki.embarcadero.com/RADStudio/Alexandria/en/Linking

 

But turning this option on for the release build did not make any difference.

Edited by dummzeuch
  • Thanks 1

Share this post


Link to post
4 hours ago, dummzeuch said:

But turning this option on for the release build did not make any difference.

That's the mystery, isn't it?

First, thanks a lot for the detailed test.

 

So let me try to summarize what you found out: in Release config, even if you check "Debug Information" option to True (in Project Options, Building | Delphi Compiler | Linking), it doesn't generate line number, unless you explicitly add the `{$D+}` directive in the source code, is that correct?

 

If yes, I think finding out the reason might explain what's happening here.

For the record, I'm using *Debug* config, and "Debug Information" is set to True. But still, I can't get line numbers. So maybe what's happening in my Debug config is the same as it's happening in your Release config?

Share this post


Link to post
33 minutes ago, Wagner Landgraf said:

That's the mystery, isn't it?

First, thanks a lot for the detailed test.

 

So let me try to summarize what you found out: in Release config, even if you check "Debug Information" option to True (in Project Options, Building | Delphi Compiler | Linking), it doesn't generate line number, unless you explicitly add the `{$D+}` directive in the source code, is that correct?

 

If yes, I think finding out the reason might explain what's happening here.

For the record, I'm using *Debug* config, and "Debug Information" is set to True. But still, I can't get line numbers. So maybe what's happening in my Debug config is the same as it's happening in your Release config?

I suggest you make your own tests with a simple project to check how the compiler / linker options behave with regards of adding line numbers to the map file. There may be more options that affect it.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×