106 lines
4.1 KiB
Diff
106 lines
4.1 KiB
Diff
|
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||
|
From: Kevin Buettner <kevinb@redhat.com>
|
||
|
Date: Mon, 2 Oct 2023 15:05:23 -0700
|
||
|
Subject: gdb-rhbz1773651-gdb-index-internal-error.patch
|
||
|
|
||
|
;; Backport upstream patch which prevents internal error when
|
||
|
;; generating a gdb-index file (RH BZ 1773651).
|
||
|
|
||
|
Throw error when creating an overly large gdb-index file
|
||
|
|
||
|
The header in a .gdb_index section uses 32-bit unsigned offsets to
|
||
|
refer to other areas of the section. Thus, there is a size limit of
|
||
|
2^32-1 which is currently unaccounted for by GDB's code for outputting
|
||
|
these sections.
|
||
|
|
||
|
At the moment, when GDB creates an overly large section, it will exit
|
||
|
abnormally due to an internal error, which is caused by a failed
|
||
|
assert in assert_file_size, which in turn is called from
|
||
|
write_gdbindex_1, both of which are in gdb/dwarf2/index-write.c.
|
||
|
|
||
|
This is what happens when that assert fails:
|
||
|
|
||
|
$ gdb -q -nx -iex 'set auto-load no' -iex 'set debuginfod enabled off' -ex file ./libgraph_tool_inference.so -ex "save gdb-index `pwd`/"
|
||
|
Reading symbols from ./libgraph_tool_inference.so...
|
||
|
No executable file now.
|
||
|
Discard symbol table from `libgraph_tool_inference.so'? (y or n) n
|
||
|
Not confirmed.
|
||
|
../../gdb/dwarf2/index-write.c:1069: internal-error: assert_file_size: Assertion `file_size == expected_size' failed.
|
||
|
A problem internal to GDB has been detected,
|
||
|
further debugging may prove unreliable.
|
||
|
----- Backtrace -----
|
||
|
0x55fddb4d78b0 gdb_internal_backtrace_1
|
||
|
../../gdb/bt-utils.c:122
|
||
|
0x55fddb4d78b0 _Z22gdb_internal_backtracev
|
||
|
../../gdb/bt-utils.c:168
|
||
|
0x55fddb98b5d4 internal_vproblem
|
||
|
../../gdb/utils.c:396
|
||
|
0x55fddb98b8de _Z15internal_verrorPKciS0_P13__va_list_tag
|
||
|
../../gdb/utils.c:476
|
||
|
0x55fddbb71654 _Z18internal_error_locPKciS0_z
|
||
|
../../gdbsupport/errors.cc:58
|
||
|
0x55fddb5a0f23 assert_file_size
|
||
|
../../gdb/dwarf2/index-write.c:1069
|
||
|
0x55fddb5a1ee0 assert_file_size
|
||
|
/usr/include/c++/13/bits/stl_iterator.h:1158
|
||
|
0x55fddb5a1ee0 write_gdbindex_1
|
||
|
../../gdb/dwarf2/index-write.c:1119
|
||
|
0x55fddb5a51be write_gdbindex
|
||
|
../../gdb/dwarf2/index-write.c:1273
|
||
|
[...]
|
||
|
---------------------
|
||
|
../../gdb/dwarf2/index-write.c:1069: internal-error: assert_file_size: Assertion `file_size == expected_size' failed.
|
||
|
|
||
|
This problem was encountered while building the python-graph-tool
|
||
|
package on Fedora. The Fedora bugzilla bug can be found here:
|
||
|
|
||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1773651
|
||
|
|
||
|
This commit prevents the internal error from occurring by calling error()
|
||
|
when the file size exceeds 2^32-1.
|
||
|
|
||
|
Using a gdb built with this commit, I now see this behavior instead:
|
||
|
|
||
|
$ gdb -q -nx -iex 'set auto-load no' -iex 'set debuginfod enabled off' -ex file ./libgraph_tool_inference.so -ex "save gdb-index `pwd`/"
|
||
|
Reading symbols from ./libgraph_tool_inference.so...
|
||
|
No executable file now.
|
||
|
Discard symbol table from `/mesquite2/fedora-bugs/1773651/libgraph_tool_inference.so'? (y or n) n
|
||
|
Not confirmed.
|
||
|
Error while writing index for `/mesquite2/fedora-bugs/1773651/libgraph_tool_inference.so': gdb-index maximum file size of 4294967295 exceeded
|
||
|
(gdb)
|
||
|
|
||
|
I wish I could provide a test case, but due to the sizes of both the
|
||
|
input and output files, I think that testing resources would be
|
||
|
strained or exceeded in many environments.
|
||
|
|
||
|
My testing on Fedora 38 shows no regressions.
|
||
|
|
||
|
Approved-by: Tom Tromey <tom@tromey.com>
|
||
|
|
||
|
diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c
|
||
|
--- a/gdb/dwarf2/index-write.c
|
||
|
+++ b/gdb/dwarf2/index-write.c
|
||
|
@@ -1082,7 +1082,7 @@ write_gdbindex_1 (FILE *out_file,
|
||
|
{
|
||
|
data_buf contents;
|
||
|
const offset_type size_of_header = 6 * sizeof (offset_type);
|
||
|
- offset_type total_len = size_of_header;
|
||
|
+ size_t total_len = size_of_header;
|
||
|
|
||
|
/* The version number. */
|
||
|
contents.append_offset (8);
|
||
|
@@ -1109,6 +1109,13 @@ write_gdbindex_1 (FILE *out_file,
|
||
|
|
||
|
gdb_assert (contents.size () == size_of_header);
|
||
|
|
||
|
+ /* The maximum size of an index file is limited by the maximum value
|
||
|
+ capable of being represented by 'offset_type'. Throw an error if
|
||
|
+ that length has been exceeded. */
|
||
|
+ size_t max_size = ~(offset_type) 0;
|
||
|
+ if (total_len > max_size)
|
||
|
+ error (_("gdb-index maximum file size of %zu exceeded"), max_size);
|
||
|
+
|
||
|
contents.file_write (out_file);
|
||
|
cu_list.file_write (out_file);
|
||
|
types_cu_list.file_write (out_file);
|