public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/gdb] gdb-17.2-rebase-f44: Backport test for RHBZ 1976887 (Kevin Buettner).
@ 2026-06-28  0:00 
  0 siblings, 0 replies; only message in thread
From:  @ 2026-06-28  0:00 UTC (permalink / raw)
  To: git-commits

A new commit has been pushed.

Repo   : rpms/gdb
Branch : gdb-17.2-rebase-f44
Commit : 002d74553867daac37f7b6d7e6f5522a32b58d1b
Author : Alexandra Hájková <ahajkova@redhat.com>
Date   : 2021-09-30T13:15:28+02:00
Stats  : +600/-0 in 5 file(s)
URL    : https://src.fedoraproject.org/rpms/gdb/c/002d74553867daac37f7b6d7e6f5522a32b58d1b?branch=gdb-17.2-rebase-f44

Log:
Backport test for RHBZ 1976887 (Kevin Buettner).

---
diff --git a/_gdb.spec.Patch.include b/_gdb.spec.Patch.include
index f4c56c4..40256f8 100644
--- a/_gdb.spec.Patch.include
+++ b/_gdb.spec.Patch.include
@@ -415,3 +415,6 @@ Patch100: gdb-rhbz1970741-early-exit-for-empty-debuginfod-url.patch
 #type field location kind (RHBZ 1976887).
 Patch101: gdb-rhbz1976887-field-location-kind.patch
 
+# Backport test for RHBZ 1976887 (Kevin Buettner).
+Patch102: gdb-test-for-rhbz1976887.patch
+

diff --git a/_gdb.spec.patch.include b/_gdb.spec.patch.include
index 202a5cc..48f09cd 100644
--- a/_gdb.spec.patch.include
+++ b/_gdb.spec.patch.include
@@ -99,3 +99,4 @@
 %patch099 -p1
 %patch100 -p1
 %patch101 -p1
+%patch102 -p1

diff --git a/_patch_order b/_patch_order
index e7c012b..f448515 100644
--- a/_patch_order
+++ b/_patch_order
@@ -99,3 +99,4 @@ gdb-rhbz1971096-glibc2.34-5.patch
 gdb-rhbz1916516-pathstuffs132-internal-error.patch
 gdb-rhbz1970741-early-exit-for-empty-debuginfod-url.patch
 gdb-rhbz1976887-field-location-kind.patch
+gdb-test-for-rhbz1976887.patch

