[Bug symtab/26243] New: Handle line number 0 in line table produced by clang

classic Classic list List threaded Threaded
19 messages Options
Reply | Threaded
Open this post in threaded view
|

[Bug symtab/26243] New: Handle line number 0 in line table produced by clang

Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26243

            Bug ID: 26243
           Summary: Handle line number 0 in line table produced by clang
           Product: gdb
           Version: HEAD
            Status: NEW
          Severity: normal
          Priority: P2
         Component: symtab
          Assignee: unassigned at sourceware dot org
          Reporter: vries at gcc dot gnu.org
  Target Milestone: ---

Created attachment 12701
  --> https://sourceware.org/bugzilla/attachment.cgi?id=12701&action=edit
test.cpp

Consider attached test-case test.cpp, compiled like this:
...
$ clang++ --version
clang version 10.0.0
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
$ clang++ -g -O0 test.cpp
...

[ FTR, it executes like this:
...
$ ./a.out
20 23 25 26 28 30 35 60 64 65 68 70
... ]

The following debug session derails after line 53:
...
$ gdb a.out
Reading symbols from a.out...
(gdb) b inorder
Breakpoint 1 at 0x400c40: file test.cpp, line 44.
(gdb) r
Starting program: a.out

Breakpoint 1, inorder (root=0x6031f0 <node_array>) at test.cpp:44
44        std::vector<node *> todo;
(gdb) n
45        todo.push_back(root);
(gdb)
46        while (!todo.empty()){
(gdb)
47          node *curr = todo.back();
(gdb)
48          todo.pop_back();
(gdb)
49          if (curr->visited) {
(gdb)
52            curr->visited = true;
(gdb)
53            if (curr->right) { todo.push_back(curr->right); }
(gdb)
0x0000000000400d1d in inorder (root=0x6031f0 <node_array>)
(gdb)
Single stepping until exit from function _Z7inorderP4node,
which has no line number information.
main (argc=1, argv=0x7fffffffdce8) at test.cpp:77
77        std::cout <<  "\n";
...

In contrast, with gdb 8.3.1, we have:
...
$ gdb a.out
Reading symbols from a.out...
(gdb) b inorder
Breakpoint 1 at 0x400c40: file test.cpp, line 44.
(gdb) r
Starting program: a.out

Breakpoint 1, inorder (root=0x6031f0 <node_array>) at test.cpp:44
44        std::vector<node *> todo;
(gdb) n
45        todo.push_back(root);
(gdb)
46        while (!todo.empty()){
(gdb)
47          node *curr = todo.back();
(gdb)
48          todo.pop_back();
(gdb)
49          if (curr->visited) {
(gdb)
52            curr->visited = true;
(gdb)
53            if (curr->right) { todo.push_back(curr->right); }
(gdb)
54            todo.push_back(curr);
(gdb)
55            if (curr->left) { todo.push_back(curr->left); }
(gdb)
46        while (!todo.empty()){
(gdb)
47          node *curr = todo.back();
...

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug symtab/26243] Handle line number 0 in line table produced by clang

Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26243

--- Comment #1 from Tom de Vries <vries at gcc dot gnu.org> ---
The inorder function runs from 400c30 to 400d80:
...
0000000000400c30 <_Z7inorderP4node>:
  400c30:       55                      push   %rbp
  400c31:       48 89 e5                mov    %rsp,%rbp
  ...
  400d79:       e8 42 fc ff ff          callq  4009c0 <_Unwind_Resume@plt>
  400d7e:       66 90                   xchg   %ax,%ax

0000000000400d80 <main>:
  400d80:       55                      push   %rbp
...
and has the following line table (skipping test.cpp for each entry):
...
      Line number    Starting address    View    Stmt
               43            0x400c30               x
               44            0x400c40               x
               45            0x400c54               x
               46            0x400c5e               x
               46            0x400c63        
               46            0x400c6c        
               46            0x400c6e        
               47            0x400c7b               x
               47            0x400c87        
               48            0x400c8b               x
               49            0x400c94               x
               49            0x400c98        
               50            0x400ca2               x
               50            0x400ca6        
               50            0x400ca8        
               50            0x400cbb        
               51            0x400cce               x
               58            0x400cd3               x
               52            0x400ce8               x
               52            0x400cec        
               53            0x400cf0               x
               53            0x400cf9        
               53            0x400cff        
               53            0x400d03        
               53            0x400d0b        
               53            0x400d18        
                0            0x400d1d        
               54            0x400d25               x
               55            0x400d2f               x
               55            0x400d38        
               55            0x400d3e        
               55            0x400d42        
               55            0x400d4a        
               55            0x400d57        
                0            0x400d5c        
               46            0x400d61               x
               58            0x400d66               x
               61            0x400d80               x
...

With gdb 8.3.1, the 0 line number entries are filtered out, because is_stmt ==
0 for those entries:
...
$ gdb -batch a.out -ex "maint expand-symtabs test.cpp" -ex "maint info
line-table"
INDEX    LINE ADDRESS
21         43 0x0000000000400c30
22         44 0x0000000000400c40
23         45 0x0000000000400c54
24         46 0x0000000000400c5e
25         47 0x0000000000400c7b
26         48 0x0000000000400c8b
27         49 0x0000000000400c94
28         50 0x0000000000400ca2
29         51 0x0000000000400cce
30         58 0x0000000000400cd3
31         52 0x0000000000400ce8
32         53 0x0000000000400cf0
33         54 0x0000000000400d25
34         55 0x0000000000400d2f
35         46 0x0000000000400d61
36         58 0x0000000000400d66
37         61 0x0000000000400d80
...

But with current gdb, that's no longer the case:
...
INDEX  LINE   ADDRESS            IS-STMT
50     43     0x0000000000400c30 Y
51     44     0x0000000000400c40 Y
52     45     0x0000000000400c54 Y
53     46     0x0000000000400c5e Y
54     46     0x0000000000400c63  
55     46     0x0000000000400c6c  
56     46     0x0000000000400c6e  
57     47     0x0000000000400c7b Y
58     47     0x0000000000400c87  
59     48     0x0000000000400c8b Y
60     49     0x0000000000400c94 Y
61     49     0x0000000000400c98  
62     50     0x0000000000400ca2 Y
63     50     0x0000000000400ca6  
64     50     0x0000000000400ca8  
65     50     0x0000000000400cbb  
66     51     0x0000000000400cce Y
67     58     0x0000000000400cd3 Y
68     52     0x0000000000400ce8 Y
69     52     0x0000000000400cec  
70     53     0x0000000000400cf0 Y
71     53     0x0000000000400cf9  
72     53     0x0000000000400cff  
73     53     0x0000000000400d03  
74     53     0x0000000000400d0b  
75     53     0x0000000000400d18  
76     END    0x0000000000400d1d  
77     54     0x0000000000400d25 Y
78     55     0x0000000000400d2f Y
79     55     0x0000000000400d38  
80     55     0x0000000000400d3e  
81     55     0x0000000000400d42  
82     55     0x0000000000400d4a  
83     55     0x0000000000400d57  
84     END    0x0000000000400d5c  
85     46     0x0000000000400d61 Y
86     58     0x0000000000400d66 Y
87     61     0x0000000000400d80 Y
...

The line 0 entries are represented here as "END" or end-of-sequence, because
that's the semantics of line number 0 internally in GDB.

So, the question is: what is the semantics of a line 0 entry in a .debug_line
table?  The dwarf standard does not give it any special meaning.

In the llvm source code, we find in
./include/llvm/DebugInfo/DWARF/DWARFDebugLine.h:
...
    /// An unsigned integer indicating a source line number. Lines are numbered
    /// beginning at 1. The compiler may emit the value 0 in cases where an    
    /// instruction cannot be attributed to any source line.                    
    uint32_t Line;
...

So, apparently clang/llvm decided on this semantics.

The easiest thing to do seems to be ignore this entry during reading:
...
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 558fad74f8..0bbd04b84f 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -20300,8 +20300,9 @@ lnp_state_machine::record_line (bool end_sequence)
          bool file_changed
            = m_last_subfile != m_cu->get_builder ()->get_current_subfile ();
          bool ignore_this_line
-           = (file_changed && !end_sequence && m_last_address == m_address
-              && !m_is_stmt && m_stmt_at_address);
+           = ((file_changed && !end_sequence && m_last_address == m_address
+               && !m_is_stmt && m_stmt_at_address)
+              || (!end_sequence && m_line == 0));

          if ((file_changed && !ignore_this_line) || end_sequence)
            {
...
such that we have line table:
...
47     43     0x0000000000400c30 Y
48     44     0x0000000000400c40 Y
49     45     0x0000000000400c54 Y
50     46     0x0000000000400c5e Y
51     46     0x0000000000400c63  
52     46     0x0000000000400c6c  
53     46     0x0000000000400c6e  
54     47     0x0000000000400c7b Y
55     47     0x0000000000400c87  
56     48     0x0000000000400c8b Y
57     49     0x0000000000400c94 Y
58     49     0x0000000000400c98  
59     50     0x0000000000400ca2 Y
60     50     0x0000000000400ca6  
61     50     0x0000000000400ca8  
62     50     0x0000000000400cbb  
63     51     0x0000000000400cce Y
64     58     0x0000000000400cd3 Y
65     52     0x0000000000400ce8 Y
66     52     0x0000000000400cec  
67     53     0x0000000000400cf0 Y
68     53     0x0000000000400cf9  
69     53     0x0000000000400cff  
70     53     0x0000000000400d03  
71     53     0x0000000000400d0b  
72     53     0x0000000000400d18  
73     54     0x0000000000400d25 Y
74     55     0x0000000000400d2f Y
75     55     0x0000000000400d38  
76     55     0x0000000000400d3e  
77     55     0x0000000000400d42  
78     55     0x0000000000400d4a  
79     55     0x0000000000400d57  
80     46     0x0000000000400d61 Y
81     58     0x0000000000400d66 Y
82     61     0x0000000000400d80 Y
...
and we get the same debug session as with gdb 8.3.1.

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug symtab/26243] Handle line number 0 in line table produced by clang

Sourceware - gdb-prs mailing list
In reply to this post by Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26243

--- Comment #2 from Tom de Vries <vries at gcc dot gnu.org> ---
This behaviour appears to be a recent regression by commit d8cc8af6a1
"[gdb/symtab] Fix line-table end-of-sequence sorting", caused by the part of
the patch that reverts this bit that was introduced by commit 3d92a3e313 "gdb:
Don't reorder line table entries too much when sorting":
...
diff --git a/gdb/symtab.c b/gdb/symtab.c
index d5ba249ced..f456f4d852 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -3222,7 +3222,12 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section
*section, i
nt notcurrent)
       struct linetable_entry *last = item + len;
       item = std::upper_bound (first, last, pc, pc_compare);
       if (item != first)
-       prev = item - 1;                /* Found a matching item.  */
+       {
+         /* Found a matching item.  Skip backwards over any end of
+            sequence markers.  */
+         for (prev = item - 1; prev->line == 0 && prev != first; prev--)
+           /* Nothing.  */;
+       }

       /* At this point, prev points at the line whose start addr is <= pc, and
          item points at the next line.  If we ran off the end of the linetable
...

But the root cause is that clang/llvm style line number zero entries are just
not handled by gdb.

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug symtab/26243] Handle line number 0 in line table produced by clang

Sourceware - gdb-prs mailing list
In reply to this post by Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26243

--- Comment #3 from Tom de Vries <vries at gcc dot gnu.org> ---
(In reply to Tom de Vries from comment #1)

> The line 0 entries are represented here as "END" or end-of-sequence, because
> that's the semantics of line number 0 internally in GDB.
>
> So, the question is: what is the semantics of a line 0 entry in a
> .debug_line table?  The dwarf standard does not give it any special meaning.
>
> In the llvm source code, we find in
> ./include/llvm/DebugInfo/DWARF/DWARFDebugLine.h:
> ...
>     /// An unsigned integer indicating a source line number. Lines are
> numbered              
>     /// beginning at 1. The compiler may emit the value 0 in cases where an
>
>     /// instruction cannot be attributed to any source line.                
>
>     uint32_t Line;
> ...
>
> So, apparently clang/llvm decided on this semantics.
>

Correction.  I found it in the dwarf standard:
...
line:

An unsigned integer indicating a source line
number. Lines are numbered beginning at 1.
The compiler may emit the value 0 in cases
where an instruction cannot be attributed to any
source line.
...

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug symtab/26243] Handle line number 0 in line table produced by clang

Sourceware - gdb-prs mailing list
In reply to this post by Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26243

Andrew Burgess <andrew.burgess at embecosm dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrew.burgess at embecosm dot com

--- Comment #4 from Andrew Burgess <andrew.burgess at embecosm dot com> ---
Ignoring line number 0 while parsing is probably not the right answer.  If we
do that then instruction associated with line 0 will instead be associated with
the preceding line number.

This probably indicates that we should pick some other value for the end
marker, -1 is probably safe enough, or given we now already carry a single bit
flag for is-stmt, we could/should just add a separate flag for is-end.

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug symtab/26243] Handle line number 0 in line table produced by clang

Sourceware - gdb-prs mailing list
In reply to this post by Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26243

--- Comment #5 from Tom de Vries <vries at gcc dot gnu.org> ---
(In reply to Andrew Burgess from comment #4)
> Ignoring line number 0 while parsing is probably not the right answer.  If
> we do that then instruction associated with line 0 will instead be
> associated with the preceding line number.

Indeed, I found a scenario where this would make a difference: ni-stepping
through line 53.

With trunk I get:
...
(gdb)
0x0000000000400d13      53            if (curr->right) {
todo.push_back(curr->right); }
(gdb)
0x0000000000400d18      53            if (curr->right) {
todo.push_back(curr->right); }
(gdb)
0x0000000000400d1d in inorder (root=0x6031f0 <node_array>)
(gdb)
0x0000000000400d21 in inorder (root=0x6031f0 <node_array>)
(gdb)
...

But with the patch from comment 1, we have instead:
...
(gdb)
0x0000000000400d13      53            if (curr->right) {
todo.push_back(curr->right); }
(gdb)
0x0000000000400d18      53            if (curr->right) {
todo.push_back(curr->right); }
(gdb)
0x0000000000400d1d      53            if (curr->right) {
todo.push_back(curr->right); }
(gdb)
0x0000000000400d21      53            if (curr->right) {
todo.push_back(curr->right); }
(gdb)
...

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug symtab/26243] Handle line number 0 in line table produced by clang

Sourceware - gdb-prs mailing list
In reply to this post by Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26243

--- Comment #6 from Tom de Vries <vries at gcc dot gnu.org> ---
(In reply to Tom de Vries from comment #5)
> (In reply to Andrew Burgess from comment #4)
> > Ignoring line number 0 while parsing is probably not the right answer.  If
> > we do that then instruction associated with line 0 will instead be
> > associated with the preceding line number.
>

Hmm, I think we probably want the "ignore line number 0" approach for gdb 10,
to fix the regression in behaviour compared to gdb 9.2.  The scenario below
doesn't work with gdb 9.2 either.

> Indeed, I found a scenario where this would make a difference: ni-stepping
> through line 53.
>
> With trunk I get:
> ...
> (gdb)
> 0x0000000000400d13      53            if (curr->right) {
> todo.push_back(curr->right); }
> (gdb)
> 0x0000000000400d18      53            if (curr->right) {
> todo.push_back(curr->right); }
> (gdb)
> 0x0000000000400d1d in inorder (root=0x6031f0 <node_array>)
> (gdb)
> 0x0000000000400d21 in inorder (root=0x6031f0 <node_array>)
> (gdb)
> ...
>
> But with the patch from comment 1, we have instead:
> ...
> (gdb)
> 0x0000000000400d13      53            if (curr->right) {
> todo.push_back(curr->right); }
> (gdb)
> 0x0000000000400d18      53            if (curr->right) {
> todo.push_back(curr->right); }
> (gdb)
> 0x0000000000400d1d      53            if (curr->right) {
> todo.push_back(curr->right); }
> (gdb)
> 0x0000000000400d21      53            if (curr->right) {
> todo.push_back(curr->right); }
> (gdb)
> ...

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug symtab/26243] Handle line number 0 in line table produced by clang

Sourceware - gdb-prs mailing list
In reply to this post by Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26243

--- Comment #7 from Tom de Vries <vries at gcc dot gnu.org> ---
submitted patch:
https://sourceware.org/pipermail/gdb-patches/2020-July/170506.html

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug symtab/26243] Handle line number 0 in line table produced by clang

Sourceware - gdb-prs mailing list
In reply to this post by Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26243

--- Comment #8 from Simon Marchi <simark at simark dot ca> ---
This exact problem was hit in the context of AMD's rocm-gdb [1], and we (Pedro,
I and AMD devs) were in the middle of a discussion about how to handle this
correctly.  I'll try to capture what came out of our discussion so far.

Let's use some simple dummy instruction / line mapping as an example:

insn1 <-> line 10
insn2 <-> line 0
insn3 <-> line 0
insn4 <-> line 20

- If an instruction is mapped to line 0, we should not hide the fact that the
instruction maps to no source line.  We should not merge it with the preceding
instruction's line, or something like that.

So if you stepi until insn2, or put a breakpoint on it and run, it should not
appear as if you stopped at line 10.  It should appear that you stopped
somewhere without source.

This should be a good motivation for compilers to emit better debug info, where
all instructions are covered, where possible.

- Getting from a region with line info to a region without line info.  You are
on insn1 and you do "step".  The current behavior is: it stops at insn2, where
you have no source available.

On one hand, it's "correct" to stop, because we went from an instruction
belonging to line 10 to an instruction not belonging to line 10.  That's the
conservative thing to do.  But that's also not very useful to the average user
who wants to debug at source level.

The other would be to make the step/next commands keep stepping when they go
from an instruction with line info to an instruction without line info.  That
is essentially the historical behavior Tom described.  In our example, doing a
"step" while stopped at insn1 would step until stopped at insn4.

There is a good suggestion coming from Pedro.  There's a quite unknown setting
(and with an incredibly bad name, IMO), "set step-mode":

  (gdb) help set step-mode
  Set mode of the step operation.
  When set, doing a step over a function without debug line information
  will stop at the first instruction of that function. Otherwise, the
  function is skipped and the step command stops at a different source line.

It talks about "stepping over a function", but really it could apply here as
well.  When "off" (the default), it would behave as it did historically,
skipping those regions.  When "on", a step would stop at the instruction with
line 0.

- Doing a step/next when stopped at an instruction with line 0

So you are stopped at insn2 and do "step", what happens?  Currently, GDB steps
out of the function, we all agreed that is not really helpful.

The three possibilities are:

1. We don't have line info, so we can't step a line.  Make step act as a stepi,
and next act as a nexti.
2. Treat line 0 as a real line, for this purpose.  Here, GDB would single step
insn2, see that we are still at the same line as in the beginning, and single
step again, to stop on insn4.
3. Tie the behavior of this to "set step-mode" as well.  When "on", act like 1,
when "off", act like 2.

So with (1) the user would require two `step` to get to insn4.  With (2), it
would require one.  We had arguments for and against both, which we can detail
later.

[1] https://github.com/ROCm-Developer-Tools/ROCgdb

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug symtab/26243] Handle line number 0 in line table produced by clang

Sourceware - gdb-prs mailing list
In reply to this post by Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26243

Pedro Alves <palves at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |palves at redhat dot com

--- Comment #9 from Pedro Alves <palves at redhat dot com> ---
Created attachment 12705
  --> https://sourceware.org/bugzilla/attachment.cgi?id=12705&action=edit
Make "set step-mode off" not stop for "no-line-info" blocks

Here's a patch implementing the idea above.

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug symtab/26243] Handle line number 0 in line table produced by clang

Sourceware - gdb-prs mailing list
In reply to this post by Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26243

--- Comment #10 from Pedro Alves <palves at redhat dot com> ---
With the prototype patch attached, and using Tom's testcase, I run to line 46,
and then do "next".

With step-mode on, with or without the patch, we get:

 (gdb) set step-mode on
 (gdb) b 46
 Breakpoint 1 at 0x400c7b: file test.cpp, line 46.
 (gdb) r
 Starting program: /home/pedro/tmp/line0/a.out

 Breakpoint 1, inorder (root=0x6031d0 <node_array>) at test.cpp:46
 46        while (!todo.empty()){
 (gdb) n
 0x0000000000400c80 in inorder (root=0x6031d0 <node_array>)
 (gdb) n
 0x0000000000400c84      46        while (!todo.empty()){
 (gdb) n
 0x0000000000400ca3 in inorder (root=0x6031d0 <node_array>)
 (gdb) n
 47          node *curr = todo.back();


WITHOUT the patch, and "set step-mode off" (the default), we get:

 (gdb) set step-mode off
 (gdb) b 46
 Breakpoint 1 at 0x400c7b: file test.cpp, line 46.
 (gdb) r
 Starting program: /home/pedro/tmp/line0/a.out

 Breakpoint 1, inorder (root=0x6031d0 <node_array>) at test.cpp:46
 46        while (!todo.empty()){
 (gdb) n
 0x0000000000400c80 in inorder (root=0x6031d0 <node_array>)
 (gdb) n
 Single stepping until exit from function _Z7inorderP4node,
 which has no line number information.
 main (argc=1, argv=0x7fffffffd428) at test.cpp:77
 77        std::cout <<  "\n";
 (gdb)


While with the patch and "set step-mode off" (the default),
we get:

 (gdb) set step-mode off
 (gdb) b 46
 Breakpoint 1 at 0x400c7b: file test.cpp, line 46.
 (gdb) r
 Starting program: /home/pedro/tmp/line0/a.out

 Breakpoint 1, inorder (root=0x6031d0 <node_array>) at test.cpp:46
 46        while (!todo.empty()){
 (gdb) n
 47          node *curr = todo.back();


WDYT?  This seems like the ideal behavior to me.

I have no idea whether changing the line table reader to use some way other
than "line == 0" to track "end-of-statement" would be invasive.

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug symtab/26243] Handle line number 0 in line table produced by clang

Sourceware - gdb-prs mailing list
In reply to this post by Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26243

--- Comment #11 from Pedro Alves <palves at redhat dot com> ---
I tried my patch against the testcase from Tom's proposed patch on the mailing
list, and that results in:

 Running
/home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp
...
 FAIL: gdb.dwarf2/dw2-line-number-zero.exp: bar2, 2nd next
 KPASS: gdb.dwarf2/dw2-line-number-zero.exp: continue to breakpoint:
bar1_label_3 (PRMS gdb/nnnnn)
 KPASS: gdb.dwarf2/dw2-line-number-zero.exp: continue to breakpoint:
bar2_label_3 (PRMS gdb/nnnnn)

The FAIL is because GDB is not figuring out the length of the "bar2" function
correctly:

 (gdb) disassemble bar2
 Dump of assembler code for function bar2:
   0x00000000004004c0 <+0>:     push   %rbp
   0x00000000004004c1 <+1>:     mov    %rsp,%rbp
   0x00000000004004c4 <+4>:     mov    $0x1,%edi
   0x00000000004004c9 <+9>:     call   0x400487 <foo>
   0x00000000004004ce <+14>:    mov    $0x2,%edi
   0x00000000004004d3 <+19>:    call   0x400487 <foo>
 End of assembler dump.
 (gdb) q

So after that "next", the program stops at an address outside of the function,
and so the patch's still-in-same-function logic doesn't apply.

I.e., seems like either there's a bug elsewhere, where bar2's length is
determined, or the testcase has a bug.  The other two calls to foo should be
part of the function too.

Interestingly, if you try to set a breakpoint just by number using
Tom's testcase (with or without his proposed fix), GDB crashes...:

 (gdb) b 54
 Aborted (core dumped)

Sigh.

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug symtab/26243] Handle line number 0 in line table produced by clang

Sourceware - gdb-prs mailing list
In reply to this post by Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26243

--- Comment #12 from Pedro Alves <palves at redhat dot com> ---
> I.e., seems like either there's a bug elsewhere, where bar2's length is
> determined, or the testcase has a bug.  The other two calls to foo should be
> part of the function too.

It's the latter - a simple typo:

diff --git c/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp
w/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp
index e322f777082..acf16848e82 100644
--- c/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp
+++ w/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp
@@ -74,7 +74,7 @@ Dwarf::assemble $asm_file {
                {external 1 flag}
                {name bar2}
                {low_pc $bar2_start addr}
-               {high_pc "$bar2_start + $main_length" addr}
+               {high_pc "$bar2_start + $bar2_length" addr}
            }
        }
     }

With that, I now get:

Running
/home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp
...
KPASS: gdb.dwarf2/dw2-line-number-zero.exp: continue to breakpoint:
bar1_label_3 (PRMS gdb/nnnnn)
KPASS: gdb.dwarf2/dw2-line-number-zero.exp: continue to breakpoint:
bar2_label_3 (PRMS gdb/nnnnn)

                === gdb Summary ===

# of expected passes            6
# of unknown successes          2

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug symtab/26243] Handle line number 0 in line table produced by clang

Sourceware - gdb-prs mailing list
In reply to this post by Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26243

--- Comment #13 from Tom de Vries <vries at gcc dot gnu.org> ---
(In reply to Pedro Alves from comment #12)

> > I.e., seems like either there's a bug elsewhere, where bar2's length is
> > determined, or the testcase has a bug.  The other two calls to foo should be
> > part of the function too.
>
> It's the latter - a simple typo:
>
> diff --git c/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp
> w/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp
> index e322f777082..acf16848e82 100644
> --- c/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp
> +++ w/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp
> @@ -74,7 +74,7 @@ Dwarf::assemble $asm_file {
>                 {external 1 flag}
>                 {name bar2}
>                 {low_pc $bar2_start addr}
> -               {high_pc "$bar2_start + $main_length" addr}
> +               {high_pc "$bar2_start + $bar2_length" addr}
>             }
>         }
>      }
>

Sorry about that.  I've now found out that I could have used this instead:
...
                 {external 1 flag}
                 {MACRO_AT_func {bar2}}
...

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug symtab/26243] Handle line number 0 in line table produced by clang

Sourceware - gdb-prs mailing list
In reply to this post by Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26243

--- Comment #14 from Andrew Burgess <andrew.burgess at embecosm dot com> ---
I just posted this to the mailing list:
  https://sourceware.org/pipermail/gdb-patches/2020-July/170588.html

This removes the use of 0 as the end of sequence marker and replaces it with a
named constant (with the value -1).

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug symtab/26243] Handle line number 0 in line table produced by clang

Sourceware - gdb-prs mailing list
In reply to this post by Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26243

--- Comment #15 from Pedro Alves <palves at redhat dot com> ---
Cool!

I think that for my infrun the fix, it doesn't make a difference whether "real"
line 0 and end marker are ambiguous.

I'm working on extending Tom's testcase to test both "set step-mode" on and off
on top of my patch.

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug symtab/26243] Handle line number 0 in line table produced by clang

Sourceware - gdb-prs mailing list
In reply to this post by Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26243

--- Comment #16 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Tom de Vries <[hidden email]>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=876518dd0a0b6fd6f4ad0a0b247db0d6a267db27

commit 876518dd0a0b6fd6f4ad0a0b247db0d6a267db27
Author: Tom de Vries <[hidden email]>
Date:   Sat Jul 25 00:23:06 2020 +0200

    [gdb/symtab] Ignore zero line table entries

    The DWARF standard states for the line register in the line number
information
    state machine the following:
    ...
    An unsigned integer indicating a source line number.  Lines are numbered
    beginning at 1.  The compiler may emit the value 0 in cases where an
    instruction cannot be attributed to any source line.
    ...

    So, it's possible to have a zero line number in the DWARF line table.

    This is currently not handled by GDB.  The zero value is read in as any
other
    line number, but internally the zero value has a special meaning:
    end-of-sequence, so the line table entry ends up having a different
    interpretation than intended in some situations.

    I've created a test-case where various aspects are tested, which has these
4
    interesting tests.

    1. Next-step through a zero-line instruction, is_stmt == 1
    gdb.dwarf2/dw2-line-number-zero.exp: bar1, 2nd next

    2. Next-step through a zero-line instruction, is_stmt == 0
    gdb.dwarf2/dw2-line-number-zero.exp: bar2, 2nd next

    3. Show source location at zero-line instruction, is_stmt == 1
    gdb.dwarf2/dw2-line-number-zero.exp: continue to breakpoint: bar1_label_3

    4. Show source location at zero-line instruction, is_stmt == 0
    gdb.dwarf2/dw2-line-number-zero.exp: continue to breakpoint: bar2_label_3

    And we have the following results:

    8.3.1, 9.2:
    ...
    FAIL: gdb.dwarf2/dw2-line-number-zero.exp: bar1, 2nd next
    PASS: gdb.dwarf2/dw2-line-number-zero.exp: bar2, 2nd next
    PASS: gdb.dwarf2/dw2-line-number-zero.exp: continue to breakpoint:
bar1_label_3
    FAIL: gdb.dwarf2/dw2-line-number-zero.exp: continue to breakpoint:
bar2_label_3
    ...

    commit 8c95582da8 "gdb: Add support for tracking the DWARF line table
is-stmt
    field":
    ...
    PASS: gdb.dwarf2/dw2-line-number-zero.exp: bar1, 2nd next
    PASS: gdb.dwarf2/dw2-line-number-zero.exp: bar2, 2nd next
    FAIL: gdb.dwarf2/dw2-line-number-zero.exp: continue to breakpoint:
bar1_label_3
    FAIL: gdb.dwarf2/dw2-line-number-zero.exp: continue to breakpoint:
bar2_label_3
    ...

    commit d8cc8af6a1 "[gdb/symtab] Fix line-table end-of-sequence sorting",
    master:
    FAIL: gdb.dwarf2/dw2-line-number-zero.exp: bar1, 2nd next
    FAIL: gdb.dwarf2/dw2-line-number-zero.exp: bar2, 2nd next
    PASS: gdb.dwarf2/dw2-line-number-zero.exp: continue to breakpoint:
bar1_label_3
    PASS: gdb.dwarf2/dw2-line-number-zero.exp: continue to breakpoint:
bar2_label_3
    ...

    The regression in test 2 at commit d8cc8af6a1 was filed as PR symtab/26243,
    where clang emits zero line numbers.

    The way to fix all tests is to make sure line number zero internally
doesn't
    clash with special meaning values, and by handling it appropriately
    everywhere.  That however looks too intrusive for the GDB 10 release.

    Instead, we decide to ensure defined behaviour for line number zero by
    ignoring it.  This gives us back the test results from before commit
    d8cc8af6a1, fixing PR26243.

    We mark the FAILs for tests 3 and 4 as KFAILs.  Test 4 was already failing
for
    the 9.2 release, and we consider the regression of test 3 from gdb 9.2 to
gdb
    10 the cost for having defined behaviour.

    Build and reg-tested on x86_64-linux.

    gdb/ChangeLog:

    2020-07-25  Tom de Vries  <[hidden email]>

            PR symtab/26243
            * dwarf2/read.c (lnp_state_machine::record_line): Ignore zero line
            entries.

    gdb/testsuite/ChangeLog:

    2020-07-25  Tom de Vries  <[hidden email]>

            PR symtab/26243
            * gdb.dwarf2/dw2-line-number-zero.c: New test.
            * gdb.dwarf2/dw2-line-number-zero.exp: New file.

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug symtab/26243] Handle line number 0 in line table produced by clang

Sourceware - gdb-prs mailing list
In reply to this post by Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26243

Tom de Vries <vries at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |FIXED
             Status|NEW                         |RESOLVED

--- Comment #17 from Tom de Vries <vries at gcc dot gnu.org> ---
Patch fixing regression and adding dwarf assembly test-case added, marking
resolved-fixed.

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug symtab/26243] Handle line number 0 in line table produced by clang

Sourceware - gdb-prs mailing list
In reply to this post by Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26243

Jaydeep Chauhan <jaydeepchauhan1494 at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jaydeepchauhan1494 at gmail dot co
                   |                            |m

--- Comment #18 from Jaydeep Chauhan <jaydeepchauhan1494 at gmail dot com> ---
*** Bug 26538 has been marked as a duplicate of this bug. ***

--
You are receiving this mail because:
You are on the CC list for the bug.