From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17742 invoked by alias); 1 May 2013 10:28:14 -0000 Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org Received: (qmail 17732 invoked by uid 89); 1 May 2013 10:28:13 -0000 X-Spam-SWARE-Status: No, score=-5.4 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.1 Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Wed, 01 May 2013 10:28:10 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r41AS9b2017250 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 1 May 2013 06:28:09 -0400 Received: from localhost.localdomain (ovpn-116-98.ams2.redhat.com [10.36.116.98]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r41AS76T027680 for ; Wed, 1 May 2013 06:28:08 -0400 Message-ID: <5180EE37.3020507@redhat.com> Date: Wed, 01 May 2013 10:28:00 -0000 From: Phil Muldoon MIME-Version: 1.0 To: gdb@sourceware.org Subject: Cleanups and Exception handlers Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-SW-Source: 2013-05/txt/msg00004.txt.bz2 I'd like to quantify and discuss strategies of cleanups and GDB exception handlers. It seems I am always making mistakes in this area, and the comments in the TRY_CATCH macro (well to me) are not adequate about the mechanics of cleanups in an exception handler. So I would like to discuss patterns of usage with a view to updating the comments to be more explanatory. Take this example, something that caught me out recently: struct cleanups cleanups; cleanups = make_cleanup (xfree, foo); TRY_CATCH (except, RETURN_MASK_ALL) { make_cleanup_ui_out_tuple_begin_end (out, NULL); ... // Do some other stuff } if (except.reason < 0) { // Some exception handling code } do_cleanups (cleanups); It seems if you create a cleanup in an exception handler, even if the old cleanup chain is saved before the exception handler starts, you have to call do_cleanups() in the exception handler or the cleanup is lost. It seems that the TRY_CATCH code is manipulating the cleanup chain, but I can't find any comments on why it does this, or how that affects your own cleanup chain. What happens if you discard cleanups in an exception handler to a point where the cleanup was registered before the exception handler started? In the above example, assuming everything went OK in above, and no calls produced an error() or some other call, when I call do_cleanups() in that code, my "tuple" cleanup seems to have been discarded. (I know this as in my code, I rapidly encounter ui_out->level > MAX_UI_OUT_LEVELS as the tuples were never closed in the cleanups. Question 1) What is the rule regarding cleanup chains that were created outside of an exception handler, but where additional cleanups were registered and not processed (cleanedup) inside the exception handler. Question 2) If in the above example, something goes wrong, does one have to call do_cleanups() in the exception handling block (IE if (except.reason < 0)) Example 2: TRY_CATCH (except, RETURN_MASK_ALL) { struct cleanups cleanups = make_cleanup_ui_out_tuple_begin_end (out, NULL); ... // Do some other stuff do_cleanups (cleanups); } if (except.reason < 0) { // Some exception handling code } In this example we create a pointer to the cleanup chain, and perform a tuple cleanup. If I call do_cleanups() in this example (assuming nothing went wrong in the TRY_CATCH block), the tuple is cleaned up properly. But what happens if something happens and the exception handling "if" is called. Question 3) For cleanups created and registered exclusively in the TRY_CATCH block, on some exception being raised are they cleaned up automatically? (As there is no scope for the exception handling failure code to do cleanups). This all came about as MI tuples tend to be "long lived" cleanups and in Python we have to handle every potential GDB exception call in an exception handler to prevent propagation upwards. I found this leads to giant TRY_CATCH calls that encompass tuple creation, tuple population, and tuple closure. But I am not sure. Cheers, Phil