diff --git a/gdb-test-for-rhbz1976887.patch b/gdb-test-for-rhbz1976887.patch
new file mode 100644
index 0000000..d0625d7
--- /dev/null
+++ b/gdb-test-for-rhbz1976887.patch
@@ -0,0 +1,592 @@
+From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= <ahajkova@redhat.com>
+Date: Thu, 30 Sep 2021 13:13:03 +0200
+Subject: gdb-test-for-rhbz1976887.patch
+
+;; Backport test for RHBZ 1976887 (Kevin Buettner).
+
+Test case reproducing PR28030 bug
+
+The original reproducer for PR28030 required use of a specific
+compiler version - gcc-c++-11.1.1-3.fc34 is mentioned in the PR,
+though it seems probable that other gcc versions might also be able to
+reproduce the bug as well.  This commit introduces a test case which,
+using the DWARF assembler, provides a reproducer which is independent
+of the compiler version.  (Well, it'll work with whatever compilers
+the DWARF assembler works with.)
+
+To the best of my knowledge, it's also the first test case which uses
+the DWARF assembler to provide debug info for a shared object.  That
+being the case, I provided more than the usual commentary which should
+allow this case to be used as a template when a combo shared
+library / DWARF assembler test case is required in the future.
+
+I provide some details regarding the bug in a comment near the
+beginning of locexpr-dml.exp.
+
+This problem was difficult to reproduce; I found myself constantly
+referring to the backtrace while trying to figure out what (else) I
+might be missing while trying to create a reproducer.  Below is a
+partial backtrace which I include for posterity.
+
+ #0  internal_error (
+    file=0xc50110 "/ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/gdbtypes.c", line=5575,
+    fmt=0xc520c0 "Unexpected type field location kind: %d")
+    at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdbsupport/errors.cc:51
+ #1  0x00000000006ef0c5 in copy_type_recursive (objfile=0x1635930,
+    type=0x274c260, copied_types=0x30bb290)
+    at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/gdbtypes.c:5575
+ #2  0x00000000006ef382 in copy_type_recursive (objfile=0x1635930,
+    type=0x274ca10, copied_types=0x30bb290)
+    at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/gdbtypes.c:5602
+ #3  0x0000000000a7409a in preserve_one_value (value=0x24269f0,
+    objfile=0x1635930, copied_types=0x30bb290)
+    at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/value.c:2529
+ #4  0x000000000072012a in gdbscm_preserve_values (
+    extlang=0xc55720 <extension_language_guile>, objfile=0x1635930,
+    copied_types=0x30bb290)
+    at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/guile/scm-value.c:94
+ #5  0x00000000006a3f82 in preserve_ext_lang_values (objfile=0x1635930,
+    copied_types=0x30bb290)
+    at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/extension.c:568
+ #6  0x0000000000a7428d in preserve_values (objfile=0x1635930)
+    at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/value.c:2579
+ #7  0x000000000082d514 in objfile::~objfile (this=0x1635930,
+    __in_chrg=<optimized out>)
+    at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/objfiles.c:549
+ #8  0x0000000000831cc8 in std::_Sp_counted_ptr<objfile*, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=0x1654580)
+    at /usr/include/c++/11/bits/shared_ptr_base.h:348
+ #9  0x00000000004e6617 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x1654580) at /usr/include/c++/11/bits/shared_ptr_base.h:168
+ #10 0x00000000004e1d2f in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0x190bb88, __in_chrg=<optimized out>)
+    at /usr/include/c++/11/bits/shared_ptr_base.h:705
+ #11 0x000000000082feee in std::__shared_ptr<objfile, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0x190bb80, __in_chrg=<optimized out>)
+    at /usr/include/c++/11/bits/shared_ptr_base.h:1154
+ #12 0x000000000082ff0a in std::shared_ptr<objfile>::~shared_ptr (
+    this=0x190bb80, __in_chrg=<optimized out>)
+    at /usr/include/c++/11/bits/shared_ptr.h:122
+ #13 0x000000000085ed7e in __gnu_cxx::new_allocator<std::_List_node<std::shared_ptr<objfile> > >::destroy<std::shared_ptr<objfile> > (this=0x114bc00,
+    __p=0x190bb80) at /usr/include/c++/11/ext/new_allocator.h:168
+ #14 0x000000000085e88d in std::allocator_traits<std::allocator<std::_List_node<std::shared_ptr<objfile> > > >::destroy<std::shared_ptr<objfile> > (__a=...,
+    __p=0x190bb80) at /usr/include/c++/11/bits/alloc_traits.h:531
+ #15 0x000000000085e50c in std::__cxx11::list<std::shared_ptr<objfile>, std::allocator<std::shared_ptr<objfile> > >::_M_erase (this=0x114bc00, __position=
+  std::shared_ptr<objfile> (expired, weak count 1) = {get() = 0x1635930})
+    at /usr/include/c++/11/bits/stl_list.h:1925
+ #16 0x000000000085df0e in std::__cxx11::list<std::shared_ptr<objfile>, std::allocator<std::shared_ptr<objfile> > >::erase (this=0x114bc00, __position=
+  std::shared_ptr<objfile> (expired, weak count 1) = {get() = 0x1635930})
+    at /usr/include/c++/11/bits/list.tcc:158
+ #17 0x000000000085c748 in program_space::remove_objfile (this=0x114bbc0,
+    objfile=0x1635930)
+    at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/progspace.c:210
+ #18 0x000000000082d3ae in objfile::unlink (this=0x1635930)
+    at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/objfiles.c:487
+ #19 0x000000000082e68c in objfile_purge_solibs ()
+    at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/objfiles.c:875
+ #20 0x000000000092dd37 in no_shared_libraries (ignored=0x0, from_tty=1)
+    at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/solib.c:1236
+ #21 0x00000000009a37fe in target_pre_inferior (from_tty=1)
+    at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/target.c:2496
+ #22 0x00000000007454d6 in run_command_1 (args=0x0, from_tty=1,
+    run_how=RUN_NORMAL)
+    at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/infcmd.c:437
+
+I'll note a few points regarding this backtrace:
+
+Frame #1 is where the internal error occurs.  It's caused by an
+unhandled case for FIELD_LOC_KIND_DWARF_BLOCK.  The fix for this bug
+adds support for this case.
+
+Frame #22 - it's a partial backtrace - shows that GDB is attempting to
+(re)run the program.  You can see the exact command sequence that was
+used for reproducing this problem in the PR (at
+https://sourceware.org/bugzilla/show_bug.cgi?id=28030), but in a
+nutshell, after starting the program and advancing to the appropriate
+source line, GDB was asked to step into libstdc++; a "finish" command
+was issued, returning a value.  The fact that a value was returned is
+very important.  GDB was then used to step back into libstdc++.  A
+breakpoint was set on a source line in the library after which a "run"
+command was issued.
+
+Frame #19 shows a call to objfile_purge_solibs.  It's aptly named.
+
+Frame #7 is a call to the destructor for one of the objfile solibs; it
+turned out to be the one for libstdc++.
+
+Frames #6 thru #3 show various value preservation frames.  If you look
+at preserve_values() in gdb/value.c, the value history is preserved
+first, followed by internal variables, followed by values for the
+extension languages (python and guile).
+
+diff --git a/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location-lib.c b/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location-lib.c
+new file mode 100644
+--- /dev/null
++++ b/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location-lib.c
+@@ -0,0 +1,48 @@
++/* Copyright (C) 2021 Free Software Foundation, Inc.
++
++   This file is part of GDB.
++
++   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/>.  */
++
++#include "locexpr-data-member-location.h"
++
++struct A g_A = {3, 4};
++struct B g_B = { {8, 9}, 10, 11 };
++
++B *
++foo ()
++{						/* foo prologue */
++  asm ("foo_label: .globl foo_label");
++  return &g_B;					/* foo return */
++}						/* foo end */
++
++B *
++bar (B *v)
++{						/* bar prologue */
++  asm ("bar_label: .globl bar_label");
++  return v;					/* bar return */
++}						/* bar end */
++
++/* Some of the DWARF assembler procs (e.g. function_range) compile
++   this file, expecting it to be a complete program with a main()
++   function.  When IS_SHAREDLIB is NOT defined, we have main() as
++   defined below.  */
++
++#ifndef IS_SHAREDLIB
++int
++main ()
++{
++  B *b = foo ();
++}
++#endif
+diff --git a/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location-main.c b/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location-main.c
+new file mode 100644
+--- /dev/null
++++ b/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location-main.c
+@@ -0,0 +1,27 @@
++/* Copyright (C) 2021 Free Software Foundation, Inc.
++
++   This file is part of GDB.
++
++   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/>.  */
++
++#include "locexpr-data-member-location.h"
++
++int
++main (void)
++{
++  B *v1;
++  v1 = bar (foo ());
++
++  return 0;
++}
+diff --git a/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location.exp b/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location.exp
+new file mode 100644
+--- /dev/null
++++ b/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location.exp
+@@ -0,0 +1,349 @@
++# Copyright 2021 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/>.
++
++# This test case uses the DWARF assembler to reproduce the problem
++# described by PR28030.  The bug turned out to be that
++# FIELD_LOC_KIND_DWARF_BLOCK was not handled when recursively copying
++# a value's type when preserving the value history during the freeing
++# up of objfiles associated with a shared object.  (Yes, figuring out
++# how to make this happen in a concise test case turned out to be
++# challenging.)
++#
++# The following elements proved to be necessary for reproducing the
++# problem:
++#
++# 1) A location expression needed to be used with
++#    DW_AT_data_member_location rather than a simple offset.
++#    Moreover, this location expression needed to use opcodes
++#    which GDB's DWARF reader could not convert to a simple
++#    offset.  (Note, however, that GDB could probably be improved
++#    to handle the opcodes chosen for this test; if decode_locdesc()
++#    in dwarf2/read.c is ever updated to handle both DW_OP_pick and
++#    DW_OP_drop, then this test could end up passing even if
++#    the bug it's intended to test has not been fixed.)
++#
++# 2) The debug info containing the above DWARF info needed
++#    to be associated with a shared object since the problem
++#    occurred while GDB was preserving values during the
++#    purging of shared objects.
++#
++# 3) After performing some simple gdb commands, the program is
++#    run again.  In the course of running the objfile destructor
++#    associated with the shared object, values are preserved
++#    along with their types.  As noted earlier, it was during
++#    the recursive type copy that the bug was observed.
++#
++# Therefore, due to #2 above, this test case creates debug info
++# which is then used by a shared object.
++
++# This test can't be run on targets lacking shared library support.
++if [skip_shlib_tests] {
++    return 0
++}
++
++load_lib dwarf.exp
++
++# This test can only be run on targets which support DWARF-2 and use gas.
++if ![dwarf2_support] {
++    return 0
++}
++
++# gdb_test_file_name is the name of this file without the .exp
++# extension.  Use it to form basenames for the main program
++# and shared object.
++set main_basename ${::gdb_test_file_name}-main
++set lib_basename ${::gdb_test_file_name}-lib
++
++# We're generating DWARF assembly for the shared object; therefore,
++# the source file for the library / shared object must be listed first
++# (in the standard_testfile invocation) since ${srcfile} is used by
++# get_func_info (for determining the start, end, and length of a
++# function).
++#
++# The output of Dwarf::assemble will be placed in $lib_basename.S
++# which will be ${srcfile3} after the execution of standard_testfile.
++
++standard_testfile $lib_basename.c $main_basename.c $lib_basename.S
++
++set libsrc "${::srcdir}/${::subdir}/${::srcfile}"
++set lib_so [standard_output_file ${lib_basename}.so]
++set asm_file [standard_output_file ${::srcfile3}]
++
++# We need to know the size of some types in order to write some of the
++# debugging info that we're about to generate.  For that, we ask GDB
++# by debugging the shared object associated with this test case.
++
++# Compile the shared library: -DIS_SHAREDLIB prevents main() from
++# being defined.  Note that debugging symbols will be present for
++# this compilation.
++if {[gdb_compile_shlib $libsrc $lib_so \
++                       {additional_flags=-DIS_SHAREDLIB debug}] != ""} {
++    untested "failed to compile shared library"
++    return
++}
++
++# Start a fresh GDB and load the shared library.
++clean_restart $lib_so
++
++# Using our running GDB session, determine sizes of several types.
++set long_size [get_sizeof "long" -1]
++set addr_size [get_sizeof "void *" -1]
++set struct_A_size [get_sizeof "g_A" -1]
++set struct_B_size [get_sizeof "g_B" -1]
++
++if { $long_size == -1 || $addr_size == -1 \
++     || $struct_A_size == -1 || $struct_B_size == -1} {
++    perror "Can't determine type sizes"
++    return
++}
++
++# Retrieve struct offset of MBR in struct TP
++proc get_offsetof { tp mbr } {
++    return [get_integer_valueof "&((${tp} *) 0)->${mbr}" -1]
++}
++
++# Use running GDB session to get struct offsets
++set A_a [get_offsetof A a]
++set A_x [get_offsetof A x]
++set B_a [get_offsetof B a]
++set B_b [get_offsetof B b]
++set B_x2 [get_offsetof B x2]
++
++# Create the DWARF.
++Dwarf::assemble ${asm_file} {
++    declare_labels L
++
++    # Find start, end, and length of functions foo and bar.
++    # These calls to get_func_info will create and set variables
++    # foo_start, bar_start, foo_end, bar_end, foo_len, and
++    # bar_len.
++    #
++    # In order to get the right answers, get_func_info (and,
++    # underneath, function_range) should use the same compiler flags
++    # as those used to make a shared object.  For any targets that get
++    # this far, -fpic is probably correct.
++    #
++    # Also, it should be noted that IS_SHAREDLIB is NOT defined as one
++    # of the additional flags.  Not defining IS_SHAREDLIB will cause a
++    # main() to be defined for the compilation of the shared library
++    # source file which happens as a result of using get_func_info;
++    # this is currently required in order to this facility.
++    set flags {additional_flags=-fpic debug}
++    get_func_info foo $flags
++    get_func_info bar $flags
++
++    cu {} {
++	DW_TAG_compile_unit {
++	    {DW_AT_language @DW_LANG_C_plus_plus}
++	    {name ${::srcfile}}
++	    {stmt_list $L DW_FORM_sec_offset}
++        } {
++	    declare_labels int_label class_A_label class_B_label \
++	                   B_ptr_label
++
++	    int_label: DW_TAG_base_type {
++		{DW_AT_byte_size ${::long_size} DW_FORM_udata}
++		{DW_AT_encoding @DW_ATE_signed}
++		{DW_AT_name "int"}
++	    }
++
++	    class_A_label: DW_TAG_class_type {
++		{DW_AT_name "A"}
++		{DW_AT_byte_size ${::struct_A_size} DW_FORM_sdata}
++	    } {
++		DW_TAG_member {
++		    {DW_AT_name "a"}
++		    {DW_AT_type :$int_label}
++		    {DW_AT_data_member_location ${::A_a} DW_FORM_udata}
++		}
++		DW_TAG_member {
++		    {DW_AT_name "x"}
++		    {DW_AT_type :$int_label}
++		    {DW_AT_data_member_location ${::A_x} DW_FORM_udata}
++		}
++	    }
++
++	    class_B_label: DW_TAG_class_type {
++		{DW_AT_name "B"}
++		{DW_AT_byte_size ${::struct_B_size} DW_FORM_sdata}
++	    } {
++		# While there are easier / better ways to specify an
++		# offset used by DW_AT_data_member_location than that
++		# used below, we need a location expression here in
++		# order to reproduce the bug.  Moreover, this location
++		# expression needs to use opcodes that aren't handled
++		# by decode_locdesc() in dwarf2/read.c; if we use
++		# opcodes that _are_ handled by that function, the
++		# location expression will be converted into a simple
++		# offset - which will then (again) not reproduce the
++		# bug.  At the time that this test was written,
++		# neither DW_OP_pick nor DW_OP_drop were being handled
++		# by decode_locdesc(); this is why those opcodes were
++		# chosen.
++		DW_TAG_inheritance {
++		    {DW_AT_type :$class_A_label}
++		    {DW_AT_data_member_location {
++			DW_OP_constu ${::B_a}
++			DW_OP_plus
++			DW_OP_pick 0
++			DW_OP_drop} SPECIAL_expr}
++		    {DW_AT_accessibility 1 DW_FORM_data1}
++		}
++		DW_TAG_member {
++		    {DW_AT_name "b"}
++		    {DW_AT_type :$int_label}
++		    {DW_AT_data_member_location ${::B_b} DW_FORM_udata}
++		}
++		DW_TAG_member {
++		    {DW_AT_name "x2"}
++		    {DW_AT_type :$int_label}
++		    {DW_AT_data_member_location ${::B_x2} DW_FORM_udata}
++		}
++	    }
++
++	    B_ptr_label: DW_TAG_pointer_type {
++		{DW_AT_type :$class_B_label}
++		{DW_AT_byte_size ${::addr_size} DW_FORM_sdata}
++	    }
++
++	    DW_TAG_variable {
++		{DW_AT_name "g_A"}
++		{DW_AT_type :$class_A_label}
++		{DW_AT_external 1 flag}
++		{DW_AT_location {DW_OP_addr [gdb_target_symbol "g_A"]} \
++		                 SPECIAL_expr}
++	    }
++
++	    DW_TAG_variable {
++		{DW_AT_name "g_B"}
++		{DW_AT_type :$class_B_label}
++		{DW_AT_external 1 flag}
++		{DW_AT_location {DW_OP_addr [gdb_target_symbol "g_B"]} \
++		                 SPECIAL_expr}
++	    }
++
++	    # We can't use MACRO_AT for the definitions of foo and bar
++	    # because it doesn't provide a way to pass the appropriate
++	    # flags.  Therefore, we list the name, low_pc, and high_pc
++	    # explicitly.
++	    DW_TAG_subprogram {
++		{DW_AT_name foo}
++		{DW_AT_low_pc $foo_start DW_FORM_addr}
++		{DW_AT_high_pc $foo_end DW_FORM_addr}
++		{DW_AT_type :${B_ptr_label}}
++		{DW_AT_external 1 flag}
++	    }
++
++	    DW_TAG_subprogram {
++		{DW_AT_name bar}
++		{DW_AT_low_pc $bar_start DW_FORM_addr}
++		{DW_AT_high_pc $bar_end DW_FORM_addr}
++		{DW_AT_type :${B_ptr_label}}
++		{DW_AT_external 1 flag}
++	    } {
++		DW_TAG_formal_parameter {
++		    {DW_AT_name v}
++		    {DW_AT_type :${B_ptr_label}}
++		}
++	    }
++	}
++    }
++
++    lines {version 2} L {
++	include_dir "${::srcdir}/${::subdir}"
++	file_name "${::srcfile}" 1
++
++	# Generate a line table program.
++	program {
++	    {DW_LNE_set_address $foo_start}
++	    {line [gdb_get_line_number "foo prologue"]}
++	    {DW_LNS_copy}
++	    {DW_LNE_set_address foo_label}
++	    {line [gdb_get_line_number "foo return"]}
++	    {DW_LNS_copy}
++	    {line [gdb_get_line_number "foo end"]}
++	    {DW_LNS_copy}
++	    {DW_LNE_set_address $foo_end}
++	    {DW_LNS_advance_line 1}
++	    {DW_LNS_copy}
++	    {DW_LNE_end_sequence}
++
++	    {DW_LNE_set_address $bar_start}
++	    {line [gdb_get_line_number "bar prologue"]}
++	    {DW_LNS_copy}
++	    {DW_LNE_set_address bar_label}
++	    {line [gdb_get_line_number "bar return"]}
++	    {DW_LNS_copy}
++	    {line [gdb_get_line_number "bar end"]}
++	    {DW_LNS_copy}
++	    {DW_LNE_set_address $bar_end}
++	    {DW_LNS_advance_line 1}
++	    {DW_LNS_copy}
++	    {DW_LNE_end_sequence}
++	}
++    }
++}
++
++# Compile the shared object again, but this time include / use the
++# DWARF info that we've created above.  Note that (again)
++# -DIS_SHAREDLIB is used to prevent inclusion of main() in the shared
++# object.  Also note the use of the "nodebug" option.  Any debugging
++# information that we need will be provided by the DWARF info created
++# above.
++if {[gdb_compile_shlib [list $libsrc $asm_file] $lib_so \
++                       {additional_flags=-DIS_SHAREDLIB nodebug}] != ""} {
++    untested "failed to compile shared library"
++    return
++}
++
++# Compile the main program for use with the shared object.
++if [prepare_for_testing "failed to prepare" ${testfile} \
++                        ${::srcfile2} [list debug shlib=$lib_so]] {
++    return -1
++}
++
++# Do whatever is necessary to make sure that the shared library is
++# loaded for remote targets.
++gdb_load_shlib ${lib_so}
++
++if ![runto_main] then {
++    fail "can't run to main"
++    return
++}
++
++# Step into foo so that we can finish out of it.
++gdb_test "step" "foo .. at .* foo end.*" "step into foo"
++
++# Finishing out of foo will create a value that will later need to
++# be preserved when restarting the program.
++gdb_test "finish" "= \\(class B \\*\\) ${::hex} .*" "finish out of foo"
++
++# Dereferencing and printing the return value isn't necessary
++# for reproducing the bug, but we should make sure that the
++# return value is what we expect it to be.
++gdb_test "p *$" { = {<A> = {a = 8, x = 9}, b = 10, x2 = 11}} \
++         "dereference return value"
++
++# The original PR28030 reproducer stepped back into the shared object,
++# so we'll do the same here:
++gdb_test "step" "bar \\(.*" "step into bar"
++
++# We don't want a clean restart here since that will be too clean.
++# The original reproducer for PR28030 set a breakpoint in the shared
++# library and then restarted via "run".  The command below does roughly
++# the same thing.  It's at this step that an internal error would
++# occur for PR28030.  The "message" argument tells runto to turn on
++# the printing of PASSes while runto is doing its job.
++runto "bar" message
+diff --git a/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location.h b/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location.h
+new file mode 100644
+--- /dev/null
++++ b/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location.h
+@@ -0,0 +1,30 @@
++/* Copyright (C) 2021 Free Software Foundation, Inc.
++
++   This file is part of GDB.
++
++   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/>.  */
++
++typedef struct A {
++    long a;
++    long x;
++} A;
++
++typedef struct B {
++    A a;
++    long b;
++    long x2;
++} B;
++
++extern B *foo ();
++extern B *bar (B *v);

diff --git a/gdb.spec b/gdb.spec
index c94263c..66b3e7a 100644
--- a/gdb.spec
+++ b/gdb.spec
@@ -1144,6 +1144,9 @@ fi
 
 %changelog
 * Thu Sep 30 2021 Alexandra Hájková <ahajkova@redhat.com> - 10.2-9
+- Backport test for RHBZ 1976887 (Kevin Buettner).
+
+* Thu Sep 30 2021 Alexandra Hájková <ahajkova@redhat.com> - 10.2-9
 - Backport upstream patch which fixes internal-error: Unexpected
   type field location kind (RHBZ 1976887, Alexandra Hájková).
 

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-06-28  0:00 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-28  0:00 [rpms/gdb] gdb-17.2-rebase-f44: Backport test for RHBZ 1976887 (Kevin Buettner) 

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox