[PATCH 2/3] gdb: Don't reorder line table entries too much when sorting.

Tom de Vries tdevries@suse.de
Fri Jun 5 14:49:17 GMT 2020


On 23-12-2019 02:51, Andrew Burgess wrote:
> I had to make a small adjustment in find_pc_sect_line in order to
> correctly find the previous line in the line table.  In some line
> tables I was seeing an actual line entry and an end of sequence marker
> at the same address, before this commit these would reorder to move
> the end of sequence marker before the line entry (end of sequence has
> line number 0).  Now the end of sequence marker remains in its correct
> location, and in order to find a previous line we should step backward
> over any end of sequence markers.
> 
> As an example, the binary:
>   gdb/testsuite/outputs/gdb.dwarf2/dw2-ranges-func/dw2-ranges-func-lo-cold
> 
> Has this line table before the patch:
> 
>   INDEX    LINE ADDRESS
>   0          48 0x0000000000400487
>   1         END 0x000000000040048e
>   2          52 0x000000000040048e
>   3          54 0x0000000000400492
>   4          56 0x0000000000400497
>   5         END 0x000000000040049a
>   6          62 0x000000000040049a
>   7         END 0x00000000004004a1
>   8          66 0x00000000004004a1
>   9          68 0x00000000004004a5
>   10         70 0x00000000004004aa
>   11         72 0x00000000004004b9
>   12        END 0x00000000004004bc
>   13         76 0x00000000004004bc
>   14         78 0x00000000004004c0
>   15         80 0x00000000004004c5
>   16        END 0x00000000004004cc
> 
> And after this patch:
> 
>   INDEX    LINE ADDRESS
>   0          48 0x0000000000400487
>   1          52 0x000000000040048e
>   2         END 0x000000000040048e
>   3          54 0x0000000000400492
>   4          56 0x0000000000400497
>   5         END 0x000000000040049a
>   6          62 0x000000000040049a
>   7          66 0x00000000004004a1
>   8         END 0x00000000004004a1
>   9          68 0x00000000004004a5
>   10         70 0x00000000004004aa
>   11         72 0x00000000004004b9
>   12        END 0x00000000004004bc
>   13         76 0x00000000004004bc
>   14         78 0x00000000004004c0
>   15         80 0x00000000004004c5
>   16        END 0x00000000004004cc
> 
> When calling find_pc_sect_line with the address 0x000000000040048e, in
> both cases we find entry #3, we then try to find the previous entry,
> which originally found this entry '2         52 0x000000000040048e',
> after the patch it finds '2         END 0x000000000040048e', which
> cases the lookup to fail.
> 
> By skipping the END marker after this patch we get back to the correct
> entry, which is now #1: '1          52 0x000000000040048e', and
> everything works again.

I start to suspect that you have been working around an incorrect line
table.

Consider this bit:
...
   0          48 0x0000000000400487
   1          52 0x000000000040048e
   2         END 0x000000000040048e
...

The end marker marks the address one past the end of the sequence.
Therefore, it makes no sense to have an entry in the sequence with the
same address as the end marker.

[ dwarf doc:

end_sequence:

A boolean indicating that the current address is that of the first byte
after the end of a sequence of target machine instructions. end_sequence
terminates a sequence of lines; therefore other information in the same
row is not meaningful.

DW_LNE_end_sequence:

The DW_LNE_end_sequence opcode takes no operands. It sets the
end_sequence register of the state machine to “true” and appends a row
to the matrix using the current values of the state-machine registers.
Then it resets the registers to the initial values specified above (see
Section 6.2.2). Every line number program sequence must end with a
DW_LNE_end_sequence instruction which creates a row whose address is
that of the byte after the last target machine instruction of the sequence.

]

The incorrect entry is generated by this dwarf assembler sequence:
...
                {DW_LNS_copy}
                {DW_LNE_end_sequence}
...

I think we should probably fix the dwarf assembly test-cases.

If we want to handle this in gdb, the thing that seems most logical to
me is to ignore this kind of entries.

Note btw that the opposite does make sense: and end marker can have the
same address as a following start-of-sequence entry.

Thanks,
- Tom


More information about the Gdb-patches mailing list