Skip to content

Commit 49fa133

Browse files
committed
[gdb/symtab] Fix segfault in search_one_symtab
PR28539 describes a segfault in lambda function search_one_symtab due to psymbol_functions::expand_symtabs_matching calling expansion_notify with a nullptr symtab: ... struct compunit_symtab *symtab = psymtab_to_symtab (objfile, ps); if (expansion_notify != NULL) if (!expansion_notify (symtab)) return false; ... This happens as follows. The partial symtab ps is a dwarf2_include_psymtab for some header file: ... (gdb) p ps.filename $5 = 0x64fcf80 "/usr/include/c++/11/bits/stl_construct.h" ... The includer of ps is a shared symtab for a partial unit, with as user: ... (gdb) p ps.includer().user.filename $11 = 0x64fc9f0 \ "/usr/src/debug/llvm13-13.0.0-1.2.x86_64/tools/clang/lib/AST/Decl.cpp" ... The call to psymtab_to_symtab expands the Decl.cpp symtab (and consequently the shared symtab), but returns nullptr because: ... struct dwarf2_include_psymtab : public partial_symtab { ... compunit_symtab *get_compunit_symtab (struct objfile *objfile) const override { return nullptr; } ... Fix this by returning the Decl.cpp symtab instead, which fixes the segfault in the PR. Tested on x86_64-linux. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28539
1 parent 8fee99c commit 49fa133

File tree

3 files changed

+105
-1
lines changed

3 files changed

+105
-1
lines changed

gdb/dwarf2/read.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5787,7 +5787,10 @@ struct dwarf2_include_psymtab : public partial_symtab
57875787

57885788
compunit_symtab *get_compunit_symtab (struct objfile *objfile) const override
57895789
{
5790-
return nullptr;
5790+
compunit_symtab *cust = includer ()->get_compunit_symtab (objfile);
5791+
while (cust != nullptr && cust->user != nullptr)
5792+
cust = cust->user;
5793+
return cust;
57915794
}
57925795

57935796
private:

gdb/psymtab.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,6 +1152,8 @@ psymbol_functions::expand_symtabs_matching
11521152
struct compunit_symtab *symtab =
11531153
psymtab_to_symtab (objfile, ps);
11541154

1155+
gdb_assert (symtab != nullptr);
1156+
11551157
if (expansion_notify != NULL)
11561158
if (!expansion_notify (symtab))
11571159
return false;
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Copyright 2021 Free Software Foundation, Inc.
2+
3+
# This program is free software; you can redistribute it and/or modify
4+
# it under the terms of the GNU General Public License as published by
5+
# the Free Software Foundation; either version 3 of the License, or
6+
# (at your option) any later version.
7+
#
8+
# This program is distributed in the hope that it will be useful,
9+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
# GNU General Public License for more details.
12+
#
13+
# You should have received a copy of the GNU General Public License
14+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
15+
16+
# Lookup a type in a partial unit with DW_AT_stmt_list.
17+
#
18+
# The test-case is setup such that the partial symtab expansion route is
19+
# .h partial symtab -> shared partial symtab -> toplevel symtab.
20+
#
21+
# That is, the partial symtabs (as displayed by maint print objfiles) are:
22+
#
23+
# ../sysdeps/x86_64/crtn.S at 0x3d944e0^M
24+
# elf-init.c at 0x3d94440^M
25+
# dw2-symtab-includes.h at 0x3d7c7a0^M
26+
# <unknown> at 0x31ef870^M
27+
# bla.c at 0x33985f0^M
28+
# ../sysdeps/x86_64/crti.S at 0x33e9a00^M
29+
# init.c at 0x33fa600^M
30+
# ../sysdeps/x86_64/start.S at 0x33f3fd0^M
31+
#
32+
# and the expansion of dw2-symtab-includes.h triggers the expansion of its
33+
# includer <unknown>, which triggers expansion of user bla.c.
34+
#
35+
# The problem in PR28539 was that after expansion of dw2-symtab-includes.h
36+
# the expansion_notify function in psymbol_functions::expand_symtabs_matching
37+
# should be called with the bla.c symtab, but instead it got called with
38+
# nullptr, which caused a segfault.
39+
40+
load_lib dwarf.exp
41+
42+
# This test can only be run on targets which support DWARF-2 and use gas.
43+
require dwarf2_support 1
44+
45+
standard_testfile main.c .S
46+
47+
# Create the DWARF.
48+
set asm_file [standard_output_file $srcfile2]
49+
Dwarf::assemble $asm_file {
50+
declare_labels partial_label lines_label
51+
global srcdir subdir srcfile
52+
53+
cu {} {
54+
partial_label: partial_unit {
55+
{stmt_list ${lines_label} DW_FORM_sec_offset}
56+
} {
57+
DW_TAG_base_type {
58+
{DW_AT_byte_size 4 DW_FORM_sdata}
59+
{DW_AT_encoding @DW_ATE_signed}
60+
{DW_AT_name myint}
61+
}
62+
}
63+
}
64+
65+
cu {} {
66+
compile_unit {
67+
{language @DW_LANG_C}
68+
{DW_AT_name bla.c}
69+
} {
70+
imported_unit {
71+
{import $partial_label ref_addr}
72+
}
73+
}
74+
}
75+
76+
lines {version 2} lines_label {
77+
include_dir "${srcdir}/${subdir}"
78+
file_name "dw2-symtab-includes.h" 1
79+
program {
80+
{DW_LNS_advance_line 1}
81+
}
82+
}
83+
}
84+
85+
if { [prepare_for_testing "failed to prepare" $testfile \
86+
"${asm_file} ${srcfile}" {}] } {
87+
return -1
88+
}
89+
90+
# Check that no symtabs are expanded.
91+
set test "no symtabs expanded"
92+
if { [readnow] } {
93+
unsupported $test
94+
} else {
95+
gdb_test_no_output "maint info symtabs" $test
96+
}
97+
98+
# Lookup myint. Regression test for PR28539.
99+
gdb_test "ptype myint" "type = myint"

0 commit comments

Comments
 (0)