From patchwork Sat Jan 12 11:50:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 31040 Received: (qmail 124373 invoked by alias); 12 Jan 2019 11:50:52 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 124272 invoked by uid 89); 12 Jan 2019 11:50:51 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=reducing, Declare, Nothing, extracted X-HELO: mail-wm1-f50.google.com Received: from mail-wm1-f50.google.com (HELO mail-wm1-f50.google.com) (209.85.128.50) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 12 Jan 2019 11:50:46 +0000 Received: by mail-wm1-f50.google.com with SMTP id y8so4684840wmi.4 for ; Sat, 12 Jan 2019 03:50:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=HbNSGg9+MMaE61nFO6WaODio5f62x+kjFdE9eX1K/vQ=; b=NS2L20SybBCsFVKajyIUeCSLlOxGVHQd/8IHm0kjvaXK00LvzKA2YJWEIA5SKSBsZ3 tDMnkEH4xvyp6vMiLyEmJmIdFWLjBwqk8crxZf++OIdE2Pm9TOf8bEbdnKuuTbWEuIG6 dK5JYmmFnwP7jemz3tHNvzM7q3mz7Ze60I7KWX5BW2BP+wl2xO/rUq3BmN33Eby7BdLj Z32uPWWkKA1OISFcQjG+10W/kqAmlgvuefw/2ul3LOALcitiB33ZodSpCbs/MPa3iuFH FBidaZnV/L2x/kuLi+YxCqgPjZmLbjoeUAUHfboEEZAHdx/1Mb3DX3cG4bgYHHmCsMuU 10sw== Return-Path: Received: from localhost (host86-172-198-47.range86-172.btcentralplus.com. [86.172.198.47]) by smtp.gmail.com with ESMTPSA id j8sm50867166wrt.40.2019.01.12.03.50.43 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 12 Jan 2019 03:50:43 -0800 (PST) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Tom Tromey , Andrew Burgess Subject: [PATCH 1/4] gdb: Remove delete_longjmp_breakpoint_cleanup Date: Sat, 12 Jan 2019 11:50:34 +0000 Message-Id: <8d74a5fd945b788f4a2bedd2d65c71aa4f6280bd.1547292660.git.andrew.burgess@embecosm.com> In-Reply-To: References: In-Reply-To: References: <20190109033426.16062-1-tom@tromey.com> X-IsSubscribed: yes This removes delete_longjmp_breakpoint_cleanup in favor of a new cleanup function type. This new type is somewhat generic, and will be reused in subsequent patches. Note that cleanup_function::cancel was purposely not named "reset". An earlier version did this, but it was too easy to mistake cleanup_function::reset and gdb::optional::reset. gdb/ChangeLog: * breakpoint.c (until_break_command): Delete cleanup, use longjmp_breakpoint_cleanup instead. * breakpoint.h: Declare longjmp_breakpoint_cleanup class. * common/cleanup-function.h: New file. * infcmd.c (delete_longjmp_breakpoint_cleanup): Delete. (until_next_command): Delete cleanup, use longjmp_breakpoint_cleanup instead. * inferior.h (delete_longjmp_breakpoint_cleanup): Delete declaration. --- gdb/ChangeLog | 13 +++++ gdb/breakpoint.c | 11 ++-- gdb/breakpoint.h | 10 ++++ gdb/common/cleanup-function.h | 118 ++++++++++++++++++++++++++++++++++++++++++ gdb/infcmd.c | 12 +---- gdb/inferior.h | 2 - 6 files changed, 149 insertions(+), 17 deletions(-) create mode 100644 gdb/common/cleanup-function.h diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 2ab8a76326c..3e9da1f99fa 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -11073,7 +11073,6 @@ until_break_command (const char *arg, int from_tty, int anywhere) struct gdbarch *frame_gdbarch; struct frame_id stack_frame_id; struct frame_id caller_frame_id; - struct cleanup *old_chain; int thread; struct thread_info *tp; struct until_break_fsm *sm; @@ -11106,8 +11105,6 @@ until_break_command (const char *arg, int from_tty, int anywhere) tp = inferior_thread (); thread = tp->global_num; - old_chain = make_cleanup (null_cleanup, NULL); - /* Note linespec handling above invalidates the frame chain. Installing a breakpoint also invalidates the frame chain (as it may need to switch threads), so do any frame handling before @@ -11122,6 +11119,9 @@ until_break_command (const char *arg, int from_tty, int anywhere) one. */ breakpoint_up caller_breakpoint; + + gdb::optional lj_deleter; + if (frame_id_p (caller_frame_id)) { struct symtab_and_line sal2; @@ -11136,7 +11136,7 @@ until_break_command (const char *arg, int from_tty, int anywhere) bp_until); set_longjmp_breakpoint (tp, caller_frame_id); - make_cleanup (delete_longjmp_breakpoint_cleanup, &thread); + lj_deleter.emplace (thread); } /* set_momentary_breakpoint could invalidate FRAME. */ @@ -11159,7 +11159,8 @@ until_break_command (const char *arg, int from_tty, int anywhere) std::move (caller_breakpoint)); tp->thread_fsm = &sm->thread_fsm; - discard_cleanups (old_chain); + if (lj_deleter) + lj_deleter->cancel (); proceed (-1, GDB_SIGNAL_DEFAULT); } diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index 97b6f3fbc64..5cbfb1ecfc6 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -30,6 +30,7 @@ #include #include "common/array-view.h" #include "cli/cli-script.h" +#include "common/cleanup-function.h" struct block; struct gdbpy_breakpoint_object; @@ -1431,6 +1432,15 @@ extern void set_longjmp_breakpoint (struct thread_info *tp, struct frame_id frame); extern void delete_longjmp_breakpoint (int thread); +/* Cleanup class that calls delete_longjmp_breakpoint. */ +#ifdef __cpp_template_auto +using longjmp_breakpoint_cleanup + = cleanup_function ; +#else +using longjmp_breakpoint_cleanup += cleanup_function ; +#endif + /* Mark all longjmp breakpoints from THREAD for later deletion. */ extern void delete_longjmp_breakpoint_at_next_stop (int thread); diff --git a/gdb/common/cleanup-function.h b/gdb/common/cleanup-function.h new file mode 100644 index 00000000000..3a59648457c --- /dev/null +++ b/gdb/common/cleanup-function.h @@ -0,0 +1,118 @@ +/* Copyright (C) 2019 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef COMMON_CLEANUP_FUNCTION_H +#define COMMON_CLEANUP_FUNCTION_H + +#include + +/* This is the general part of a recursive template to unpack the arguments + from the tuple PARAMS into ARGS. The template parameter N is the number + of parameters left to unpack from PARAMS. Each iteration takes an extra + parameter from PARAMS and passes it as an extra argument to + CALL_FUNCTION_ON_TUPLE::UNPACK_TUPLE, reducing N until we hit the base + case below. */ +template +struct call_function_on_tuple +{ + template + static void unpack (void (*func) (FuncArgTypes... ), + const std::tuple& params, + UnpackedArgTypes... args) + { + call_function_on_tuple::unpack (func, params, + std::get (params), + args...); + } +}; + +/* This is the base case specialisation, when we reach this point all of + the arguments have been extracted from PARAMS and are being passed in + ARGS. It is worth noting that ARGS must be non-empty, thus this can't + be used to call FUNC if FUNC takes no parameters. This special case is + handled within CLEANUP_FUNCTION::UNPACK_TUPLE below. */ +template <> +struct call_function_on_tuple<0> +{ + template + static void unpack (void (*func) (FuncArgTypes...), + const std::tuple& params, + UnpackedArgTypes... args) + { + func (args...); + } +}; + +/* In a C++17 world we can make use of the `auto` keyword in the template + parameter list to avoid having to pass the function type signature as a + separate template parameter. */ + +#ifdef __cpp_template_auto +template +#else +template +#endif +class cleanup_function +{ +public: + + explicit cleanup_function (Args... args) + : m_args (std::forward(args)...) + { /* Nothing. */ } + + ~cleanup_function () + { + /* Maybe we should be try/catch around this? */ + if (!m_cancelled) + unpack_tuple_and_call (function, m_args); + } + + /* Mark this cleanup as cancelled, the cleanup function will not be + called. */ + void cancel () + { + m_cancelled = true; + } + +private: + + /* This is the entry point for calling function F with the contents of + tuple PARAMS as arguments in the case where the tuple actually holds + some values. */ + template + void unpack_tuple_and_call (void (*f) (FuncArgTypes...), + std::tuple const& params) + { + call_function_on_tuple::unpack (f, params); + } + + /* This is the entry point for calling function F for the case where F + takes no parameters. */ + template + void unpack_tuple_and_call (void (*f) (void), std::tuple<> const& params) + { + f (); + } + + /* Storage for the arguments to the cleanup function */ + std::tuple m_args; + + /* Has this cleanup been cancelled? */ + bool m_cancelled = false; +}; + +#endif /* COMMON_CLEANUP_FUNCTION_H */ diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 3c3add89ab8..9265be5585a 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -947,13 +947,6 @@ nexti_command (const char *count_string, int from_tty) step_1 (1, 1, count_string); } -void -delete_longjmp_breakpoint_cleanup (void *arg) -{ - int thread = * (int *) arg; - delete_longjmp_breakpoint (thread); -} - /* Data for the FSM that manages the step/next/stepi/nexti commands. */ @@ -1517,7 +1510,6 @@ until_next_command (int from_tty) struct symtab_and_line sal; struct thread_info *tp = inferior_thread (); int thread = tp->global_num; - struct cleanup *old_chain; struct until_next_fsm *sm; clear_proceed_status (0); @@ -1556,11 +1548,11 @@ until_next_command (int from_tty) tp->control.step_over_calls = STEP_OVER_ALL; set_longjmp_breakpoint (tp, get_frame_id (frame)); - old_chain = make_cleanup (delete_longjmp_breakpoint_cleanup, &thread); + longjmp_breakpoint_cleanup lj_deleter (thread); sm = new_until_next_fsm (command_interp (), tp->global_num); tp->thread_fsm = &sm->thread_fsm; - discard_cleanups (old_chain); + lj_deleter.cancel (); proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT); } diff --git a/gdb/inferior.h b/gdb/inferior.h index a82df1a52a5..c63fa26b086 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -198,8 +198,6 @@ extern void continue_1 (int all_threads); extern void interrupt_target_1 (int all_threads); -extern void delete_longjmp_breakpoint_cleanup (void *arg); - extern void detach_command (const char *, int); extern void notice_new_inferior (struct thread_info *, int, int);