From patchwork Fri May 8 20:21:29 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kratochvil X-Patchwork-Id: 6642 Received: (qmail 76323 invoked by alias); 8 May 2015 20:21:33 -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 76313 invoked by uid 89); 8 May 2015 20:21:32 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.3 required=5.0 tests=AWL, BAYES_00, KAM_LAZY_DOMAIN_SECURITY, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=no 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, 08 May 2015 20:21:32 +0000 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id BEB1091778 for ; Fri, 8 May 2015 20:21:30 +0000 (UTC) Received: from host1.jankratochvil.net (ovpn-116-27.ams2.redhat.com [10.36.116.27]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t48KLTUU016386 for ; Fri, 8 May 2015 16:21:29 -0400 Subject: [PATCH 2/6] Call dummy_frame_dtor_ftype also from remove_dummy_frame From: Jan Kratochvil To: gdb-patches@sourceware.org Date: Fri, 08 May 2015 22:21:29 +0200 Message-ID: <20150508202128.15830.40142.stgit@host1.jankratochvil.net> In-Reply-To: <20150508202119.15830.18218.stgit@host1.jankratochvil.net> References: <20150508202119.15830.18218.stgit@host1.jankratochvil.net> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-IsSubscribed: yes Hi, there was now a leak-like bug that if dummy_frame "disappeared" by remove_dummy_frame then its destructor was not called. For example in the case of 'compile code' dummy frames the injected objfile would never get freed after some inferior longjmp out of the injected code. Jan gdb/ChangeLog 2015-05-08 Jan Kratochvil * compile/compile-object-run.c (do_module_cleanup): Add parameter registers_valid. (compile_object_run): Update do_module_cleanup caller. * dummy-frame.c: Include infcall.h. (struct dummy_frame): Update dtor comment. (remove_dummy_frame): Call dtor. (pop_dummy_frame): Update dtor caller. * dummy-frame.h (dummy_frame_dtor_ftype): Add parameter registers_valid. --- gdb/compile/compile-object-run.c | 4 ++-- gdb/dummy-frame.c | 9 ++++++--- gdb/dummy-frame.h | 5 +++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/gdb/compile/compile-object-run.c b/gdb/compile/compile-object-run.c index 6738aad..422693b 100644 --- a/gdb/compile/compile-object-run.c +++ b/gdb/compile/compile-object-run.c @@ -45,7 +45,7 @@ struct do_module_cleanup static dummy_frame_dtor_ftype do_module_cleanup; static void -do_module_cleanup (void *arg) +do_module_cleanup (void *arg, int registers_valid) { struct do_module_cleanup *data = arg; struct objfile *objfile; @@ -129,7 +129,7 @@ compile_object_run (struct compile_module *module) data->executedp = NULL; gdb_assert (!(dtor_found && executed)); if (!dtor_found && !executed) - do_module_cleanup (data); + do_module_cleanup (data, 0); throw_exception (ex); } END_CATCH diff --git a/gdb/dummy-frame.c b/gdb/dummy-frame.c index f193289..6c4fb4c 100644 --- a/gdb/dummy-frame.c +++ b/gdb/dummy-frame.c @@ -28,6 +28,7 @@ #include "gdbcmd.h" #include "observer.h" #include "gdbthread.h" +#include "infcall.h" struct dummy_frame_id { @@ -62,8 +63,7 @@ struct dummy_frame /* 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. */ + /* If non-NULL, a destructor that is run when this dummy frame is freed. */ dummy_frame_dtor_ftype *dtor; /* Arbitrary data that is passed to DTOR. */ @@ -96,6 +96,9 @@ remove_dummy_frame (struct dummy_frame **dummy_ptr) { struct dummy_frame *dummy = *dummy_ptr; + if (dummy->dtor != NULL) + dummy->dtor (dummy->dtor_data, 0); + *dummy_ptr = dummy->next; discard_infcall_suspend_state (dummy->caller_state); xfree (dummy); @@ -136,7 +139,7 @@ pop_dummy_frame (struct dummy_frame **dummy_ptr) gdb_assert (ptid_equal (dummy->id.ptid, inferior_ptid)); if (dummy->dtor != NULL) - dummy->dtor (dummy->dtor_data); + dummy->dtor (dummy->dtor_data, 1); restore_infcall_suspend_state (dummy->caller_state); diff --git a/gdb/dummy-frame.h b/gdb/dummy-frame.h index ffd3b0a..c156b81 100644 --- a/gdb/dummy-frame.h +++ b/gdb/dummy-frame.h @@ -54,8 +54,9 @@ extern void dummy_frame_discard (struct frame_id dummy_id, ptid_t ptid); extern const struct frame_unwind dummy_frame_unwind; -/* Destructor for dummy_frame. DATA is supplied by registrant. */ -typedef void (dummy_frame_dtor_ftype) (void *data); +/* Destructor for dummy_frame. DATA is supplied by registrant. + REGISTERS_VALID is 1 for dummy_frame_pop, 0 for dummy_frame_discard. */ +typedef void (dummy_frame_dtor_ftype) (void *data, int registers_valid); /* Call DTOR with DTOR_DATA when DUMMY_ID frame of thread PTID gets discarded. Dummy frame with DUMMY_ID must exist. There must be no other call of