From patchwork Tue Jan 1 22:45:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 30931 Received: (qmail 123622 invoked by alias); 1 Jan 2019 22:45:32 -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 122775 invoked by uid 89); 1 Jan 2019 22:45:26 -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, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=goes, states, held X-HELO: mail-wm1-f65.google.com Received: from mail-wm1-f65.google.com (HELO mail-wm1-f65.google.com) (209.85.128.65) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 01 Jan 2019 22:45:24 +0000 Received: by mail-wm1-f65.google.com with SMTP id f188so26298650wmf.5 for ; Tue, 01 Jan 2019 14:45:23 -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=RKzz7W8BrOP3VtURA5zcBysORCvngGGuQvStLQYMLg0=; b=AfYfsZeH2/LrbYBCQX42aDqPoitUPggwKi9j6nvy4ogTnW//C5Or3AEylS/wQ6x112 bxLnAXhRxK3GeEGUAs4pF2z1H1+8i5YodzSbOaS6sz/4vq3GZdqenYm8fyBdwS/dmxnZ pps2KMQVvZo6StmUBxXrvMtxHTbPt733nwzjFmWx7hJudoVaoOOeNbHYByLUBsR2vlnz 7J2eCbFlXtolUTPbaFOy2RH+tWZlTrZuFvHilrW6GkYW49RsHAH+rOFQHIS4ySpQpfkR 6EX44tLD4CBQ7X/dfJEiv3hvas0Vkl/oJJfqY088RWmgbHv2i+UvXxUjcJP+m2C8jTZC g2Dg== Return-Path: Received: from localhost (host86-172-198-47.range86-172.btcentralplus.com. [86.172.198.47]) by smtp.gmail.com with ESMTPSA id f14sm41848834wrv.56.2019.01.01.14.45.21 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 01 Jan 2019 14:45:21 -0800 (PST) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess Subject: [PATCH 5/6] gdb: Remove cleanup from linux-fork.c:inferior_call_waitpid Date: Tue, 1 Jan 2019 22:45:05 +0000 Message-Id: <93fd47987a3ab8907c4745e4054d622b5122cede.1546382416.git.andrew.burgess@embecosm.com> In-Reply-To: References: In-Reply-To: References: X-IsSubscribed: yes Replace cleanup in linux-fork.c:inferior_call_waitpid with a RAII object. gdb/ChangeLog: * linux-fork.c (class scoped_switch_fork_info): New class. (inferior_call_waitpid): Update to use scoped_switch_fork_info. --- gdb/ChangeLog | 5 +++ gdb/linux-fork.c | 101 +++++++++++++++++++++++++++++++++---------------------- 2 files changed, 65 insertions(+), 41 deletions(-) diff --git a/gdb/linux-fork.c b/gdb/linux-fork.c index 39ab74e2deb..f3231bae048 100644 --- a/gdb/linux-fork.c +++ b/gdb/linux-fork.c @@ -437,45 +437,64 @@ linux_fork_detach (int from_tty) delete_fork (inferior_ptid); } -static void -inferior_call_waitpid_cleanup (void *fp) +/* Temporarily switch to the infrun state stored on the fork_info + identified by a given ptid_t. When this object goes out of scope, + restore the currently selected infrun state. */ + +class scoped_switch_fork_info { - struct fork_info *oldfp = (struct fork_info *) fp; +public: + /* Switch to the infrun state held on the fork_info identified by + PPTID. If PPTID is the current inferior then no switch is done. */ + scoped_switch_fork_info (ptid_t pptid) + : m_oldfp (nullptr) + { + if (pptid != inferior_ptid) + { + struct fork_info *newfp = nullptr; + + /* Switch to pptid. */ + m_oldfp = find_fork_ptid (inferior_ptid); + gdb_assert (m_oldfp != nullptr); + newfp = find_fork_ptid (pptid); + gdb_assert (newfp != nullptr); + fork_save_infrun_state (m_oldfp, 1); + remove_breakpoints (); + fork_load_infrun_state (newfp); + insert_breakpoints (); + } + } - if (oldfp) - { - /* Switch back to inferior_ptid. */ - remove_breakpoints (); - fork_load_infrun_state (oldfp); - insert_breakpoints (); - } -} + /* Restore the previously selected infrun state. If the constructor + didn't need to switch states, then nothing is done here either. */ + ~scoped_switch_fork_info () + { + if (m_oldfp != nullptr) + { + /* Switch back to inferior_ptid. */ + remove_breakpoints (); + fork_load_infrun_state (m_oldfp); + insert_breakpoints (); + } + } + + DISABLE_COPY_AND_ASSIGN (scoped_switch_fork_info); + +private: + /* The fork_info for the previously selected infrun state, or nullptr if + we were already in the desired state, and nothing needs to be + restored. */ + struct fork_info *m_oldfp; +}; static int inferior_call_waitpid (ptid_t pptid, int pid) { struct objfile *waitpid_objf; struct value *waitpid_fn = NULL; - struct value *argv[3], *retv; - struct gdbarch *gdbarch = get_current_arch (); - struct fork_info *oldfp = NULL, *newfp = NULL; - struct cleanup *old_cleanup; int ret = -1; - if (pptid != inferior_ptid) - { - /* Switch to pptid. */ - oldfp = find_fork_ptid (inferior_ptid); - gdb_assert (oldfp != NULL); - newfp = find_fork_ptid (pptid); - gdb_assert (newfp != NULL); - fork_save_infrun_state (oldfp, 1); - remove_breakpoints (); - fork_load_infrun_state (newfp); - insert_breakpoints (); - } - - old_cleanup = make_cleanup (inferior_call_waitpid_cleanup, oldfp); + scoped_switch_fork_info switch_fork_info (pptid); /* Get the waitpid_fn. */ if (lookup_minimal_symbol ("waitpid", NULL, NULL).minsym != NULL) @@ -483,22 +502,22 @@ inferior_call_waitpid (ptid_t pptid, int pid) if (!waitpid_fn && lookup_minimal_symbol ("_waitpid", NULL, NULL).minsym != NULL) waitpid_fn = find_function_in_inferior ("_waitpid", &waitpid_objf); - if (!waitpid_fn) - goto out; + if (waitpid_fn != nullptr) + { + struct gdbarch *gdbarch = get_current_arch (); + struct value *argv[3], *retv; - /* Get the argv. */ - argv[0] = value_from_longest (builtin_type (gdbarch)->builtin_int, pid); - argv[1] = value_from_pointer (builtin_type (gdbarch)->builtin_data_ptr, 0); - argv[2] = value_from_longest (builtin_type (gdbarch)->builtin_int, 0); + /* Get the argv. */ + argv[0] = value_from_longest (builtin_type (gdbarch)->builtin_int, pid); + argv[1] = value_from_pointer (builtin_type (gdbarch)->builtin_data_ptr, 0); + argv[2] = value_from_longest (builtin_type (gdbarch)->builtin_int, 0); - retv = call_function_by_hand (waitpid_fn, NULL, argv); - if (value_as_long (retv) < 0) - goto out; + retv = call_function_by_hand (waitpid_fn, NULL, argv); - ret = 0; + if (value_as_long (retv) >= 0) + ret = 0; + } -out: - do_cleanups (old_cleanup); return ret; }