Bug 17106

Summary: Infinite recursion in in_dynamic_types (e.g. when printing a variable)
Product: gdb Reporter: Pete Deas <petedeas>
Component: expAssignee: Tom Tromey <tromey>
Status: RESOLVED FIXED    
Severity: normal CC: tromey
Priority: P2    
Version: 7.7   
Target Milestone: 7.8   
Host: Target:
Build: Last reconfirmed:

Description Pete Deas 2014-07-01 17:38:21 UTC
Release: 7.7.90.20140701-cvs

OS: Linux petebox 3.15.1-gentoo #1 SMP Sat Jun 21 15:14:16 BST 2014 x86_64 Intel(R) Core(TM) i3 CPU M 370 @ 2.40GHz GenuineIntel GNU/Linux

gcc: 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) 

(gdb) show configuration
This GDB was configured as follows:
   configure --host=x86_64-unknown-linux-gnu --target=x86_64-unknown-linux-gnu
             --with-auto-load-dir=$debugdir:$datadir/auto-load
             --with-auto-load-safe-path=$debugdir:$datadir/auto-load
             --with-expat
             --with-gdb-datadir=/usr/local/share/gdb (relocatable)
             --with-jit-reader-dir=/usr/local/lib/gdb (relocatable)
             --without-libunwind-ia64
             --with-lzma
             --with-python=/usr
             --without-guile
             --with-separate-debug-dir=/usr/local/lib/debug (relocatable)
             --with-zlib
             --without-babeltrace

How-to-Repeat:

Compile the following (I used g++ -g3 -std=c++98 -Wall demo.cpp -o demo):

// Start of file
#include <iostream>

struct Container;

struct Item {
        Container &m_container;
        int m_n;
        Item(Container &c, int n) : m_container(c), m_n(n) { };
};

struct Container {
        Item m_item;
        Container(int n) : m_item(*this, n) { };
};

int main(int argc, const char *argv[]) {
        Container c(7);
        std::cout << c.m_item.m_n << std::endl;
        return 0;
}
// EOF

Using gdb, attempt to print c after it has been constructed:

Temporary breakpoint 1, main (argc=1, argv=0x7fffffffe148) at demo.cpp:17
17              Container c(7);
(gdb) n
18              std::cout << c.m_item.m_n << std::endl;
(gdb) p c
7
Segmentation fault (core dumped)

For comparison, GDB 7.7.1 does not have this bug, and prints:

$1 = {m_item = {m_container = @0x7fffffffe050, m_n = 7}}

Snippet of backtrace taken during "print c":

...
#42 0x00000000005ca380 in is_dynamic_type (type=0x20f4810) at gdbtypes.c:1647
#43 0x00000000005ca380 in is_dynamic_type (type=0x20f48a0) at gdbtypes.c:1647
#44 0x00000000005ca380 in is_dynamic_type (type=0x20f4810) at gdbtypes.c:1647
#45 0x00000000005ca380 in is_dynamic_type (type=0x20f48a0) at gdbtypes.c:1647
#46 0x00000000005ca380 in is_dynamic_type (type=0x20f4810) at gdbtypes.c:1647
#47 0x00000000005ca380 in is_dynamic_type (type=0x20f48a0) at gdbtypes.c:1647
#48 0x00000000005cdbc1 in resolve_dynamic_type (type=type@entry=0x20f48a0, 
    addr=addr@entry=140737488347200) at gdbtypes.c:1834
#49 0x000000000055ed34 in value_from_contents_and_address (type=type@entry=0x20f48a0, 
    valaddr=valaddr@entry=0x0, address=address@entry=140737488347200) at value.c:3412
#50 0x00000000005677b7 in get_value_at (type=0x20f48a0, addr=140737488347200, lazy=1) at valops.c:920
#51 0x0000000000624e0a in dwarf2_evaluate_loc_desc_full (type=0x20f48a0, frame=0x1f7fe80, 
    data=0x20a7298 "\221`", size=2, per_cu=0x208d720, byte_offset=0) at dwarf2loc.c:2329
