This is the mail archive of the gdb-prs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug gdb/19893] New: Synthetic pointers created from C++ references are broken


https://sourceware.org/bugzilla/show_bug.cgi?id=19893

            Bug ID: 19893
           Summary: Synthetic pointers created from C++ references are
                    broken
           Product: gdb
           Version: HEAD
            Status: NEW
          Severity: normal
          Priority: P2
         Component: gdb
          Assignee: martin.galvan at tallertechnologies dot com
          Reporter: martin.galvan at tallertechnologies dot com
                CC: daniel.gutson at tallertechnologies dot com,
                    palves at redhat dot com, tromey at sourceware dot org
  Target Milestone: ---

Created attachment 9147
  --> https://sourceware.org/bugzilla/attachment.cgi?id=9147&action=edit
Example program that triggers the bug (compile with gcc -O3 and try to print
'arg')

Hi everyone,

After compiling a program which uses C++ references with gcc 4.8.4 or later,
some optimizations may convert the references into synthetic pointers. This
seems to cause all sorts of breakage when trying to use them in gdb
expressions. 

Suppose we have something like:

int var = 42;
int& ref = var;

Case 1: Trying to print the address of a ref causes gdb to crash:

(gdb) print &ref
/build/buildd/gdb-7.7.1/gdb/dwarf2loc.c:1624: internal-error: Should not be
able to create a lazy value with an enclosing type
A problem internal to GDB has been detected,
further debugging may prove unreliable.

The expected result here would be the address of 'var'.

Case 2: Trying to print the value of a ref simply shows the <synthetic pointer>
tag:

(gdb) print ref
$1 = (int &) <synthetic pointer>

The expected result would be something like:

$1 = (int &) <synthetic pointer>: 42

Case 3: Trying to do arithmetic on the value of a ref shows the following
error:

(gdb) print ref + 0
Cannot access memory at address 0x0

The expected result would be to print '42' (the value of 'var').

Case 4: Trying to assign some value to the ref shows the same error:

(gdb) set (ref = 1)
Cannot access memory at address 0x0

There are probably other cases like these lying around.

I'm currently working on fixing this issue. I had originally sent a patch for
case 1 (https://sourceware.org/ml/gdb-patches/2015-06/msg00278.html), but after
discussing it with Pedro I decided to dwell a bit further and see the what's
the real source of all the breakage.

I think the fundamental problem here is that gdb seems to always assume that
references are implemented as pointers by the compiler, and thus the 'location'
attribute of a value representing a ref always points to the underlying
pointer. This is a mistake, since the C++ standard doesn't specify this. When
references are effectively treated like aliases (which isn't just an
optimization thing but a perfectly normal thing to do for any compiler),
breakage arises.

>From what I saw I think there may be two ways to fix this:

1) Looking for all the cases where synthetic references are a problem, and
fixing them one by one. I think case 1 could be fixed by conditionally calling
something like coerce_ref inside value_addr, though coerce_ref doesn't seem to
work as expected (as evidenced by case 4). I haven't dwelled in the code for
all the cases, but hopefully gdb uses something like coerce_ref for most of
them, so hopefully the fix shouldn't touch a lot of code.
2) Acknowledging that references aren't pointers, and refactor all the code so
they're treated as a special entity of some sort. IMHO this would be the right
thing to do, but it would probably take way longer.

In any case, I don't think gcc should be touched. It's up to the compiler to
decide how to treat references (and whether to mark them with
DW_OP_GNU_implicit_pointer when optimized away), but the debugger should be
able to handle them transparently in all cases.

What do you guys think? I'm probably missing something since I've come back to
work on this only recently, so any feedback is more than appreciated.

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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]