From patchwork Fri Jun 20 15:57:45 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 1610 Received: (qmail 2619 invoked by alias); 20 Jun 2014 16:32:45 -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 2606 invoked by uid 89); 20 Jun 2014 16:32:45 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.8 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Fri, 20 Jun 2014 16:32:44 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s5KGWfwp005320 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 20 Jun 2014 12:32:42 -0400 Received: from barimba.redhat.com (ovpn-113-103.phx2.redhat.com [10.3.113.103]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s5KFw53J015561; Fri, 20 Jun 2014 11:58:08 -0400 From: Tom Tromey To: gdb-patches@sourceware.org Cc: Jan Kratochvil Subject: [PATCH v2 05/14] add dummy frame destructor Date: Fri, 20 Jun 2014 09:57:45 -0600 Message-Id: <1403279874-23781-6-git-send-email-tromey@redhat.com> In-Reply-To: <1403279874-23781-1-git-send-email-tromey@redhat.com> References: <1403279874-23781-1-git-send-email-tromey@redhat.com> From: Jan Kratochvil The compiler code needed a hook into dummy frame destruction, so that some state could be kept while the inferior call is made and then destroyed when the inferior call finishes. This patch adds an optional destructor to dummy frames and a new API to access it. 2014-06-20 Jan Kratochvil * dummy-frame.c (struct dummy_frame) : New fields. (pop_dummy_frame): Call the destructor if it exists. (register_dummy_frame_dtor, find_dummy_frame_dtor): New functions. * dummy-frame.h (dummy_frame_dtor_ftype): New typedef. (register_dummy_frame_dtor, find_dummy_frame_dtor): Declare. --- gdb/ChangeLog | 10 ++++++++++ gdb/dummy-frame.c | 39 +++++++++++++++++++++++++++++++++++++++ gdb/dummy-frame.h | 13 +++++++++++++ 3 files changed, 62 insertions(+) diff --git a/gdb/dummy-frame.c b/gdb/dummy-frame.c index 998ca93..b0608a9 100644 --- a/gdb/dummy-frame.c +++ b/gdb/dummy-frame.c @@ -43,6 +43,13 @@ struct dummy_frame struct frame_id id; /* The caller's state prior to the call. */ struct infcall_suspend_state *caller_state; + + /* If non-NULL, a destructor that is run when this dummy frame is + popped. */ + void (*dtor) (void *data); + + /* Arbitrary data that is passed to DTOR. */ + void *dtor_data; }; static struct dummy_frame *dummy_frame_stack = NULL; @@ -107,6 +114,9 @@ pop_dummy_frame (struct dummy_frame **dummy_ptr) { struct dummy_frame *dummy = *dummy_ptr; + if (dummy->dtor != NULL) + dummy->dtor (dummy->dtor_data); + restore_infcall_suspend_state (dummy->caller_state); iterate_over_breakpoints (pop_dummy_frame_bpt, dummy); @@ -171,6 +181,35 @@ dummy_frame_discard (struct frame_id dummy_id) remove_dummy_frame (dp); } +/* See dummy-frame.h. */ + +void +register_dummy_frame_dtor (struct frame_id dummy_id, + dummy_frame_dtor_ftype *dtor, void *dtor_data) +{ + struct dummy_frame **dp, *d; + + dp = lookup_dummy_frame (dummy_id); + gdb_assert (dp != NULL); + d = *dp; + gdb_assert (d->dtor == NULL); + d->dtor = dtor; + d->dtor_data = dtor_data; +} + +/* See dummy-frame.h. */ + +int +find_dummy_frame_dtor (dummy_frame_dtor_ftype *dtor, void *dtor_data) +{ + struct dummy_frame *d; + + for (d = dummy_frame_stack; d != NULL; d = d->next) + if (d->dtor == dtor && d->dtor_data == dtor_data) + return 1; + return 0; +} + /* There may be stale dummy frames, perhaps left over from when an uncaught longjmp took us out of a function that was called by the debugger. Clean them up at least once whenever we start a new inferior. */ diff --git a/gdb/dummy-frame.h b/gdb/dummy-frame.h index 6db312e..21e7fff 100644 --- a/gdb/dummy-frame.h +++ b/gdb/dummy-frame.h @@ -59,4 +59,17 @@ extern void dummy_frame_discard (struct frame_id dummy_id); extern const struct frame_unwind dummy_frame_unwind; +/* Call DTOR with DTOR_DATA when DUMMY_ID frame gets discarded. + Dummy frame with DUMMY_ID must exist. There must be no other call of + register_dummy_frame_dtor for that dummy frame. */ +typedef void (dummy_frame_dtor_ftype) (void *data); +extern void register_dummy_frame_dtor (struct frame_id dummy_id, + dummy_frame_dtor_ftype *dtor, + void *dtor_data); + +/* Return 1 if there exists dummy frame with registered DTOR and DTOR_DATA. + Return 0 otherwise. */ +extern int find_dummy_frame_dtor (dummy_frame_dtor_ftype *dtor, + void *dtor_data); + #endif /* !defined (DUMMY_FRAME_H) */