View Issue Details

IDProjectCategoryView StatusLast Update
0035359FPCCompilerpublic2019-05-18 19:02
ReporterMartin FriebeAssigned ToSven Barth 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Platform64bit IntelOSwin 10OS Version10
Product Version3.0.4Product Build 
Target VersionFixed in Version3.3.1 
Summary0035359: Wrong dwarf-3 info for unicodestring
DescriptionTypeinfo (dwarf 3) for unicodestring will be (64 bit / not tested if present on 32 bit):

 <1><1b0>: Abbrev Number: 11 (DW_TAG_array_type)
    <1b1> DW_AT_name : UnicodeString
    <1bf> DW_AT_data_location: 2 byte block: 97 6 (DW_OP_push_object_address; DW_OP_deref)
    <1c2> DW_AT_type : <0x200>
 <2><1c6>: Abbrev Number: 12 (DW_TAG_subrange_type)
    <1c7> DW_AT_lower_bound : 1
    <1c8> DW_AT_upper_bound : 15 byte block: 97 6 12 28 4 0 30 2f 3 0 38 1c 6 31 25 (DW_OP_push_object_address; DW_OP_deref; DW_OP_dup; DW_OP_bra: 4; DW_OP_lit0; DW_OP_skip: 3; DW_OP_lit8; DW_OP_minus; DW_OP_deref; DW_OP_lit1; DW_OP_shr)


The unicode string stores the number of widechar in front of the string (for the string in the example that is: 4 / and I checked, that is what is in memory)

But DW_AT_upper_bound retrieves that number, and then does a DW_OP_shr => that means the debugger gets to believe there are only 2 elements.

As far as I can see the DW_OP_shr is incorrect?
Steps To Reproduceprogram Project1;

procedure test;
var
x : unicodestring;
begin
x:=copy('abc',1,2)+'12';
end;

begin
test;
end.
TagsNo tags attached.
Fixed in Revision42037
FPCOldBugId0
FPCTarget-
Attached Files
  • dbgdwarf-widestr.patch (1,044 bytes)
    diff --git a/compiler/dbgdwarf.pas b/compiler/dbgdwarf.pas
    index 25ea38a0..864a49b3 100644
    --- a/compiler/dbgdwarf.pas
    +++ b/compiler/dbgdwarf.pas
    @@ -4265,7 +4265,7 @@ implementation
               { now the information about the length of the string }
               if deref then
                 begin
    -              if (chardef.size=1) then
    +              if not is_widestring(def) then
                     upperopcodes:=13
                   else
                     upperopcodes:=15;
    @@ -4292,7 +4292,7 @@ implementation
                   current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_deref)));
     
                   { for widestrings, the length is specified in bytes, so divide by two }
    -              if (upperopcodes=15) then
    +              if not is_widestring(def) then
                     begin
                       current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_lit1)));
                       current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_shr)));
    
    dbgdwarf-widestr.patch (1,044 bytes)
  • dbgdwarf-widestr-fixed.patch (480 bytes)
    diff --git a/compiler/dbgdwarf.pas b/compiler/dbgdwarf.pas
    index 25ea38a0..864a49b3 100644
    --- a/compiler/dbgdwarf.pas
    +++ b/compiler/dbgdwarf.pas
    @@ -4265,7 +4265,7 @@ implementation
               { now the information about the length of the string }
               if deref then
                 begin
    -              if (chardef.size=1) then
    +              if not is_widestring(def) then
                     upperopcodes:=13
                   else
                     upperopcodes:=15;

Relationships

related to 0035340 closedMartin Friebe Lazarus watching of Unicodestring 
related to 0035444 resolvedMichael Van Canneyt FPC Document widestring internal 

Activities

Sven Barth

2019-04-14 20:48

manager   ~0115504

Does the attached patch solve the problem?
Does WideString (on Windows platforms) still work correctly?

Sven Barth

2019-04-18 20:43

manager  

dbgdwarf-widestr.patch (1,044 bytes)
diff --git a/compiler/dbgdwarf.pas b/compiler/dbgdwarf.pas
index 25ea38a0..864a49b3 100644
--- a/compiler/dbgdwarf.pas
+++ b/compiler/dbgdwarf.pas
@@ -4265,7 +4265,7 @@ implementation
           { now the information about the length of the string }
           if deref then
             begin
-              if (chardef.size=1) then
+              if not is_widestring(def) then
                 upperopcodes:=13
               else
                 upperopcodes:=15;
@@ -4292,7 +4292,7 @@ implementation
               current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_deref)));
 
               { for widestrings, the length is specified in bytes, so divide by two }
-              if (upperopcodes=15) then
+              if not is_widestring(def) then
                 begin
                   current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_lit1)));
                   current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_shr)));
dbgdwarf-widestr.patch (1,044 bytes)

Sven Barth

2019-04-18 20:43

manager   ~0115661

Reuploaded patch as UTF8 instead of UTF16...

Martin Friebe

2019-04-24 16:21

manager   ~0115773

The 2nd "if" is wrong. It should not have the "not".

