From 573269a87c89ae866db556428fe9ea63d6c4db5f Mon Sep 17 00:00:00 2001 From: Lancelot SIX Date: Tue, 11 Jan 2022 10:10:11 -0500 Subject: 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 --- gdb/infcall.c | 49 ++++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 21 deletions(-) (limited to 'gdb/infcall.c') diff --git a/gdb/infcall.c b/gdb/infcall.c index 05cf18f..8e89629 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 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 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 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 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 finalizing + = call_thread->release_thread_fsm (); + call_thread->set_thread_fsm (std::move (saved_sm)); + + finalizing->clean_up (call_thread.get ()); + } } } -- cgit v1.1