From: Simon Marchi <simark@simark.ca>
To: Tom de Vries <tdevries@suse.de>, gdb-patches@sourceware.org
Subject: Re: [PATCH v3 1/3] [gdb] Fix segfault in for_each_block, part 1
Date: Thu, 9 Nov 2023 13:19:38 -0500 [thread overview]
Message-ID: <7a4ddb90-b040-427e-8b15-dead9e4d6a81@simark.ca> (raw)
In-Reply-To: <20231109150021.5504-2-tdevries@suse.de>
On 11/9/23 10:00, Tom de Vries wrote:
> @@ -95,9 +95,9 @@ remove_program_space (program_space *pspace)
>
> /* See progspace.h. */
>
> -program_space::program_space (address_space *aspace_)
> +program_space::program_space (std::shared_ptr<address_space> aspace_)
> : num (++last_program_space_num),
> - aspace (aspace_)
> + aspace (std::move (aspace_))
The alignment here is not right, `aspace` should be aligned with `num`.
I asked Pedro if he had any thoughts about this patch, and he suggested
not to use shared_ptr (it's not ideal for various performance reasons,
including its use of atomic erations), but to use refcounted_object
(like you initially had) plus gdb::ref_ptr with an appropriate policy
that makes it behave like shared_ptr (deletes the object when the
refcount reaches 0). I was not really familiar with that, but I gave it
a try to avoid making you re-implement this again. Here's a patch (only
built-tested) that applies on top of your patch 1/3 that switches to
ref_ptr.
Sorry for leading you to the wrong direction again.
Simon
From 164ffe71449a53579f58be026f4619d8b73e41ff Mon Sep 17 00:00:00 2001
From: Simon Marchi <simon.marchi@efficios.com>
Date: Thu, 9 Nov 2023 16:59:46 +0000
Subject: [PATCH] fixup for patch 1, use gdb::ref_ptr
Change-Id: Iad4c992db97664b1ecb97ad60cc36eda6dfb5659
---
gdb/inferior.h | 2 +-
gdb/infrun.c | 11 +++---
gdb/progspace.c | 15 ++++----
gdb/progspace.h | 64 +++++++++++++++++++++-------------
gdb/scoped-mock-context.h | 2 +-
gdbsupport/refcounted-object.h | 17 +++++++++
6 files changed, 69 insertions(+), 42 deletions(-)
diff --git a/gdb/inferior.h b/gdb/inferior.h
index db75d6b5ecb..3f74cb5d8d4 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -584,7 +584,7 @@ class inferior : public refcounted_object,
bool removable = false;
/* The address space bound to this inferior. */
- std::shared_ptr<address_space> aspace;
+ address_space_ref_ptr aspace;
/* The program space bound to this inferior. */
struct program_space *pspace = NULL;
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 34c495097e5..95620d479d8 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -529,8 +529,7 @@ holding the child stopped. Try \"set detach-on-fork\" or \
}
else
{
- child_inf->pspace
- = new program_space (std::make_shared<address_space> ());
+ child_inf->pspace = new program_space (new_address_space ());
child_inf->aspace = child_inf->pspace->aspace;
child_inf->removable = true;
clone_program_space (child_inf->pspace, parent_inf->pspace);
@@ -609,8 +608,7 @@ holding the child stopped. Try \"set detach-on-fork\" or \
child_inf->aspace = parent_inf->aspace;
child_inf->pspace = parent_inf->pspace;
- parent_inf->pspace
- = new program_space (std::make_shared<address_space> ());
+ parent_inf->pspace = new program_space (new_address_space ());
parent_inf->aspace = parent_inf->pspace->aspace;
clone_program_space (parent_inf->pspace, child_inf->pspace);
@@ -620,8 +618,7 @@ holding the child stopped. Try \"set detach-on-fork\" or \
}
else
{
- child_inf->pspace
- = new program_space (std::make_shared<address_space> ());
+ child_inf->pspace = new program_space (new_address_space ());
child_inf->aspace = child_inf->pspace->aspace;
child_inf->removable = true;
child_inf->symfile_flags = SYMFILE_NO_READ;
@@ -1057,7 +1054,7 @@ handle_vfork_child_exec_or_exit (int exec)
pspace = inf->pspace;
inf->pspace = nullptr;
- std::shared_ptr<address_space> aspace = std::move (inf->aspace);
+ address_space_ref_ptr aspace = std::move (inf->aspace);
if (print_inferior_events)
{
diff --git a/gdb/progspace.c b/gdb/progspace.c
index 2d769134ac6..c0f4b725516 100644
--- a/gdb/progspace.c
+++ b/gdb/progspace.c
@@ -55,8 +55,8 @@ address_space::address_space ()
return a pointer to an existing address space, in case inferiors
share an address space on this target system. */
-std::shared_ptr<address_space>
-maybe_new_address_space (void)
+address_space_ref_ptr
+maybe_new_address_space ()
{
int shared_aspace
= gdbarch_has_shared_address_space (current_inferior ()->arch ());
@@ -67,7 +67,7 @@ maybe_new_address_space (void)
return program_spaces[0]->aspace;
}
- return std::make_shared<address_space> ();
+ return new_address_space ();
}
/* Start counting over from scratch. */
@@ -95,7 +95,7 @@ remove_program_space (program_space *pspace)
/* See progspace.h. */
-program_space::program_space (std::shared_ptr<address_space> aspace_)
+program_space::program_space (address_space_ref_ptr aspace_)
: num (++last_program_space_num),
aspace (std::move (aspace_))
{
@@ -409,14 +409,14 @@ update_address_spaces (void)
if (shared_aspace)
{
- auto aspace = std::make_shared<address_space> ();
+ address_space_ref_ptr aspace = new_address_space ();
for (struct program_space *pspace : program_spaces)
pspace->aspace = aspace;
}
else
for (struct program_space *pspace : program_spaces)
- pspace->aspace = std::make_shared<address_space> ();
+ pspace->aspace = new_address_space ();
for (inferior *inf : all_inferiors ())
if (gdbarch_has_global_solist (current_inferior ()->arch ()))
@@ -453,6 +453,5 @@ initialize_progspace (void)
modules have done that. Do this before
initialize_current_architecture, because that accesses the ebfd
of current_program_space. */
- current_program_space
- = new program_space (std::make_shared<address_space> ());
+ current_program_space = new program_space (new_address_space ());
}
diff --git a/gdb/progspace.h b/gdb/progspace.h
index c169690681b..163cbf6a0f8 100644
--- a/gdb/progspace.h
+++ b/gdb/progspace.h
@@ -29,6 +29,8 @@
#include "gdbsupport/next-iterator.h"
#include "gdbsupport/safe-iterator.h"
#include "gdbsupport/intrusive_list.h"
+#include "gdbsupport/refcounted-object.h"
+#include "gdbsupport/gdb_ref_ptr.h"
#include <list>
#include <vector>
@@ -43,6 +45,40 @@ struct shobj;
typedef std::list<std::unique_ptr<objfile>> objfile_list;
+/* An address space. It is used for comparing if
+ pspaces/inferior/threads see the same address space and for
+ associating caches to each address space. */
+struct address_space : public refcounted_object
+{
+ /* Create a new address space object, and add it to the list. */
+ address_space ();
+ DISABLE_COPY_AND_ASSIGN (address_space);
+
+ /* Returns the integer address space id of this address space. */
+ int num () const
+ {
+ return m_num;
+ }
+
+ /* Per aspace data-pointers required by other GDB modules. */
+ registry<address_space> registry_fields;
+
+private:
+ int m_num;
+};
+
+using address_space_ref_ptr
+ = gdb::ref_ptr<address_space,
+ refcounted_object_delete_ref_policy<address_space>>;
+
+/* Create a new address space. */
+
+static inline address_space_ref_ptr
+new_address_space ()
+{
+ return address_space_ref_ptr::new_reference (new address_space);
+}
+
/* An iterator that wraps an iterator over std::unique_ptr<objfile>,
and dereferences the returned object. This is useful for iterating
over a list of shared pointers and returning raw pointers -- which
@@ -192,7 +228,7 @@ struct program_space
{
/* Constructs a new empty program space, binds it to ASPACE, and
adds it to the program space list. */
- explicit program_space (std::shared_ptr<address_space> aspace);
+ explicit program_space (address_space_ref_ptr aspace);
/* Releases a program space, and all its contents (shared libraries,
objfiles, and any other references to the program space in other
@@ -334,7 +370,7 @@ struct program_space
are global, then this field is ignored (we don't currently
support inferiors sharing a program space if the target doesn't
make breakpoints global). */
- std::shared_ptr<address_space> aspace;
+ address_space_ref_ptr aspace;
/* True if this program space's section offsets don't yet represent
the final offsets of the "live" address space (that is, the
@@ -381,28 +417,6 @@ struct program_space
std::vector<target_section> m_target_sections;
};
-/* An address space. It is used for comparing if
- pspaces/inferior/threads see the same address space and for
- associating caches to each address space. */
-struct address_space
-{
- /* Create a new address space object, and add it to the list. */
- address_space ();
- DISABLE_COPY_AND_ASSIGN (address_space);
-
- /* Returns the integer address space id of this address space. */
- int num () const
- {
- return m_num;
- }
-
- /* Per aspace data-pointers required by other GDB modules. */
- registry<address_space> registry_fields;
-
-private:
- int m_num;
-};
-
/* The list of all program spaces. There's always at least one. */
extern std::vector<struct program_space *>program_spaces;
@@ -445,7 +459,7 @@ class scoped_restore_current_program_space
/* Maybe create a new address space object, and add it to the list, or
return a pointer to an existing address space, in case inferiors
share an address space. */
-extern std::shared_ptr<address_space> maybe_new_address_space (void);
+extern address_space_ref_ptr maybe_new_address_space ();
/* Update all program spaces matching to address spaces. The user may
have created several program spaces, and loaded executables into
diff --git a/gdb/scoped-mock-context.h b/gdb/scoped-mock-context.h
index f6bd63a5ae7..70b913b949b 100644
--- a/gdb/scoped-mock-context.h
+++ b/gdb/scoped-mock-context.h
@@ -38,7 +38,7 @@ struct scoped_mock_context
Target mock_target;
ptid_t mock_ptid {1, 1};
- program_space mock_pspace {std::make_shared<address_space> ()};
+ program_space mock_pspace {new_address_space ()};
inferior mock_inferior {mock_ptid.pid ()};
thread_info mock_thread {&mock_inferior, mock_ptid};
diff --git a/gdbsupport/refcounted-object.h b/gdbsupport/refcounted-object.h
index d8fdb950043..294fd873df1 100644
--- a/gdbsupport/refcounted-object.h
+++ b/gdbsupport/refcounted-object.h
@@ -67,4 +67,21 @@ struct refcounted_object_ref_policy
}
};
+/* A policy class to interface gdb::ref_ptr with a refcounted_object, that
+ deletes the object once the refcount reaches 0.. */
+
+template<typename T>
+struct refcounted_object_delete_ref_policy
+{
+ static void incref (T *obj)
+ { obj->incref (); }
+
+ static void decref (T *obj)
+ {
+ obj->decref ();
+ if (obj->refcount () == 0)
+ delete obj;
+ }
+};
+
#endif /* COMMON_REFCOUNTED_OBJECT_H */
--
2.39.2
next prev parent reply other threads:[~2023-11-09 18:19 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-09 15:00 [PATCH v3 0/3] [gdb] Fix segfault in for_each_block Tom de Vries
2023-11-09 15:00 ` [PATCH v3 1/3] [gdb] Fix segfault in for_each_block, part 1 Tom de Vries
2023-11-09 18:19 ` Simon Marchi [this message]
2023-11-10 8:14 ` Tom de Vries
2023-11-09 15:00 ` [PATCH v3 2/3] [gdb] Eliminate local var pspace in inferior.c Tom de Vries
2023-11-09 16:31 ` Simon Marchi
2023-11-10 8:15 ` Tom de Vries
2023-11-09 15:00 ` [PATCH v3 3/3] [gdb] Fix segfault in for_each_block, part 2 Tom de Vries
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=7a4ddb90-b040-427e-8b15-dead9e4d6a81@simark.ca \
--to=simark@simark.ca \
--cc=gdb-patches@sourceware.org \
--cc=tdevries@suse.de \
/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).