From patchwork Wed May 23 23:59:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 27472 Received: (qmail 72821 invoked by alias); 23 May 2018 23:59:23 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 72801 invoked by uid 89); 23 May 2018 23:59:23 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_NUMSUBJECT, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=brobecker, U*brobecker, Brobecker, sk:brobeck X-HELO: gateway32.websitewelcome.com Received: from gateway32.websitewelcome.com (HELO gateway32.websitewelcome.com) (192.185.145.18) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 23 May 2018 23:59:19 +0000 Received: from cm14.websitewelcome.com (cm14.websitewelcome.com [100.42.49.7]) by gateway32.websitewelcome.com (Postfix) with ESMTP id 3F9B17D0F3 for ; Wed, 23 May 2018 18:59:18 -0500 (CDT) Received: from box5379.bluehost.com ([162.241.216.53]) by cmsmtp with SMTP id Ldf4fQmd95CKDLdf4ftd7n; Wed, 23 May 2018 18:59:18 -0500 X-Authority-Reason: nr=8 Received: from 174-29-44-154.hlrn.qwest.net ([174.29.44.154]:57022 helo=bapiya) by box5379.bluehost.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.89_1) (envelope-from ) id 1fLdf3-002G0I-Fx; Wed, 23 May 2018 18:59:17 -0500 From: Tom Tromey To: Sergio Durigan Junior Cc: Joel Brobecker , Keith Seitz , Tom Tromey , gdb-patches@sourceware.org, Pedro Alves Subject: Re: possible fix for PR symtab/23010 References: <87po34kzxh.fsf@tromey.com> <20180430224454.wrnu4u45o5gukrxs@adacore.com> <20180507171309.f4yjprji4g3deubw@adacore.com> <8736yp4xo8.fsf@redhat.com> Date: Wed, 23 May 2018 17:59:15 -0600 In-Reply-To: <8736yp4xo8.fsf@redhat.com> (Sergio Durigan Junior's message of "Thu, 17 May 2018 20:25:43 -0400") Message-ID: <87po1l2ab0.fsf@tromey.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) MIME-Version: 1.0 X-BWhitelist: no X-Source-L: No X-Exim-ID: 1fLdf3-002G0I-Fx X-Source-Sender: 174-29-44-154.hlrn.qwest.net (bapiya) [174.29.44.154]:57022 X-Source-Auth: tom+tromey.com X-Email-Count: 4 X-Source-Cap: ZWx5bnJvYmk7ZWx5bnJvYmk7Ym94NTM3OS5ibHVlaG9zdC5jb20= X-Local-Domain: yes >>>>> "Sergio" == Sergio Durigan Junior writes: Sergio> In either case, and speaking without much knowledge of the patch itself, Sergio> I think it should be included in 8.1.1. At least I know I will include Sergio> it in our Fedora GDB (and well, if Tom is willing to backport it, then Sergio> he'll also save me some time!). I did the backport, and mentioned it on irc, but neglected to send email. I've appended it. Sergio said he would test it against libwebkitgtk, which is a relief, since that usually causes problems for my machine. Tom commit b5aa3df7a69ed6ecf6ac046dca12b39d9533ed29 Author: Tom Tromey Date: Thu Apr 12 08:24:41 2018 -0600 Fix for dwz-related crash PR symtab/23010 reports a crash that occurs when using -readnow on a dwz-generated debuginfo file. The crash occurs because the DWARF has a partial CU with no language set, and then a full CU that references this partial CU using DW_AT_abstract_origin. In this case, the partial CU is read by dw2_expand_all_symtabs using language_minimal; but then this conflicts with the creation of the block's symbol table in the C++ CU. This patch fixes the problem by arranging for partial CUs not to be read by -readnow. I tend to think that it doesn't make sense to read a partial CU in isolation -- they should only be read when imported into some other CU. In conjunction with some other patches I am going to post, this also fixes the Rust -readnow crash that Jan reported. There are two problems with this patch: 1. It is difficult to reason about. There are many cases where I've patched the code to call init_cutu_and_read_dies with the flag set to "please do read partial units" -- but I find it difficult to be sure that this is always correct. 2. It is still missing a standalone test case. This seemed hard. 2018-05-17 Tom Tromey PR symtab/23010: * dwarf2read.c (load_cu, dw2_do_instantiate_symtab) (dw2_instantiate_symtab): Add skip_partial parameter. (dw2_find_last_source_symtab, dw2_map_expand_apply) (dw2_lookup_symbol, dw2_expand_symtabs_for_function) (dw2_expand_all_symtabs, dw2_expand_symtabs_with_fullname) (dw2_expand_symtabs_matching_one) (dw2_find_pc_sect_compunit_symtab) (dw2_debug_names_lookup_symbol) (dw2_debug_names_expand_symtabs_for_function): Update. (init_cutu_and_read_dies): Add skip_partial parameter. (process_psymtab_comp_unit, build_type_psymtabs_1) (process_skeletonless_type_unit, load_partial_comp_unit) (psymtab_to_symtab_1): Update. (load_full_comp_unit): Add skip_partial parameter. (process_imported_unit_die, dwarf2_read_addr_index) (follow_die_offset, dwarf2_fetch_die_loc_sect_off) (dwarf2_fetch_constant_bytes, dwarf2_fetch_die_type_sect_off) (read_signatured_type): Update. diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d8c2ef427a..9913c081d6 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,25 @@ +2018-05-17 Tom Tromey + + PR symtab/23010: + * dwarf2read.c (load_cu, dw2_do_instantiate_symtab) + (dw2_instantiate_symtab): Add skip_partial parameter. + (dw2_find_last_source_symtab, dw2_map_expand_apply) + (dw2_lookup_symbol, dw2_expand_symtabs_for_function) + (dw2_expand_all_symtabs, dw2_expand_symtabs_with_fullname) + (dw2_expand_symtabs_matching_one) + (dw2_find_pc_sect_compunit_symtab) + (dw2_debug_names_lookup_symbol) + (dw2_debug_names_expand_symtabs_for_function): Update. + (init_cutu_and_read_dies): Add skip_partial parameter. + (process_psymtab_comp_unit, build_type_psymtabs_1) + (process_skeletonless_type_unit, load_partial_comp_unit) + (psymtab_to_symtab_1): Update. + (load_full_comp_unit): Add skip_partial parameter. + (process_imported_unit_die, dwarf2_read_addr_index) + (follow_die_offset, dwarf2_fetch_die_loc_sect_off) + (dwarf2_fetch_constant_bytes, dwarf2_fetch_die_type_sect_off) + (read_signatured_type): Update. + 2018-05-10 Joel Brobecker PR server/23158: diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index bd2bc7d278..d4380f8335 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -2140,7 +2140,7 @@ static void create_all_comp_units (struct objfile *); static int create_all_type_units (struct objfile *); -static void load_full_comp_unit (struct dwarf2_per_cu_data *, +static void load_full_comp_unit (struct dwarf2_per_cu_data *, bool, enum language); static void process_full_comp_unit (struct dwarf2_per_cu_data *, @@ -2204,7 +2204,7 @@ static const gdb_byte *read_and_check_comp_unit_head static void init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, struct abbrev_table *abbrev_table, - int use_existing_cu, int keep, + int use_existing_cu, int keep, bool skip_partial, die_reader_func_ftype *die_reader_func, void *data); static void init_cutu_and_read_dies_simple @@ -3055,12 +3055,12 @@ create_quick_file_names_table (unsigned int nr_initial_entries) processing PER_CU->CU. dw2_setup must have been already called. */ static void -load_cu (struct dwarf2_per_cu_data *per_cu) +load_cu (struct dwarf2_per_cu_data *per_cu, bool skip_partial) { if (per_cu->is_debug_types) load_full_type_unit (per_cu); else - load_full_comp_unit (per_cu, language_minimal); + load_full_comp_unit (per_cu, skip_partial, language_minimal); if (per_cu->cu == NULL) return; /* Dummy CU. */ @@ -3071,7 +3071,7 @@ load_cu (struct dwarf2_per_cu_data *per_cu) /* Read in the symbols for PER_CU. */ static void -dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu) +dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial) { struct cleanup *back_to; @@ -3087,7 +3087,7 @@ dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu) : (per_cu->v.psymtab == NULL || !per_cu->v.psymtab->readin)) { queue_comp_unit (per_cu, language_minimal); - load_cu (per_cu); + load_cu (per_cu, skip_partial); /* If we just loaded a CU from a DWO, and we're working with an index that may badly handle TUs, load all the TUs in that DWO as well. @@ -3116,14 +3116,14 @@ dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu) table. */ static struct compunit_symtab * -dw2_instantiate_symtab (struct dwarf2_per_cu_data *per_cu) +dw2_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial) { gdb_assert (dwarf2_per_objfile->using_index); if (!per_cu->v.quick->compunit_symtab) { struct cleanup *back_to = make_cleanup (free_cached_comp_units, NULL); scoped_restore decrementer = increment_reading_symtab (); - dw2_do_instantiate_symtab (per_cu); + dw2_do_instantiate_symtab (per_cu, skip_partial); process_cu_includes (); do_cleanups (back_to); } @@ -4002,7 +4002,7 @@ dw2_find_last_source_symtab (struct objfile *objfile) dw2_setup (objfile); index = dwarf2_per_objfile->n_comp_units - 1; - cust = dw2_instantiate_symtab (dw2_get_cutu (index)); + cust = dw2_instantiate_symtab (dw2_get_cutu (index), false); if (cust == NULL) return NULL; return compunit_primary_filetab (cust); @@ -4055,7 +4055,7 @@ dw2_map_expand_apply (struct objfile *objfile, /* This may expand more than one symtab, and we want to iterate over all of them. */ - dw2_instantiate_symtab (per_cu); + dw2_instantiate_symtab (per_cu, false); return iterate_over_some_symtabs (name, real_path, objfile->compunit_symtabs, last_made, callback); @@ -4302,7 +4302,8 @@ dw2_lookup_symbol (struct objfile *objfile, int block_index, while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL) { struct symbol *sym, *with_opaque = NULL; - struct compunit_symtab *stab = dw2_instantiate_symtab (per_cu); + struct compunit_symtab *stab = dw2_instantiate_symtab (per_cu, + false); const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab); struct block *block = BLOCKVECTOR_BLOCK (bv, block_index); @@ -4397,7 +4398,7 @@ dw2_expand_symtabs_for_function (struct objfile *objfile, func_name); while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL) - dw2_instantiate_symtab (per_cu); + dw2_instantiate_symtab (per_cu, false); } } @@ -4413,7 +4414,12 @@ dw2_expand_all_symtabs (struct objfile *objfile) { struct dwarf2_per_cu_data *per_cu = dw2_get_cutu (i); - dw2_instantiate_symtab (per_cu); + /* We don't want to directly expand a partial CU, because if we + read it with the wrong language, then assertion failures can + be triggered later on. See PR symtab/23010. So, tell + dw2_instantiate_symtab to skip partial CUs -- any important + partial CU will be read via DW_TAG_imported_unit anyway. */ + dw2_instantiate_symtab (per_cu, true); } } @@ -4450,7 +4456,7 @@ dw2_expand_symtabs_with_fullname (struct objfile *objfile, if (filename_cmp (this_fullname, fullname) == 0) { - dw2_instantiate_symtab (per_cu); + dw2_instantiate_symtab (per_cu, false); break; } } @@ -5274,7 +5280,7 @@ dw2_expand_symtabs_matching_one bool symtab_was_null = (per_cu->v.quick->compunit_symtab == NULL); - dw2_instantiate_symtab (per_cu); + dw2_instantiate_symtab (per_cu, false); if (expansion_notify != NULL && symtab_was_null @@ -5529,7 +5535,8 @@ dw2_find_pc_sect_compunit_symtab (struct objfile *objfile, paddress (get_objfile_arch (objfile), pc)); result - = recursively_find_pc_sect_compunit_symtab (dw2_instantiate_symtab (data), + = recursively_find_pc_sect_compunit_symtab (dw2_instantiate_symtab (data, + false), pc); gdb_assert (result != NULL); return result; @@ -6345,7 +6352,7 @@ dw2_debug_names_lookup_symbol (struct objfile *objfile, int block_index_int, while ((per_cu = iter.next ()) != NULL) { struct symbol *sym, *with_opaque = NULL; - struct compunit_symtab *stab = dw2_instantiate_symtab (per_cu); + struct compunit_symtab *stab = dw2_instantiate_symtab (per_cu, false); const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab); struct block *block = BLOCKVECTOR_BLOCK (bv, block_index); @@ -6404,7 +6411,7 @@ dw2_debug_names_expand_symtabs_for_function (struct objfile *objfile, struct dwarf2_per_cu_data *per_cu; while ((per_cu = iter.next ()) != NULL) - dw2_instantiate_symtab (per_cu); + dw2_instantiate_symtab (per_cu, false); } } @@ -7725,6 +7732,7 @@ static void init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, struct abbrev_table *abbrev_table, int use_existing_cu, int keep, + bool skip_partial, die_reader_func_ftype *die_reader_func, void *data) { @@ -7875,6 +7883,9 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, init_cu_die_reader (&reader, cu, section, NULL); info_ptr = read_full_die (&reader, &comp_unit_die, info_ptr, &has_children); + if (skip_partial && comp_unit_die->tag == DW_TAG_partial_unit) + return; + /* If we are in a DWO stub, process it and then read in the "real" CU/TU from the DWO file. Note that if USE_EXISTING_OK != 0, and THIS_CU->cu already contains a @@ -8379,14 +8390,14 @@ process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu, free_one_cached_comp_unit (this_cu); if (this_cu->is_debug_types) - init_cutu_and_read_dies (this_cu, NULL, 0, 0, build_type_psymtabs_reader, - NULL); + init_cutu_and_read_dies (this_cu, NULL, 0, 0, false, + build_type_psymtabs_reader, NULL); else { process_psymtab_comp_unit_data info; info.want_partial_unit = want_partial_unit; info.pretend_language = pretend_language; - init_cutu_and_read_dies (this_cu, NULL, 0, 0, + init_cutu_and_read_dies (this_cu, NULL, 0, 0, false, process_psymtab_comp_unit_reader, &info); } @@ -8562,7 +8573,7 @@ build_type_psymtabs_1 (void) } init_cutu_and_read_dies (&tu->sig_type->per_cu, abbrev_table, 0, 0, - build_type_psymtabs_reader, NULL); + false, build_type_psymtabs_reader, NULL); } do_cleanups (cleanups); @@ -8668,7 +8679,7 @@ process_skeletonless_type_unit (void **slot, void *info) *slot = entry; /* This does the job that build_type_psymtabs_1 would have done. */ - init_cutu_and_read_dies (&entry->per_cu, NULL, 0, 0, + init_cutu_and_read_dies (&entry->per_cu, NULL, 0, 0, false, build_type_psymtabs_reader, NULL); return 1; @@ -8827,7 +8838,7 @@ load_partial_comp_unit_reader (const struct die_reader_specs *reader, static void load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu) { - init_cutu_and_read_dies (this_cu, NULL, 1, 1, + init_cutu_and_read_dies (this_cu, NULL, 1, 1, false, load_partial_comp_unit_reader, NULL); } @@ -9974,7 +9985,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) return; } - dw2_do_instantiate_symtab (per_cu); + dw2_do_instantiate_symtab (per_cu, false); } /* Trivial hash function for die_info: the hash value of a DIE @@ -10043,11 +10054,12 @@ load_full_comp_unit_reader (const struct die_reader_specs *reader, static void load_full_comp_unit (struct dwarf2_per_cu_data *this_cu, + bool skip_partial, enum language pretend_language) { gdb_assert (! this_cu->is_debug_types); - init_cutu_and_read_dies (this_cu, NULL, 1, 1, + init_cutu_and_read_dies (this_cu, NULL, 1, 1, skip_partial, load_full_comp_unit_reader, &pretend_language); } @@ -10568,7 +10580,7 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu) /* If necessary, add it to the queue and load its DIEs. */ if (maybe_queue_comp_unit (cu, per_cu, cu->language)) - load_full_comp_unit (per_cu, cu->language); + load_full_comp_unit (per_cu, false, cu->language); VEC_safe_push (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs, per_cu); @@ -19654,7 +19666,7 @@ dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu, /* Note: We can't use init_cutu_and_read_dies_simple here, we need addr_base. */ - init_cutu_and_read_dies (per_cu, NULL, 0, 0, + init_cutu_and_read_dies (per_cu, NULL, 0, 0, false, dwarf2_read_addr_index_reader, &aidata); addr_base = aidata.addr_base; addr_size = aidata.addr_size; @@ -22852,7 +22864,7 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz, /* If necessary, add it to the queue and load its DIEs. */ if (maybe_queue_comp_unit (cu, per_cu, cu->language)) - load_full_comp_unit (per_cu, cu->language); + load_full_comp_unit (per_cu, false, cu->language); target_cu = per_cu->cu; } @@ -22860,7 +22872,7 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz, { /* We're loading full DIEs during partial symbol reading. */ gdb_assert (dwarf2_per_objfile->reading_partial_symbols); - load_full_comp_unit (cu->per_cu, language_minimal); + load_full_comp_unit (cu->per_cu, false, language_minimal); } *ref_cu = target_cu; @@ -22913,7 +22925,7 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off, dw2_setup (per_cu->objfile); if (per_cu->cu == NULL) - load_cu (per_cu); + load_cu (per_cu, false); cu = per_cu->cu; if (cu == NULL) { @@ -23021,7 +23033,7 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off, dw2_setup (per_cu->objfile); if (per_cu->cu == NULL) - load_cu (per_cu); + load_cu (per_cu, false); cu = per_cu->cu; if (cu == NULL) { @@ -23146,7 +23158,7 @@ dwarf2_fetch_die_type_sect_off (sect_offset sect_off, dw2_setup (per_cu->objfile); if (per_cu->cu == NULL) - load_cu (per_cu); + load_cu (per_cu, false); cu = per_cu->cu; if (!cu) return NULL; @@ -23421,7 +23433,7 @@ read_signatured_type (struct signatured_type *sig_type) gdb_assert (per_cu->is_debug_types); gdb_assert (per_cu->cu == NULL); - init_cutu_and_read_dies (per_cu, NULL, 0, 1, + init_cutu_and_read_dies (per_cu, NULL, 0, 1, false, read_signatured_type_reader, NULL); sig_type->per_cu.tu_read = 1; }