summaryrefslogtreecommitdiff
path: root/gdb/infcall.c
diff options
context:
space:
mode:
authorLancelot SIX <lancelot.six@amd.com>2022-01-11 10:10:11 -0500
committerLancelot SIX <lancelot.six@amd.com>2022-02-07 06:12:06 -0500
commit573269a87c89ae866db556428fe9ea63d6c4db5f (patch)
treeeb6f3111a711e0609ee6db4ff25e17d3ae889194 /gdb/infcall.c
parentd08cbc5d3203118da5583296e49273cf82378042 (diff)
downloadbinutils-gdb-573269a87c89ae866db556428fe9ea63d6c4db5f.tar.gz
gdb: make thread_info::m_thread_fsm a std::unique_ptr
While working on function calls, I realized that the thread_fsm member of struct thread_info is a raw pointer to a resource it owns. This commit changes the type of the thread_fsm member to a std::unique_ptr in order to signify this ownership relationship and slightly ease resource management (no need to manually call delete). To ensure consistent use, the field is made a private member (m_thread_fsm). The setter method (set_thread_fsm) can then check that it is incorrect to associate a FSM to a thread_info object if another one is already in place. This is ensured by an assertion. The function run_inferior_call takes an argument as a pointer to a call_thread_fsm and installs it in it in a thread_info instance. Also change this function's signature to accept a unique_ptr in order to signify that the ownership of the call_thread_fsm is transferred during the call. No user visible change expected after this commit. Tested on x86_64-linux with no regression observed. Change-Id: Ia1224f72a4afa247801ce6650ce82f90224a9ae8
Diffstat (limited to 'gdb/infcall.c')
-rw-r--r--gdb/infcall.c49
1 files changed, 28 insertions, 21 deletions
diff --git a/gdb/infcall.c b/gdb/infcall.c
index 05cf18f0a7f..8e896296b96 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -574,7 +574,7 @@ call_thread_fsm::should_notify_stop ()
thrown errors. The caller should rethrow if there's an error. */
static struct gdb_exception
-run_inferior_call (struct call_thread_fsm *sm,
+run_inferior_call (std::unique_ptr<call_thread_fsm> sm,
struct thread_info *call_thread, CORE_ADDR real_pc)
{
struct gdb_exception caught_error;
@@ -597,9 +597,8 @@ run_inferior_call (struct call_thread_fsm *sm,
clear_proceed_status (0);
/* Associate the FSM with the thread after clear_proceed_status
- (otherwise it'd clear this FSM), and before anything throws, so
- we don't leak it (and any resources it manages). */
- call_thread->thread_fsm = sm;
+ (otherwise it'd clear this FSM). */
+ call_thread->set_thread_fsm (std::move (sm));
disable_watchpoints_before_interactive_call_start ();
@@ -1251,12 +1250,9 @@ call_function_by_hand_dummy (struct value *function,
just below is the place to chop this function in two.. */
{
- struct thread_fsm *saved_sm;
- struct call_thread_fsm *sm;
-
/* Save the current FSM. We'll override it. */
- saved_sm = call_thread->thread_fsm;
- call_thread->thread_fsm = NULL;
+ std::unique_ptr<thread_fsm> saved_sm = call_thread->release_thread_fsm ();
+ struct call_thread_fsm *sm;
/* Save this thread's ptid, we need it later but the thread
may have exited. */
@@ -1273,17 +1269,19 @@ call_function_by_hand_dummy (struct value *function,
values_type,
return_method != return_method_normal,
struct_addr);
-
- e = run_inferior_call (sm, call_thread.get (), real_pc);
+ {
+ std::unique_ptr<call_thread_fsm> sm_up (sm);
+ e = run_inferior_call (std::move (sm_up), call_thread.get (), real_pc);
+ }
gdb::observers::inferior_call_post.notify (call_thread_ptid, funaddr);
if (call_thread->state != THREAD_EXITED)
{
/* The FSM should still be the same. */
- gdb_assert (call_thread->thread_fsm == sm);
+ gdb_assert (call_thread->thread_fsm () == sm);
- if (call_thread->thread_fsm->finished_p ())
+ if (call_thread->thread_fsm ()->finished_p ())
{
struct value *retval;
@@ -1297,11 +1295,16 @@ call_function_by_hand_dummy (struct value *function,
/* Get the return value. */
retval = sm->return_value;
- /* Clean up / destroy the call FSM, and restore the
- original one. */
- call_thread->thread_fsm->clean_up (call_thread.get ());
- delete call_thread->thread_fsm;
- call_thread->thread_fsm = saved_sm;
+ /* Restore the original FSM and clean up / destroh the call FSM.
+ Doing it in this order ensures that if the call to clean_up
+ throws, the original FSM is properly restored. */
+ {
+ std::unique_ptr<thread_fsm> finalizing
+ = call_thread->release_thread_fsm ();
+ call_thread->set_thread_fsm (std::move (saved_sm));
+
+ finalizing->clean_up (call_thread.get ());
+ }
maybe_remove_breakpoints ();
@@ -1315,9 +1318,13 @@ call_function_by_hand_dummy (struct value *function,
/* Didn't complete. Clean up / destroy the call FSM, and restore the
previous state machine, and handle the error. */
- call_thread->thread_fsm->clean_up (call_thread.get ());
- delete call_thread->thread_fsm;
- call_thread->thread_fsm = saved_sm;
+ {
+ std::unique_ptr<thread_fsm> finalizing
+ = call_thread->release_thread_fsm ();
+ call_thread->set_thread_fsm (std::move (saved_sm));
+
+ finalizing->clean_up (call_thread.get ());
+ }
}
}