But in any case it is best to leave it as it is "upperopcodes=15"
If the first "if" reserved 15 bytes, then the 15 bytes must be filled.

With that change it works.

About WideString. For some reason widestring are not encoded this way, but as pointer to widechar. I am testing on windows, so probably due to tf_winlikewidestring.
Still interesting, because the length of the widestring is still stored as expected.

dbgdwarf-widestr-fixed.patch (480 bytes)
diff --git a/compiler/dbgdwarf.pas b/compiler/dbgdwarf.pas
index 25ea38a0..864a49b3 100644
--- a/compiler/dbgdwarf.pas
+++ b/compiler/dbgdwarf.pas
@@ -4265,7 +4265,7 @@ implementation
           { now the information about the length of the string }
           if deref then
             begin
-              if (chardef.size=1) then
+              if not is_widestring(def) then
                 upperopcodes:=13
               else
                 upperopcodes:=15;

Martin Friebe

2019-04-24 20:54

manager   ~0115782

Is the len on widestring always in bytes?
This prints the dwords in front of each string.

On Windows, it indeed prints 10 for a widestring of len 5.
But on linux, it prints 5 for all the strings.
Tested 64 bit.

type
  p32 = ^longint;
var
  a: widestring;
  b: unicodestring;
  c: ansistring;
  d: array of char;
  e: array of WideChar;
begin
  a := copy('abcd',1,3)+'12';
  b := copy('abcd',1,3)+'12';
  c := copy('abcd',1,3)+'12';
  SetLength(d,5);
  SetLength(e,5);

  DebugLn([' ', high(LongInt), ' ',high(ptrint) ]);
  debugln(['a ', p32(a)[-1], ' ', p32(a)[-2], ' ', p32(a)[-3], ' ', p32(a)[-4], ' ' ]);
  debugln(['b ', p32(b)[-1], ' ', p32(b)[-2], ' ', p32(b)[-3], ' ', p32(b)[-4], ' ' ]);
  debugln(['c ', p32(c)[-1], ' ', p32(c)[-2], ' ', p32(c)[-3], ' ', p32(c)[-4], ' ' ]);
  debugln(['d ', p32(d)[-1], ' ', p32(d)[-2], ' ', p32(d)[-3], ' ', p32(d)[-4], ' ' ]);
  debugln(['e ', p32(e)[-1], ' ', p32(e)[-2], ' ', p32(e)[-3], ' ', p32(e)[-4], ' ' ]);

Martin Friebe

2019-04-24 21:31

manager   ~0115785

Anyway the patch seems to work for linux too (only tested 64 bit)

widestring seems to be an alias for unicodestring in this case.

Serge Anvarov

2019-04-24 21:47

reporter   ~0115786

Yes, the length field for WideString is specified in bytes.
For compatible with Delphi (http://docwiki.embarcadero.com/RADStudio/Rio/en/Internal_Data_Formats_%28Delphi%29#Wide_String_Types) and Windows BSTR type (https://msdn.microsoft.com/en-us/windows/desktop/1B2D7D2C-47AF-4389-A6B6-B01B7E915228)

Sven Barth

2019-05-11 17:39

manager   ~0116135

Please test and close if okay.

Martin Friebe

2019-05-18 19:02

manager   ~0116250

Works, thanks

Issue History

Date Modified Username Field Change
2019-04-10 23:04 Martin Friebe New Issue
2019-04-10 23:04 Martin Friebe Relationship added related to 0035340
2019-04-14 20:48 Sven Barth File Added: dbgdwarf-widestr.patch
2019-04-14 20:48 Sven Barth Note Added: 0115504
2019-04-16 11:31 Sven Barth Assigned To => Sven Barth
2019-04-16 11:31 Sven Barth Status new => feedback
2019-04-18 20:43 Sven Barth File Deleted: dbgdwarf-widestr.patch
2019-04-18 20:43 Sven Barth File Added: dbgdwarf-widestr.patch
2019-04-18 20:43 Sven Barth Note Added: 0115661
2019-04-24 16:21 Martin Friebe File Added: dbgdwarf-widestr-fixed.patch
2019-04-24 16:21 Martin Friebe Note Added: 0115773
2019-04-24 16:21 Martin Friebe Status feedback => assigned
2019-04-24 20:54 Martin Friebe Note Added: 0115782
2019-04-24 21:31 Martin Friebe Note Added: 0115785
2019-04-24 21:47 Serge Anvarov Note Added: 0115786
2019-04-25 18:22 Marco van de Voort Relationship added related to 0035444
2019-05-11 17:39 Sven Barth Status assigned => resolved
2019-05-11 17:39 Sven Barth Resolution open => fixed
2019-05-11 17:39 Sven Barth Fixed in Version => 3.3.1
2019-05-11 17:39 Sven Barth Fixed in Revision => 42037
2019-05-11 17:39 Sven Barth FPCTarget => -
2019-05-11 17:39 Sven Barth Note Added: 0116135
2019-05-18 19:02 Martin Friebe Status resolved => closed
2019-05-18 19:02 Martin Friebe Note Added: 0116250