2007-12-13 Doug Evans PR 2384 * gdbtypes.c (fill_in_vptr_fieldno): Don't set TYPE_VPTR_FIELDNO, TYPE_VPTR_BASETYPE if from different objfile. * gdb.cp/gdb2384.exp: New file. * gdb.cp/gdb2384.cc: New file. * gdb.cp/gdb2384-base.h: New file. * gdb.cp/gdb2384-base.cc: New file. Index: gdbtypes.c =================================================================== RCS file: /cvs/src/src/gdb/gdbtypes.c,v retrieving revision 1.140 diff -u -p -u -p -r1.140 gdbtypes.c --- gdbtypes.c 4 Dec 2007 23:33:00 -0000 1.140 +++ gdbtypes.c 13 Dec 2007 23:59:35 -0000 @@ -1307,8 +1307,13 @@ fill_in_vptr_fieldno (struct type *type) fill_in_vptr_fieldno (baseclass); if (TYPE_VPTR_FIELDNO (baseclass) >= 0) { - TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (baseclass); - TYPE_VPTR_BASETYPE (type) = TYPE_VPTR_BASETYPE (baseclass); + /* If the type comes from a different objfile we can't use it + here, it may have a different lifetime. PR 2384 */ + if (TYPE_OBJFILE (type) == TYPE_OBJFILE (baseclass)) + { + TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (baseclass); + TYPE_VPTR_BASETYPE (type) = TYPE_VPTR_BASETYPE (baseclass); + } break; } } Index: testsuite/gdb.cp/gdb2384-base.cc =================================================================== RCS file: testsuite/gdb.cp/gdb2384-base.cc diff -N testsuite/gdb.cp/gdb2384-base.cc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.cp/gdb2384-base.cc 13 Dec 2007 23:59:35 -0000 @@ -0,0 +1,12 @@ +#include "gdb2384-base.h" + +base::base (int _x) + : x (_x) +{ +} + +int +base::meth () +{ + return x; +} Index: testsuite/gdb.cp/gdb2384-base.h =================================================================== RCS file: testsuite/gdb.cp/gdb2384-base.h diff -N testsuite/gdb.cp/gdb2384-base.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.cp/gdb2384-base.h 13 Dec 2007 23:59:35 -0000 @@ -0,0 +1,7 @@ +class base +{ + public: + base (int _x); + int x; + virtual int meth (); +}; Index: testsuite/gdb.cp/gdb2384.cc =================================================================== RCS file: testsuite/gdb.cp/gdb2384.cc diff -N testsuite/gdb.cp/gdb2384.cc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.cp/gdb2384.cc 13 Dec 2007 23:59:35 -0000 @@ -0,0 +1,22 @@ +#include "gdb2384-base.h" + +class derived : public base +{ + public: + derived (int); +}; + +derived::derived (int _x) + : base (_x) +{ +} + +int g; + +int +main () +{ + derived d (42); + g = d.meth (); // set breakpoint here + return 0; +} Index: testsuite/gdb.cp/gdb2384.exp =================================================================== RCS file: testsuite/gdb.cp/gdb2384.exp diff -N testsuite/gdb.cp/gdb2384.exp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.cp/gdb2384.exp 13 Dec 2007 23:59:35 -0000 @@ -0,0 +1,99 @@ +# Copyright 2007 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# When gdb resolves type information for class "derived" from objfile +# gdb2384, it use to fill in the TYPE_VPTR_BASETYPE field with class "base" +# from objfile gdb2384-base.so. When the program is rerun the type +# information for base-in-so-base.so is discarded leaving +# TYPE_VPTR_BASETYPE dangling. + +if $tracelevel then { + strace $tracelevel +} + +if { [skip_cplus_tests] } { continue } + +set prms_id 2384 +set bug_id 0 + +set testfile "gdb2384" +set srcfile ${testfile}.cc +set binfile $objdir/$subdir/$testfile + +set libfile "gdb2384-base" +set libsrcfile ${libfile}.cc +set sofile $objdir/$subdir/"${libfile}.so" + +# Create and source the file that provides information about the compiler +# used to compile the test case. +if [get_compiler_info ${binfile} "c++"] { + return -1 +} + +if { [gdb_compile_shlib $srcdir/$subdir/$libsrcfile $sofile {debug c++}] != "" + || [gdb_compile $srcdir/$subdir/$srcfile $binfile executable [list debug "c++" shlib=${sofile}]] != ""} { + untested gdb2384.exp + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} +#gdb_load_shlibs ${sofile} + +set bp_location [gdb_get_line_number "set breakpoint here"] + +# Set a breakpoint with multiple locations. + +gdb_test "break $srcfile:$bp_location" \ + "Breakpoint.*at.* file .*$srcfile, line.*" \ + "set breakpoint" + +gdb_run_cmd +gdb_expect { + -re "Breakpoint \[0-9\]+,.*main \\(.*\\).*$gdb_prompt $" { + pass "run to breakpoint" + } + -re "$gdb_prompt $" { + fail "run to breakpoint" + } + timeout { + fail "run to breakpoint (timeout)" + } +} + +gdb_test "print d.meth ()" \ + ".*42.*" \ + "print d.meth ()" + +# Now try again. gdb's without the fix will hopefully segv here + +gdb_run_cmd +gdb_expect { + -re "Breakpoint \[0-9\]+,.*main \\(.*\\).*$gdb_prompt $" { + pass "run to breakpoint #2" + } + -re "$gdb_prompt $" { + fail "run to breakpoint #2" + } + timeout { + fail "run to breakpoint #2 (timeout)" + } +} + +gdb_test "print d.meth ()" \ + ".*42.*" \ + "gdb2384"