#52 0x00000000005509e9 in default_read_var_value (var=0x20f67e0, frame=0x1f7fe80) at findvar.c:435
#53 0x00000000005631b3 in evaluate_subexp_standard (expect_type=expect_type@entry=0x0, 
    exp=exp@entry=0x217a9c0, pos=0x7fff5c4859dc, noside=noside@entry=EVAL_NORMAL) at eval.c:771
#54 0x0000000000642a11 in evaluate_subexp_c (expect_type=0x0, exp=0x217a9c0, pos=0x7fff5c4859dc, 
    noside=EVAL_NORMAL) at c-lang.c:720
#55 0x0000000000561042 in evaluate_subexp (noside=EVAL_NORMAL, pos=0x7fff5c4859dc, 
    exp=<optimized out>, expect_type=0x0) at eval.c:71
#56 evaluate_expression (exp=<optimized out>) at eval.c:146
#57 0x0000000000577efb in print_command_1 (exp=0x1ebe152 "c", voidprint=1) at ./printcmd.c:977
#58 0x0000000000672ded in execute_command (p=<optimized out>, p@entry=0x1ebe150 "p c", from_tty=1)
    at top.c:461
#59 0x00000000005ba031 in command_handler (command=0x1ebe150 "p c") at event-top.c:433
#60 0x00000000005ba4dc in command_line_handler (rl=<optimized out>) at event-top.c:630
#61 0x00000000006be2e0 in rl_callback_read_char () at callback.c:220
#62 0x00000000005ba099 in rl_callback_read_char_wrapper (client_data=<optimized out>)
    at event-top.c:167
#63 0x00000000005b8d93 in process_event () at event-loop.c:343
#64 0x00000000005b90e7 in gdb_do_one_event () at event-loop.c:407
#65 0x00000000005b9307 in start_event_loop () at event-loop.c:432
#66 0x00000000005b2a63 in captured_command_loop (data=data@entry=0x0) at main.c:301
#67 0x00000000005afaea in catch_errors (func=func@entry=0x5b2a50 <captured_command_loop>, 
    func_args=func_args@entry=0x0, errstring=errstring@entry=0x780c22 "", 
    mask=mask@entry=RETURN_MASK_ALL) at exceptions.c:524
#68 0x00000000005b3836 in captured_main (data=data@entry=0x7fff5c485da0) at main.c:1097
#69 0x00000000005afaea in catch_errors (func=func@entry=0x5b2e10 <captured_main>, 
    func_args=func_args@entry=0x7fff5c485da0, errstring=errstring@entry=0x780c22 "", 
    mask=mask@entry=RETURN_MASK_ALL) at exceptions.c:524
#70 0x00000000005b3d3b in gdb_main (args=args@entry=0x7fff5c485da0) at main.c:1105
#71 0x000000000045f865 in main (argc=<optimized out>, argv=<optimized out>) at gdb.c:33

I don't know enough about gdb internals yet to suggest a fix, but I hope this report is useful.
Comment 1 Tom Tromey 2014-07-01 19:39:24 UTC
Mine.
Comment 2 Sourceware Commits 2014-07-14 16:39:48 UTC
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gdb and binutils".

The branch, gdb-7.8-branch has been updated
       via  c086b11bd257f68392b75a2297d601a6ab741a6b (commit)
      from  cb1a4f45173ee9c7482b3ae0f0a44cffcad4dd24 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

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

