mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-01-08 21:10:35 +00:00
e22f8b7c8c
Switch the license of all .f and .f90 files to GPLv3. Switch the license of all .s and .S files to GPLv3.
127 lines
5.3 KiB
Plaintext
127 lines
5.3 KiB
Plaintext
# Copyright 2002, 2004, 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 <http://www.gnu.org/licenses/>.
|
|
|
|
if $tracelevel then {
|
|
strace $tracelevel
|
|
}
|
|
|
|
set prms_id 0
|
|
set bug_id 0
|
|
|
|
if { [skip_cplus_tests] } { continue }
|
|
|
|
set testfile hang
|
|
set binfile ${objdir}/${subdir}/${testfile}
|
|
|
|
foreach file {hang1 hang2 hang3} {
|
|
if {[gdb_compile "${srcdir}/${subdir}/${file}.C" "${file}.o" object {c++ debug}] != ""} {
|
|
untested hang.exp
|
|
return -1
|
|
}
|
|
}
|
|
|
|
if {[gdb_compile "hang1.o hang2.o hang3.o" ${binfile} executable {c++ debug}] != "" } {
|
|
untested hang.exp
|
|
return -1
|
|
}
|
|
|
|
|
|
gdb_exit
|
|
gdb_start
|
|
gdb_reinitialize_dir $srcdir/$subdir
|
|
gdb_load ${binfile}
|
|
|
|
|
|
# As of May 1, 2002, GDB hangs trying to read the debug info for the
|
|
# `hang2.o' compilation unit from the executable `hang', when compiled
|
|
# by g++ 2.96 with STABS debugging info. Here's what's going on, as
|
|
# best as I can tell.
|
|
#
|
|
# The definition of `struct A' in `hang.H' refers to `struct B' as an
|
|
# incomplete type. The stabs declare type number (1,3) to be a cross-
|
|
# reference type, `xsB:'.
|
|
#
|
|
# The definition of `struct C' contains a nested definition for
|
|
# `struct B' --- or more properly, `struct C::B'. However, the stabs
|
|
# fail to qualify the structure tag: it just looks like a definition
|
|
# for `struct B'. I think this is a compiler bug, but perhaps GCC
|
|
# doesn't emit qualified names for a reason.
|
|
#
|
|
# `hang.H' gets #included by both `hang1.C' and `hang2.C'. So the
|
|
# stabs for `struct A', the incomplete `struct B', and `struct C'
|
|
# appear in both hang1.o's and hang2.o's stabs.
|
|
#
|
|
# When those two files are linked together, since hang2.o appears
|
|
# later in the command line, its #inclusion of `hang.H' gets replaced
|
|
# with an N_EXCL stab, referring back to hang1.o's stabs for the
|
|
# header file.
|
|
#
|
|
# When GDB builds psymtabs for the executable hang, it notes that
|
|
# hang2.o's stabs contain an N_EXCL referring to a header that appears
|
|
# in full in hang1.o's stabs. So hang2.o's psymtab lists a dependency
|
|
# on hang1.o's psymtab.
|
|
#
|
|
# When the user types the command `print var_in_b', GDB scans the
|
|
# psymtabs for a symbol by that name, and decides to read full symbols
|
|
# for `hang2.o'.
|
|
#
|
|
# Since `hang2.o''s psymtab lists `hang1.o' as a dependency, GDB first
|
|
# reads `hang1.o''s symbols. When GDB sees `(1,3)=xsB:', it creates a
|
|
# type object for `struct B', sets its TYPE_FLAG_STUB flag, and
|
|
# records it as type number `(1,3)'.
|
|
#
|
|
# When GDB finds the definition of `struct C::B', since the stabs
|
|
# don't indicate that the type is nested within C, it treats it as
|
|
# a definition of `struct B'.
|
|
#
|
|
# When GDB is finished reading `hang1.o''s symbols, it calls
|
|
# `cleanup_undefined_types'. This function mistakes the definition of
|
|
# `struct C::B' for a definition for `struct B', and overwrites the
|
|
# incomplete type object for the real `struct B', using `memcpy'. Now
|
|
# stabs type number `(1,3)' refers to this (incorrect) complete type.
|
|
# Furthermore, the `memcpy' simply copies the original's `cv_type'
|
|
# field to the target, giving the target a corrupt `cv_type' ring: the
|
|
# chain does not point back to the target type.
|
|
#
|
|
# Having satisfied `hang2.o''s psymtab's dependencies, GDB begins to
|
|
# read `hang2.o''s symbols. These contain the true definition for
|
|
# `struct B', which refers to type number `(1,3)' as the type it's
|
|
# defining. GDB looks up type `(1,3)', and finds the (incorrect)
|
|
# complete type established by the call to `cleanup_undefined_types'
|
|
# above. However, it doesn't notice that the type is already defined,
|
|
# and passes it to `read_struct_type', which then writes the new
|
|
# definition's size, field list, etc. into the type object which
|
|
# already has those fields initialized. Adding insult to injury,
|
|
# `read_struct_type' then calls `finish_cv_type'; since the `memcpy'
|
|
# in `cleanup_undefined_types' corrupted the target type's `cv_type'
|
|
# ring, `finish_cv_type' enters an infinite loop.
|
|
|
|
# This checks that GDB recognizes when a structure is about to be
|
|
# overwritten, and refuses, with a complaint.
|
|
gdb_test "print var_in_b" " = 1729" "doesn't overwrite struct type"
|
|
|
|
# This checks that cleanup_undefined_types doesn't create corrupt
|
|
# cv_type chains. Note that var_in_hang3 does need to be declared in
|
|
# a separate compilation unit, whose psymtab depends on hang1.o's
|
|
# psymtab. Otherwise, GDB won't call cleanup_undefined_types (as it
|
|
# finishes hang1.o's symbols) before it calls make_cv_type (while
|
|
# reading hang3.o's symbols).
|
|
#
|
|
# The bug only happens when you compile with -gstabs+; Otherwise, GCC
|
|
# won't include the `const' qualifier on `const_B_ptr' in `hang3.o''s
|
|
# STABS, so GDB won't try to create a const variant of the smashed
|
|
# struct type, and get caught by the corrupted cv_type chain.
|
|
gdb_test "print var_in_hang3" " = 42" "doesn't corrupt cv_type chain"
|