[gdb] Fix assert crashes with minidebuginfo (BZ 903522).

Jan Kratochvil jankratochvil at fedoraproject.org
Fri Feb 1 19:07:01 UTC 2013


commit 88bebb3fb19347c95716e1ae97c5dbebc33aa1bd
Author: Jan Kratochvil <jan.kratochvil at redhat.com>
Date:   Fri Feb 1 20:06:54 2013 +0100

    Fix assert crashes with minidebuginfo (BZ 903522).

 gdb-minidebuginfo-crash.patch |  142 +++++++++++++++++++++++++++++++++++++++++
 gdb.spec                      |   10 +++-
 2 files changed, 151 insertions(+), 1 deletions(-)
---
diff --git a/gdb-minidebuginfo-crash.patch b/gdb-minidebuginfo-crash.patch
new file mode 100644
index 0000000..f2f00f1
--- /dev/null
+++ b/gdb-minidebuginfo-crash.patch
@@ -0,0 +1,142 @@
+http://sourceware.org/ml/gdb-patches/2013-02/msg00016.html
+Subject: [patch] Fix assert crashes with minidebuginfo
+
+Hi Tom,
+
+original bugreport:
+	https://bugzilla.redhat.com/show_bug.cgi?id=903522
+
+in some cases GDB added separate debug info to minidebuginfo (which itself is
+a separate debug info).  separate debug info of a separate debug info is not
+supported by GDB and it caused a gdb_assert failure.
+
+So the added gdb_assert calls print such violation immediately at
+add_separate_debug_objfile, not only in a some rare case found by the
+bugreport.
+
+And I have found multiple such fragile checks in GDB so I have protected them
+all so that minidebuginfo is always only a sole separate debug info.
+
+No regressions on {x86_64,x86_64-m32,i686}-fedora19pre-linux-gnu.
+
+With the new gdb_asserts (and without the fix) GDB crashes on gdb.gdb/ tests
+due to current ncurses-libs-5.9-7.20121017.fc19.x86_64 files.
+
+
+Thanks,
+Jan
+
+
+gdb/
+2013-02-01  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	* elfread.c (elf_symfile_read): Limit separate debug info additions to
+	files with no separate debug info.
+	* objfiles.c (add_separate_debug_objfile): Add gdb_assert calls.
+	* symfile.c (read_symbols): Call find_separate_debug_file_in_section
+	only for files with no separate debug info.
+
+gdb/testsuite/
+2013-02-01  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	* gdb.base/gnu-debugdata.exp): Create ${binfile}.debug,
+	${binfile}.mini_debuginfo-debuglink, add -k to xz, use now
+	${binfile}.mini_debuginfo-debuglink and
+	${binfile}.mini_debuginfo-debuglink.xz.
+
+diff --git a/gdb/elfread.c b/gdb/elfread.c
+index 9d630cd..6ca659f 100644
+--- a/gdb/elfread.c
++++ b/gdb/elfread.c
+@@ -2427,8 +2427,18 @@ elf_symfile_read (struct objfile *objfil
+   /* If the file has its own symbol tables it has no separate debug
+      info.  `.dynsym'/`.symtab' go to MSYMBOLS, `.debug_info' goes to
+      SYMTABS/PSYMTABS.  `.gnu_debuglink' may no longer be present with
+-     `.note.gnu.build-id'.  */
+-  else if (!objfile_has_partial_symbols (objfile))
++     `.note.gnu.build-id'.
++
++     .gnu_debugdata is !objfile_has_partial_symbols because it contains only
++     .symtab, not .debug_* section.  But if we already added .gnu_debugdata as
++     an objfile via find_separate_debug_file_in_section there was no separate
++     debug info available.  Therefore do not attempt to search for another one,
++     objfile->separate_debug_objfile->separate_debug_objfile GDB guarantees to
++     be NULL and we would possibly violate it.  */
++
++  else if (!objfile_has_partial_symbols (objfile)
++	   && objfile->separate_debug_objfile == NULL
++	   && objfile->separate_debug_objfile_backlink == NULL)
+     {
+       char *debugfile, *build_id_filename;
+ 
+diff --git a/gdb/objfiles.c b/gdb/objfiles.c
+index 5232c8f..5829699 100644
+--- a/gdb/objfiles.c
++++ b/gdb/objfiles.c
+@@ -476,6 +476,9 @@ add_separate_debug_objfile (struct objfile *objfile, struct objfile *parent)
+   /* Must not be already in a list.  */
+   gdb_assert (objfile->separate_debug_objfile_backlink == NULL);
+   gdb_assert (objfile->separate_debug_objfile_link == NULL);
++  gdb_assert (objfile->separate_debug_objfile == NULL);
++  gdb_assert (parent->separate_debug_objfile_backlink == NULL);
++  gdb_assert (parent->separate_debug_objfile_link == NULL);
+ 
+   objfile->separate_debug_objfile_backlink = parent;
+   objfile->separate_debug_objfile_link = parent->separate_debug_objfile;
+diff --git a/gdb/symfile.c b/gdb/symfile.c
+index 63bf329..6f968b7 100644
+--- a/gdb/symfile.c
++++ b/gdb/symfile.c
+@@ -823,7 +823,12 @@ static void
+ read_symbols (struct objfile *objfile, int add_flags)
+ {
+   (*objfile->sf->sym_read) (objfile, add_flags);
+-  if (!objfile_has_partial_symbols (objfile))
++
++  /* find_separate_debug_file_in_section should be called only if there is
++     single binary with no existing separate debug info file.  */
++  if (!objfile_has_partial_symbols (objfile)
++      && objfile->separate_debug_objfile == NULL
++      && objfile->separate_debug_objfile_backlink == NULL)
+     {
+       bfd *abfd = find_separate_debug_file_in_section (objfile);
+       struct cleanup *cleanup = make_cleanup_bfd_unref (abfd);
+diff --git a/gdb/testsuite/gdb.base/gnu-debugdata.exp b/gdb/testsuite/gdb.base/gnu-debugdata.exp
+index f34e4e8..55aa3c6 100644
+--- a/gdb/testsuite/gdb.base/gnu-debugdata.exp
++++ b/gdb/testsuite/gdb.base/gnu-debugdata.exp
+@@ -127,14 +127,30 @@ if {[run "strip" [transform strip] \
+     return -1
+ }
+ 
++# Separate full debug info into ${binfile}.debug.
++remote_file host delete ${binfile}.debug
++if {[run "copydebug" [transform objcopy] \
++	 "--only-keep-debug ${binfile} ${binfile}.debug"]} {
++    return -1
++}
++
++# Add the .gnu_debuglink section to the .gnu_debugdata file.
++# .gnu_debuglink is normally not present in the .gnu_debugdata section but in
++# some files there may be PT_NOTE with NT_GNU_BUILD_ID and GDB could look up
++# the .debug file from it.
++if {[run "addlink" [transform objcopy] \
++	 "--add-gnu-debuglink=${binfile}.debug ${binfile}.mini_debuginfo ${binfile}.mini_debuginfo-debuglink"]} {
++    return -1
++}
++
+ # Inject the compressed data into the .gnu_debugdata section of the
+ # original binary.
+-remote_file host delete ${binfile}.mini_debuginfo.xz
+-if {[run "xz" "xz" "${binfile}.mini_debuginfo"]} {
++remote_file host delete ${binfile}.mini_debuginfo-debuglink.xz
++if {[run "xz" "xz" "-k ${binfile}.mini_debuginfo-debuglink"]} {
+     return -1
+ }
+ remote_file host delete ${binfile}.test
+-if {[run "objcopy 2" [transform objcopy] "--add-section .gnu_debugdata=${binfile}.mini_debuginfo.xz ${binfile}.strip ${binfile}.test"]} {
++if {[run "objcopy 2" [transform objcopy] "--add-section .gnu_debugdata=${binfile}.mini_debuginfo-debuglink.xz ${binfile}.strip ${binfile}.test"]} {
+     return -1
+ }
+ 
+
diff --git a/gdb.spec b/gdb.spec
index a1869bf..60f372b 100644
--- a/gdb.spec
+++ b/gdb.spec
@@ -34,7 +34,7 @@ Version: 7.5.50.20130118
 
 # The release always contains a leading reserved number, start it at 1.
 # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing.
-Release: 3%{?dist}
+Release: 4%{?dist}
 
 License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and BSD and Public Domain
 Group: Development/Debuggers
@@ -565,6 +565,10 @@ Patch818: gdb-rhbz795424-bitpos-lazyvalue.patch
 #=push
 Patch823: gdb-commonblock-pie.patch
 
+#=push
+# Fix assert crashes with minidebuginfo (BZ 903522).
+Patch824: gdb-minidebuginfo-crash.patch
+
 %if 0%{!?rhel:1} || 0%{?rhel} > 6
 # RL_STATE_FEDORA_GDB would not be found for:
 # Patch642: gdb-readline62-ask-more-rh.patch
@@ -879,6 +883,7 @@ find -name "*.info*"|xargs rm -f
 %patch817 -p1
 %patch818 -p1
 %patch823 -p1
+%patch824 -p1
 
 %patch393 -p1
 %if 0%{!?el5:1} || 0%{?scl:1}
@@ -1379,6 +1384,9 @@ fi
 %endif # 0%{!?el5:1} || "%{_target_cpu}" == "noarch"
 
 %changelog
+* Fri Feb  1 2013 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.5.50.20130118-4.fc19
+- Fix assert crashes with minidebuginfo (BZ 903522).
+
 * Fri Jan 25 2013 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.5.50.20130118-3.fc19
 - Release bump only.
 


More information about the scm-commits mailing list