commit c086b11bd257f68392b75a2297d601a6ab741a6b
Author: Tom Tromey <tromey@redhat.com>
Date:   Wed Jul 2 15:53:31 2014 -0600

    fix PR 17106
    
    This fixes PR 17106, a regression in printing.
    
    The bug is that resolve_dynamic_type follows struct members and
    references, but doesn't consider the possibility of infinite
    recursion.
    
    This patch fixes the problem by limiting reference following to the
    topmost layer of calls -- that is, reference-typed struct members are
    never considered as being VLAs.
    
    Built and regtested on x86-64 Fedora 20.
    New test case included.
    
    2014-07-14  Tom Tromey  <tromey@redhat.com>
    
    	PR exp/17106:
    	* gdbtypes.c (is_dynamic_type_internal): New function, from
    	is_dynamic_type.
    	(is_dynamic_type): Rewrite.
    	(resolve_dynamic_union): Use resolve_dynamic_type_internal.
    	(resolve_dynamic_struct): Likewise.
    	(resolve_dynamic_type_internal): New function, from
    	resolve_dynamic_type.
    	(resolve_dynamic_type): Rewrite.
    
    2014-07-14  Tom Tromey  <tromey@redhat.com>
    
    	* gdb.cp/vla-cxx.cc: New file.
    	* gdb.cp/vla-cxx.exp: New file.

-----------------------------------------------------------------------

Summary of changes:
 gdb/ChangeLog                    |   12 ++++++++
 gdb/gdbtypes.c                   |   56 +++++++++++++++++++++++++++----------
 gdb/testsuite/ChangeLog          |    5 +++
 gdb/testsuite/gdb.cp/vla-cxx.cc  |   49 +++++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.cp/vla-cxx.exp |   35 +++++++++++++++++++++++
 5 files changed, 142 insertions(+), 15 deletions(-)
 create mode 100644 gdb/testsuite/gdb.cp/vla-cxx.cc
 create mode 100644 gdb/testsuite/gdb.cp/vla-cxx.exp
Comment 3 Tom Tromey 2014-07-14 16:45:27 UTC
Fix checked in.
Comment 4 Sourceware Commits 2014-07-14 16:51:26 UTC
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gdb and binutils".

The branch, master has been updated
       via  d98b7a16a982e4a17995536250b55f7ff82bd78e (commit)
      from  548740d6bdd115da2c9c17b194016c2c4c0a4c69 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

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

commit d98b7a16a982e4a17995536250b55f7ff82bd78e
Author: Tom Tromey <tromey@redhat.com>
Date:   Wed Jul 2 15:53:31 2014 -0600

    fix PR 17106
    
    This fixes PR 17106, a regression in printing.
    
    The bug is that resolve_dynamic_type follows struct members and
    references, but doesn't consider the possibility of infinite
    recursion.
    
    This patch fixes the problem by limiting reference following to the
    topmost layer of calls -- that is, reference-typed struct members are
    never considered as being VLAs.
    
    Built and regtested on x86-64 Fedora 20.
    New test case included.
    
    2014-07-14  Tom Tromey  <tromey@redhat.com>
    
    	PR exp/17106:
    	* gdbtypes.c (is_dynamic_type_internal): New function, from
    	is_dynamic_type.
    	(is_dynamic_type): Rewrite.
    	(resolve_dynamic_union): Use resolve_dynamic_type_internal.
    	(resolve_dynamic_struct): Likewise.
    	(resolve_dynamic_type_internal): New function, from
    	resolve_dynamic_type.
    	(resolve_dynamic_type): Rewrite.
    
    2014-07-14  Tom Tromey  <tromey@redhat.com>
    
    	* gdb.cp/vla-cxx.cc: New file.
    	* gdb.cp/vla-cxx.exp: New file.

-----------------------------------------------------------------------

Summary of changes:
 gdb/ChangeLog                    |   12 ++++++++
 gdb/gdbtypes.c                   |   56 +++++++++++++++++++++++++++----------
 gdb/testsuite/ChangeLog          |    5 +++
 gdb/testsuite/gdb.cp/vla-cxx.cc  |   49 +++++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.cp/vla-cxx.exp |   35 +++++++++++++++++++++++
 5 files changed, 142 insertions(+), 15 deletions(-)
 create mode 100644 gdb/testsuite/gdb.cp/vla-cxx.cc
 create mode 100644 gdb/testsuite/gdb.cp/vla-cxx.exp