From: Tom Tromey <tromey@adacore.com>
To: Tom Tromey <tromey@adacore.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH 1/3] Add virtual destructor to dwarf2_per_cu_data
Date: Thu, 06 May 2021 11:23:41 -0600 [thread overview]
Message-ID: <87mtt7pyhu.fsf@tromey.com> (raw)
In-Reply-To: <87r1imsebb.fsf@tromey.com> (Tom Tromey's message of "Tue, 04 May 2021 09:34:32 -0600")
Tom> I'm thinking that instead I should add a custom deleter for these
Tom> objects that knows to cast to signatured_type when appropriate. This
Tom> would avoid a vtable pointer just to hold the destructor.
Here's the patch.
Tom
commit 25e4481af0d85f3c22c824323c42bc23438c1cbf
Author: Tom Tromey <tromey@adacore.com>
Date: Mon May 3 12:42:58 2021 -0600
Change how dwarf2_per_cu_data is deleted
Address sanitizer pointed out that the patch to use 'delete' for
dwarf2_per_cu_data introduced a bug -- now it is possible to delete a
signatured_type using a pointer to its base class.
This patch fixes the problem by introducing a deleter and a unique_ptr
specialization. A virtual destructor would be more ordinary here, but
it seemed wasteful to add a vtable just for this purpose. If virtual
methods are ever needed here, we can revisit this.
2021-05-06 Tom Tromey <tromey@adacore.com>
* dwarf2/read.h (struct dwarf2_per_cu_data_deleter: New.
(dwarf2_per_cu_data_up): New typedef.
(struct dwarf2_per_bfd) <allocate_per_cu>: Change return type.
<all_comp_units>: Use dwarf2_per_cu_data_up.
* dwarf2/read.c (dwarf2_per_cu_data::operator()): New function.
(dwarf2_per_bfd::allocate_per_cu): Return dwarf2_per_cu_data_up.
(create_cu_from_index_list): Likewise.
(create_signatured_type_table_from_index)
(create_cus_from_debug_names_list, add_type_unit)
(read_comp_units_from_section): Update.
(dwarf2_find_containing_comp_unit): Change type of all_comp_units.
(run_test): Update.
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 187249db47e..78a3dadbdd5 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,18 @@
+2021-05-06 Tom Tromey <tromey@adacore.com>
+
+ * dwarf2/read.h (struct dwarf2_per_cu_data_deleter: New.
+ (dwarf2_per_cu_data_up): New typedef.
+ (struct dwarf2_per_bfd) <allocate_per_cu>: Change return type.
+ <all_comp_units>: Use dwarf2_per_cu_data_up.
+ * dwarf2/read.c (dwarf2_per_cu_data::operator()): New function.
+ (dwarf2_per_bfd::allocate_per_cu): Return dwarf2_per_cu_data_up.
+ (create_cu_from_index_list): Likewise.
+ (create_signatured_type_table_from_index)
+ (create_cus_from_debug_names_list, add_type_unit)
+ (read_comp_units_from_section): Update.
+ (dwarf2_find_containing_comp_unit): Change type of all_comp_units.
+ (run_test): Update.
+
2021-05-06 Andrew Burgess <andrew.burgess@embecosm.com>
* guile/scm-breakpoint.c (bpscm_print_breakpoint_smob): Only print
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 5796cf1730b..e1965c193ed 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1760,6 +1760,17 @@ dwarf2_queue_item::~dwarf2_queue_item ()
}
}
+/* See dwarf2/read.h. */
+
+void
+dwarf2_per_cu_data_deleter::operator() (dwarf2_per_cu_data *data)
+{
+ if (data->is_debug_types)
+ delete static_cast<signatured_type *> (data);
+ else
+ delete data;
+}
+
/* The return type of find_file_and_directory. Note, the enclosed
string pointers are only valid while this object is valid. */
@@ -2522,10 +2533,10 @@ dw2_instantiate_symtab (dwarf2_per_cu_data *per_cu,
/* See read.h. */
-std::unique_ptr<dwarf2_per_cu_data>
+dwarf2_per_cu_data_up
dwarf2_per_bfd::allocate_per_cu ()
{
- std::unique_ptr<dwarf2_per_cu_data> result (new dwarf2_per_cu_data);
+ dwarf2_per_cu_data_up result (new dwarf2_per_cu_data);
result->per_bfd = this;
result->index = m_num_psymtabs++;
return result;
@@ -2546,13 +2557,13 @@ dwarf2_per_bfd::allocate_signatured_type ()
/* Return a new dwarf2_per_cu_data allocated on the per-bfd
obstack, and constructed with the specified field values. */
-static std::unique_ptr<dwarf2_per_cu_data>
+static dwarf2_per_cu_data_up
create_cu_from_index_list (dwarf2_per_bfd *per_bfd,
struct dwarf2_section_info *section,
int is_dwz,
sect_offset sect_off, ULONGEST length)
{
- std::unique_ptr<dwarf2_per_cu_data> the_cu = per_bfd->allocate_per_cu ();
+ dwarf2_per_cu_data_up the_cu = per_bfd->allocate_per_cu ();
the_cu->sect_off = sect_off;
the_cu->length = length;
the_cu->section = section;
@@ -2580,7 +2591,7 @@ create_cus_from_index_list (dwarf2_per_bfd *per_bfd,
ULONGEST length = extract_unsigned_integer (cu_list + 8, 8, BFD_ENDIAN_LITTLE);
cu_list += 2 * 8;
- std::unique_ptr<dwarf2_per_cu_data> per_cu
+ dwarf2_per_cu_data_up per_cu
= create_cu_from_index_list (per_bfd, section, is_dwz, sect_off,
length);
per_bfd->all_comp_units.push_back (std::move (per_cu));
@@ -2647,7 +2658,7 @@ create_signatured_type_table_from_index
slot = htab_find_slot (sig_types_hash.get (), sig_type.get (), INSERT);
*slot = sig_type.get ();
- per_bfd->all_comp_units.push_back (std::move (sig_type));
+ per_bfd->all_comp_units.emplace_back (sig_type.release ());
}
per_bfd->signatured_types = std::move (sig_types_hash);
@@ -2699,7 +2710,7 @@ create_signatured_type_table_from_debug_names
slot = htab_find_slot (sig_types_hash.get (), sig_type.get (), INSERT);
*slot = sig_type.get ();
- per_objfile->per_bfd->all_comp_units.push_back (std::move (sig_type));
+ per_objfile->per_bfd->all_comp_units.emplace_back (sig_type.release ());
}
per_objfile->per_bfd->signatured_types = std::move (sig_types_hash);
@@ -4930,7 +4941,7 @@ create_cus_from_debug_names_list (dwarf2_per_bfd *per_bfd,
of the next CU as end of this CU. We create the CUs here with
length 0, and in cutu_reader::cutu_reader we'll fill in the
actual length. */
- std::unique_ptr<dwarf2_per_cu_data> per_cu
+ dwarf2_per_cu_data_up per_cu
= create_cu_from_index_list (per_bfd, §ion, is_dwz,
sect_off, 0);
per_bfd->all_comp_units.push_back (std::move (per_cu));
@@ -4955,7 +4966,7 @@ create_cus_from_debug_names_list (dwarf2_per_bfd *per_bfd,
if (i >= 1)
{
const ULONGEST length = sect_off_next - sect_off_prev;
- std::unique_ptr<dwarf2_per_cu_data> per_cu
+ dwarf2_per_cu_data_up per_cu
= create_cu_from_index_list (per_bfd, §ion, is_dwz,
sect_off_prev, length);
per_bfd->all_comp_units.push_back (std::move (per_cu));
@@ -6132,7 +6143,8 @@ add_type_unit (dwarf2_per_objfile *per_objfile, ULONGEST sig, void **slot)
per_objfile->resize_symtabs ();
- per_objfile->per_bfd->all_comp_units.push_back (std::move (sig_type_holder));
+ per_objfile->per_bfd->all_comp_units.emplace_back
+ (sig_type_holder.release ());
sig_type->signature = sig;
sig_type->is_debug_types = 1;
if (per_objfile->per_bfd->using_index)
@@ -7711,7 +7723,7 @@ read_comp_units_from_section (dwarf2_per_objfile *per_objfile,
while (info_ptr < section->buffer + section->size)
{
- std::unique_ptr<dwarf2_per_cu_data> this_cu;
+ dwarf2_per_cu_data_up this_cu;
sect_offset sect_off = (sect_offset) (info_ptr - section->buffer);
@@ -7732,7 +7744,7 @@ read_comp_units_from_section (dwarf2_per_objfile *per_objfile,
signatured_type *sig_ptr = sig_type.get ();
sig_type->signature = cu_header.signature;
sig_type->type_offset_in_tu = cu_header.type_cu_offset_in_tu;
- this_cu = std::move (sig_type);
+ this_cu.reset (sig_type.release ());
void **slot = htab_find_slot (types_htab.get (), sig_ptr, INSERT);
gdb_assert (slot != nullptr);
@@ -24581,7 +24593,7 @@ static int
dwarf2_find_containing_comp_unit
(sect_offset sect_off,
unsigned int offset_in_dwz,
- const std::vector<std::unique_ptr<dwarf2_per_cu_data>> &all_comp_units)
+ const std::vector<dwarf2_per_cu_data_up> &all_comp_units)
{
int low, high;
@@ -24647,13 +24659,13 @@ namespace find_containing_comp_unit {
static void
run_test ()
{
- std::unique_ptr<dwarf2_per_cu_data> one (new dwarf2_per_cu_data);
+ dwarf2_per_cu_data_up one (new dwarf2_per_cu_data);
dwarf2_per_cu_data *one_ptr = one.get ();
- std::unique_ptr<dwarf2_per_cu_data> two (new dwarf2_per_cu_data);
+ dwarf2_per_cu_data_up two (new dwarf2_per_cu_data);
dwarf2_per_cu_data *two_ptr = two.get ();
- std::unique_ptr<dwarf2_per_cu_data> three (new dwarf2_per_cu_data);
+ dwarf2_per_cu_data_up three (new dwarf2_per_cu_data);
dwarf2_per_cu_data *three_ptr = three.get ();
- std::unique_ptr<dwarf2_per_cu_data> four (new dwarf2_per_cu_data);
+ dwarf2_per_cu_data_up four (new dwarf2_per_cu_data);
dwarf2_per_cu_data *four_ptr = four.get ();
one->length = 5;
@@ -24666,7 +24678,7 @@ run_test ()
four->length = 7;
four->is_dwz = 1;
- std::vector<std::unique_ptr<dwarf2_per_cu_data>> units;
+ std::vector<dwarf2_per_cu_data_up> units;
units.push_back (std::move (one));
units.push_back (std::move (two));
units.push_back (std::move (three));
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 80f0e3ee13b..756d1934ca0 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -74,6 +74,20 @@ struct dwarf2_queue_item
enum language pretend_language;
};
+/* A deleter for dwarf2_per_cu_data that knows to downcast to
+ signatured_type as appropriate. This approach lets us avoid a
+ virtual destructor, which saves a bit of space. */
+
+struct dwarf2_per_cu_data_deleter
+{
+ void operator() (dwarf2_per_cu_data *data);
+};
+
+/* A specialization of unique_ptr for dwarf2_per_cu_data and
+ subclasses. */
+typedef std::unique_ptr<dwarf2_per_cu_data, dwarf2_per_cu_data_deleter>
+ dwarf2_per_cu_data_up;
+
/* Some DWARF data can be shared across objfiles who share the same BFD,
this data is stored in this object.
@@ -103,7 +117,7 @@ struct dwarf2_per_bfd
/* A convenience function to allocate a dwarf2_per_cu_data. The
returned object has its "index" field set properly. The object
is allocated on the dwarf2_per_bfd obstack. */
- std::unique_ptr<dwarf2_per_cu_data> allocate_per_cu ();
+ dwarf2_per_cu_data_up allocate_per_cu ();
/* A convenience function to allocate a signatured_type. The
returned object has its "index" field set properly. The object
@@ -154,7 +168,7 @@ struct dwarf2_per_bfd
/* Table of all the compilation units. This is used to locate
the target compilation unit of a particular reference. */
- std::vector<std::unique_ptr<dwarf2_per_cu_data>> all_comp_units;
+ std::vector<dwarf2_per_cu_data_up> all_comp_units;
/* Table of struct type_unit_group objects.
The hash key is the DW_AT_stmt_list value. */
next prev parent reply other threads:[~2021-05-06 17:23 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-03 19:32 [PATCH 0/3] Fix some sanitizer errors Tom Tromey
2021-05-03 19:32 ` [PATCH 1/3] Add virtual destructor to dwarf2_per_cu_data Tom Tromey
2021-05-04 15:34 ` Tom Tromey
2021-05-06 17:23 ` Tom Tromey [this message]
2021-05-03 19:32 ` [PATCH 2/3] Fix buffer underflow in add_path Tom Tromey
2021-05-06 14:53 ` Tom de Vries
2021-05-03 19:32 ` [PATCH 3/3] Fix ubsan build Tom Tromey
2021-05-17 18:53 ` [PATCH 0/3] Fix some sanitizer errors Tom Tromey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87mtt7pyhu.fsf@tromey.com \
--to=tromey@adacore.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).