From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2126) id BA8153858D20; Tue, 27 Feb 2024 17:38:23 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BA8153858D20 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1709055503; bh=yfXjCnB8ldpH/4d+syFCVYEqDxXefyUj4+vWyMgREKY=; h=From:To:Subject:Date:From; b=PcgXcmqjoWx/OgTDes/phqqaxO+gJxjHBvMU+GlFSKestx5JxaGgzANOuGkSYxpnS tOdCKi0s/vU9HoiS8lbB51lw2t+oH8X5u6Uyk3iLNdzPO3gGJJINc3ZnlvgGEP0yD1 2dL/xAtOLkL8cD+FRNSAiLl/uUuBjS2xYsg3ekUc= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Tom Tromey To: gdb-cvs@sourceware.org Subject: [binutils-gdb] Rewrite final cleanups X-Act-Checkin: binutils-gdb X-Git-Author: Tom Tromey X-Git-Refname: refs/heads/master X-Git-Oldrev: cfe51255b892962c25166cc0afd8911caf9e1e56 X-Git-Newrev: 1eae7be116ddabb13b34d2c2e8e0dc13fbae2a0d Message-Id: <20240227173823.BA8153858D20@sourceware.org> Date: Tue, 27 Feb 2024 17:38:23 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D1eae7be116dd= abb13b34d2c2e8e0dc13fbae2a0d commit 1eae7be116ddabb13b34d2c2e8e0dc13fbae2a0d Author: Tom Tromey Date: Fri Feb 23 13:10:28 2024 -0700 Rewrite final cleanups =20 This patch rewrites final cleanups to use std::function and otherwise be more C++-ish. Diff: --- gdb/compile/compile.c | 30 +++++------- gdb/debuginfod-support.c | 14 ++---- gdb/python/python.c | 4 +- gdbsupport/cleanups.cc | 122 +++++--------------------------------------= ---- gdbsupport/cleanups.h | 17 ++----- 5 files changed, 33 insertions(+), 154 deletions(-) diff --git a/gdb/compile/compile.c b/gdb/compile/compile.c index 8cb2e8ac7f1..27cff2553ee 100644 --- a/gdb/compile/compile.c +++ b/gdb/compile/compile.c @@ -427,23 +427,6 @@ compile_print_command (const char *arg, int from_tty) } } =20 -/* A cleanup function to remove a directory and all its contents. */ - -static void -do_rmdir (void *arg) -{ - const char *dir =3D (const char *) arg; - char *zap; - int wstat; - - gdb_assert (startswith (dir, TMP_PREFIX)); - zap =3D concat ("rm -rf ", dir, (char *) NULL); - wstat =3D system (zap); - if (wstat =3D=3D -1 || !WIFEXITED (wstat) || WEXITSTATUS (wstat) !=3D 0) - warning (_("Could not remove temporary directory %s"), dir); - XDELETEVEC (zap); -} - /* Return the name of the temporary directory to use for .o files, and arrange for the directory to be removed at shutdown. */ =20 @@ -465,7 +448,18 @@ get_compile_file_tempdir (void) perror_with_name (_("Could not make temporary directory")); =20 tempdir_name =3D xstrdup (tempdir_name); - make_final_cleanup (do_rmdir, tempdir_name); + add_final_cleanup ([] () + { + char *zap; + int wstat; + + gdb_assert (startswith (tempdir_name, TMP_PREFIX)); + zap =3D concat ("rm -rf ", tempdir_name, (char *) NULL); + wstat =3D system (zap); + if (wstat =3D=3D -1 || !WIFEXITED (wstat) || WEXITSTATUS (wstat) != =3D 0) + warning (_("Could not remove temporary directory %s"), tempdir_name); + XDELETEVEC (zap); + }); return tempdir_name; } =20 diff --git a/gdb/debuginfod-support.c b/gdb/debuginfod-support.c index 7d8ada39e96..9bb3748c8c3 100644 --- a/gdb/debuginfod-support.c +++ b/gdb/debuginfod-support.c @@ -188,15 +188,6 @@ progressfn (debuginfod_client *c, long cur, long total) return 0; } =20 -/* Cleanup ARG, which is a debuginfod_client pointer. */ - -static void -cleanup_debuginfod_client (void *arg) -{ - debuginfod_client *client =3D static_cast (arg); - debuginfod_end (client); -} - /* Return a pointer to the single global debuginfod_client, initialising it first if needed. */ =20 @@ -221,7 +212,10 @@ get_debuginfod_client () handlers, which is too late. =20 So instead, we make use of GDB's final cleanup mechanism. */ - make_final_cleanup (cleanup_debuginfod_client, global_client); + add_final_cleanup ([] () + { + debuginfod_end (global_client); + }); debuginfod_set_progressfn (global_client, progressfn); } } diff --git a/gdb/python/python.c b/gdb/python/python.c index 8aa674c28d3..8f8ee7c0680 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -2057,7 +2057,7 @@ static struct cmd_list_element *user_show_python_list; interpreter. This lets Python's 'atexit' work. */ =20 static void -finalize_python (void *ignore) +finalize_python () { struct active_ext_lang_state *previous_active; =20 @@ -2297,7 +2297,7 @@ init_done: /* Release the GIL while gdb runs. */ PyEval_SaveThread (); =20 - make_final_cleanup (finalize_python, NULL); + add_final_cleanup (finalize_python); =20 /* Only set this when initialization has succeeded. */ gdb_python_initialized =3D 1; diff --git a/gdbsupport/cleanups.cc b/gdbsupport/cleanups.cc index 619db023063..cc14523b2d1 100644 --- a/gdbsupport/cleanups.cc +++ b/gdbsupport/cleanups.cc @@ -19,126 +19,26 @@ =20 #include "common-defs.h" #include "cleanups.h" +#include =20 -/* The cleanup list records things that have to be undone - if an error happens (descriptors to be closed, memory to be freed, etc.) - Each link in the chain records a function to call and an - argument to give it. +/* All the cleanup functions. */ =20 - Use make_cleanup to add an element to the cleanup chain. - Use do_cleanups to do all cleanup actions back to a given - point in the chain. Use discard_cleanups to remove cleanups - from the chain back to a given point, not doing them. +static std::vector> all_cleanups; =20 - If the argument is pointer to allocated memory, then you need - to additionally set the 'free_arg' member to a function that will - free that memory. This function will be called both when the cleanup - is executed and when it's discarded. */ +/* See cleanups.h. */ =20 -struct cleanup -{ - struct cleanup *next; - void (*function) (void *); - void (*free_arg) (void *); - void *arg; -}; - -/* Used to mark the end of a cleanup chain. - The value is chosen so that it: - - is non-NULL so that make_cleanup never returns NULL, - - causes a segv if dereferenced - [though this won't catch errors that a value of, say, - ((struct cleanup *) -1) will] - - displays as something useful when printed in gdb. - This is const for a bit of extra robustness. - It is initialized to coax gcc into putting it into .rodata. - All fields are initialized to survive -Wextra. */ -static const struct cleanup sentinel_cleanup =3D { 0, 0, 0, 0 }; - -/* Handy macro to use when referring to sentinel_cleanup. */ -#define SENTINEL_CLEANUP ((struct cleanup *) &sentinel_cleanup) - -/* Chain of cleanup actions established with make_final_cleanup, - to be executed when gdb exits. */ -static struct cleanup *final_cleanup_chain =3D SENTINEL_CLEANUP; - -/* Main worker routine to create a cleanup. - PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain. - FUNCTION is the function to call to perform the cleanup. - ARG is passed to FUNCTION when called. - FREE_ARG, if non-NULL, is called after the cleanup is performed. - - The result is a pointer to the previous chain pointer - to be passed later to do_cleanups or discard_cleanups. */ - -static struct cleanup * -make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function, - void *arg, void (*free_arg) (void *)) -{ - struct cleanup *newobj =3D XNEW (struct cleanup); - struct cleanup *old_chain =3D *pmy_chain; - - newobj->next =3D *pmy_chain; - newobj->function =3D function; - newobj->free_arg =3D free_arg; - newobj->arg =3D arg; - *pmy_chain =3D newobj; - - gdb_assert (old_chain !=3D NULL); - return old_chain; -} - -/* Worker routine to create a cleanup without a destructor. - PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain. - FUNCTION is the function to call to perform the cleanup. - ARG is passed to FUNCTION when called. - - The result is a pointer to the previous chain pointer - to be passed later to do_cleanups or discard_cleanups. */ - -static struct cleanup * -make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function, - void *arg) -{ - return make_my_cleanup2 (pmy_chain, function, arg, NULL); -} - -/* Add a new cleanup to the final cleanup_chain, - and return the previous chain pointer - to be passed later to do_cleanups or discard_cleanups. - Args are FUNCTION to clean up with, and ARG to pass to it. */ - -struct cleanup * -make_final_cleanup (make_cleanup_ftype *function, void *arg) -{ - return make_my_cleanup (&final_cleanup_chain, function, arg); -} - -/* Worker routine to perform cleanups. - PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain. - OLD_CHAIN is the result of a "make" cleanup routine. - Cleanups are performed until we get back to the old end of the chain. = */ - -static void -do_my_cleanups (struct cleanup **pmy_chain, - struct cleanup *old_chain) +void +add_final_cleanup (std::function &&func) { - struct cleanup *ptr; - - while ((ptr =3D *pmy_chain) !=3D old_chain) - { - *pmy_chain =3D ptr->next; /* Do this first in case of recursion. */ - (*ptr->function) (ptr->arg); - if (ptr->free_arg) - (*ptr->free_arg) (ptr->arg); - xfree (ptr); - } + all_cleanups.emplace_back (std::move (func)); } =20 -/* Discard final cleanups and do the actions they describe. */ +/* See cleanups.h. */ =20 void do_final_cleanups () { - do_my_cleanups (&final_cleanup_chain, SENTINEL_CLEANUP); + for (auto &func : all_cleanups) + func (); + all_cleanups.clear (); } diff --git a/gdbsupport/cleanups.h b/gdbsupport/cleanups.h index 3e64f7d1684..985cf81ff7d 100644 --- a/gdbsupport/cleanups.h +++ b/gdbsupport/cleanups.h @@ -19,21 +19,12 @@ #ifndef COMMON_CLEANUPS_H #define COMMON_CLEANUPS_H =20 -/* Outside of cleanups.c, this is an opaque type. */ -struct cleanup; +#include =20 -/* NOTE: cagney/2000-03-04: This typedef is strictly for the - make_cleanup function declarations below. Do not use this typedef - as a cast when passing functions into the make_cleanup() code. - Instead either use a bounce function or add a wrapper function. - Calling a f(char*) function with f(void*) is non-portable. */ -typedef void (make_cleanup_ftype) (void *); - -/* Function type for the dtor in make_cleanup_dtor. */ -typedef void (make_cleanup_dtor_ftype) (void *); - -extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *); +/* Register a function that will be called on exit. */ +extern void add_final_cleanup (std::function &&func); =20 +/* Run all the registered functions. */ extern void do_final_cleanups (); =20 #endif /* COMMON_CLEANUPS_H */