From patchwork Fri Feb 23 21:11:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 86308 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 93E953858298 for ; Fri, 23 Feb 2024 21:12:22 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-io1-xd31.google.com (mail-io1-xd31.google.com [IPv6:2607:f8b0:4864:20::d31]) by sourceware.org (Postfix) with ESMTPS id D681F385842A for ; Fri, 23 Feb 2024 21:11:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D681F385842A Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=adacore.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org D681F385842A Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::d31 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708722702; cv=none; b=XLx3Dgw7UFy9MngGktEZYyr15EDHBoJ0Uqind84RGGY+F6BV+lzGEwtoum8rrdVZYPepMXVRKu7eYyDV7Y1NU+MORxcnNcivektuLQx/pfc0KzXwDDR9nmpUG7h1olD7F0kDE6X80elGhCA9180Sr6IB+DBfJ9p9JQRTrsTIi08= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708722702; c=relaxed/simple; bh=mF5X3XpCX2bY6kKlrOzC5j9kugxSoujqlOeUd31iTjk=; h=DKIM-Signature:From:Date:Subject:MIME-Version:Message-Id:To; b=bnTTCWyh+zwoUNKN1e7lC7tZw4Cvb7T36usDK2drweg/fergrpIrFqNWPKHfDorPyc87Nj0Y2tgmrLIlF8lRHzyklnMWbXJOLbz5etKHc2twJr708HXF1Odf67fpFqinzr6L500tBM9xhh/uAA1axujDolRu/BuwkMM+tISfRH8= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-io1-xd31.google.com with SMTP id ca18e2360f4ac-7c788332976so36669639f.3 for ; Fri, 23 Feb 2024 13:11:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=adacore.com; s=google; t=1708722699; x=1709327499; darn=sourceware.org; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=wUEGxzvKRX2NktB0NWTGXkOpxzpgzRsGgIK9PF+7JIk=; b=PBpc6c6o0LjNaLC8LjPjutJDMr/TRWpxys2vNKPJeCGG327s/UWNWSwy6D1U7Mndn9 ENTR2I7Ip5OyvvANrm0K/sY6eah3eejtJphL1bx7y3KlgOZKjhBNWqkybAn3zGoeflMK asiVx/0FjGZqaMLdhyALZDVe1uX6pI+mPSEI2znnNvXGxrswIn+ZD1sssnhIiardqyVG jBG2WkOQrogvNBpXHWy0bcCM/gthPJuOKTnOhM0720pPy/Vko/VdihGzH6Z1yLWaG9BZ mIb9Ef36zDZZhNlsU/Spyz5aSyEQMTkrZkqE3TBG2Vt6atDPcVNIWR4HYM2jYRjxcvGz EGXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708722699; x=1709327499; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wUEGxzvKRX2NktB0NWTGXkOpxzpgzRsGgIK9PF+7JIk=; b=o+aPCZgkg8uDV10GoNQScToM7Lq7lLwwp2gN3x4dtSKsmO80ZWT5nr4ok4dZcKEVUF R9FtP4hACP0BAx6za/rH8K/luQDiLs20uAMYeLsPqpyDg13w6gneSIWt3uB5n9ETGy2E eViV0/NYGS4HYVHXmaNQfEbzpK72MFjHKz8w11iCYnTvqAEeYuPCumqedqYNPjAzYzlw LHLZPGwjt1rCoPKX81OORwDYiWTjdPUOaWu/4aBGSEx5ddk+oXb1h0EXzeKqGaWIWgJB SWMoiy1Uoh9sqFuBb9nCQo6DdnyTBM2XUI8wRMv+Xbzn9tD/xnC/9QZL4QA4z8DloL0h AwFA== X-Gm-Message-State: AOJu0YynzqhRpWi4Yo7tUqLRMrh8o1Vs0Pez3RLtakW+XZDaVYiejQBL 3bS81qPTyuCYIYrcHWwpkv/Wtd2kUS58Anh/+CwwMalw1uMyZ9B2AEZruOx0AT9aztImc9BjakU = X-Google-Smtp-Source: AGHT+IH3P4VeI9ehPbx14dprkd7rHcTwzAXJt/TtkY3DSPY8n9faXU9NNiUcAwCU4GcZZ54JSWVPoQ== X-Received: by 2002:a6b:7105:0:b0:7c7:9b0a:6dd1 with SMTP id q5-20020a6b7105000000b007c79b0a6dd1mr1272417iog.6.1708722698835; Fri, 23 Feb 2024 13:11:38 -0800 (PST) Received: from localhost.localdomain (71-211-170-195.hlrn.qwest.net. [71.211.170.195]) by smtp.gmail.com with ESMTPSA id y14-20020a02c00e000000b004741aec6cdasm3497851jai.25.2024.02.23.13.11.38 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 23 Feb 2024 13:11:38 -0800 (PST) From: Tom Tromey Date: Fri, 23 Feb 2024 14:11:37 -0700 Subject: [PATCH 1/5] Rewrite final cleanups MIME-Version: 1.0 Message-Id: <20240223-final-cleanups-v1-1-84d5271e9979@adacore.com> References: <20240223-final-cleanups-v1-0-84d5271e9979@adacore.com> In-Reply-To: <20240223-final-cleanups-v1-0-84d5271e9979@adacore.com> To: gdb-patches@sourceware.org X-Mailer: b4 0.12.4 X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org This patch rewrites final cleanups to use std::function and otherwise be more C++-ish. --- 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) } } -/* A cleanup function to remove a directory and all its contents. */ - -static void -do_rmdir (void *arg) -{ - const char *dir = (const char *) arg; - char *zap; - int wstat; - - gdb_assert (startswith (dir, TMP_PREFIX)); - zap = concat ("rm -rf ", dir, (char *) NULL); - wstat = system (zap); - if (wstat == -1 || !WIFEXITED (wstat) || WEXITSTATUS (wstat) != 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. */ @@ -465,7 +448,18 @@ get_compile_file_tempdir (void) perror_with_name (_("Could not make temporary directory")); tempdir_name = 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 = concat ("rm -rf ", tempdir_name, (char *) NULL); + wstat = system (zap); + if (wstat == -1 || !WIFEXITED (wstat) || WEXITSTATUS (wstat) != 0) + warning (_("Could not remove temporary directory %s"), tempdir_name); + XDELETEVEC (zap); + }); return tempdir_name; } 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; } -/* Cleanup ARG, which is a debuginfod_client pointer. */ - -static void -cleanup_debuginfod_client (void *arg) -{ - debuginfod_client *client = static_cast (arg); - debuginfod_end (client); -} - /* Return a pointer to the single global debuginfod_client, initialising it first if needed. */ @@ -221,7 +212,10 @@ get_debuginfod_client () handlers, which is too late. 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 7b0997c8d52..971fc850dbb 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -2070,7 +2070,7 @@ static struct cmd_list_element *user_show_python_list; interpreter. This lets Python's 'atexit' work. */ static void -finalize_python (void *ignore) +finalize_python () { struct active_ext_lang_state *previous_active; @@ -2310,7 +2310,7 @@ do_start_initialization () /* Release the GIL while gdb runs. */ PyEval_SaveThread (); - make_final_cleanup (finalize_python, NULL); + add_final_cleanup (finalize_python); /* Only set this when initialization has succeeded. */ gdb_python_initialized = 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 @@ #include "common-defs.h" #include "cleanups.h" +#include -/* 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. */ - 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; - 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. */ -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 = { 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 = 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 = XNEW (struct cleanup); - struct cleanup *old_chain = *pmy_chain; - - newobj->next = *pmy_chain; - newobj->function = function; - newobj->free_arg = free_arg; - newobj->arg = arg; - *pmy_chain = newobj; - - gdb_assert (old_chain != 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 = *pmy_chain) != old_chain) - { - *pmy_chain = 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)); } -/* Discard final cleanups and do the actions they describe. */ +/* See cleanups.h. */ 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 -/* Outside of cleanups.c, this is an opaque type. */ -struct cleanup; +#include -/* 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); +/* Run all the registered functions. */ extern void do_final_cleanups (); #endif /* COMMON_CLEANUPS_H */