From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6599 invoked by alias); 10 Sep 2012 19:40:39 -0000 Received: (qmail 6590 invoked by uid 22791); 10 Sep 2012 19:40:38 -0000 X-SWARE-Spam-Status: No, hits=-6.7 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,RP_MATCHES_RCVD,SPF_HELO_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 10 Sep 2012 19:40:20 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q8AJeD9g004679 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 10 Sep 2012 15:40:19 -0400 Received: from barimba (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q8AJeCxi003169 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Mon, 10 Sep 2012 15:40:13 -0400 From: Tom Tromey To: gdb-patches@sourceware.org Subject: Re: RFC: fix atexit.register References: <87d31znom9.fsf@fleche.redhat.com> Date: Mon, 10 Sep 2012 19:40:00 -0000 In-Reply-To: <87d31znom9.fsf@fleche.redhat.com> (Tom Tromey's message of "Thu, 06 Sep 2012 09:43:26 -0600") Message-ID: <874nn5d5ur.fsf@fleche.redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-09/txt/msg00136.txt.bz2 >>>>> "Tom" == Tom Tromey writes: Tom> Regression tested on x86-64 F16. I found out something scary after posting this: if gdb crashes during exit, the entire test suite will pass. This patch fixes the bug and also doesn't SEGV. I'm looking into writing a test case for a clean exit. Tom * NEWS: Update. * python/python.c (finalize_python): New function. (_initialize_python): Make a final cleanup. * gdb.python/python.exp: Test atexit.register. diff --git a/gdb/NEWS b/gdb/NEWS index dba6937..933d6f1 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -7,6 +7,8 @@ ** Vectors can be created with gdb.Type.vector. + ** Python's atexit.register now works in GDB. + * New Python-based convenience functions: ** $_memeq(buf1, buf2, length) diff --git a/gdb/python/python.c b/gdb/python/python.c index 482f53e..59ba5b7 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -1264,6 +1264,24 @@ user_show_python (char *args, int from_tty) /* Initialize the Python code. */ +/* This is installed as a final cleanup and cleans up the + interpreter. This lets Python's 'atexit' work. */ + +static void +finalize_python (void *ignore) +{ + /* We don't use ensure_python_env here because if we ever ran the + cleanup, gdb would crash -- because the cleanup calls into the + Python interpreter, which we are about to destroy. It seems + clearer to make the needed calls explicitly here than to create a + cleanup and then mysteriously discard it. */ + PyGILState_Ensure (); + python_gdbarch = target_gdbarch; + python_language = current_language; + + Py_Finalize (); +} + /* Provide a prototype to silence -Wmissing-prototypes. */ extern initialize_file_ftype _initialize_python; @@ -1439,6 +1457,7 @@ message == an error message without a stack will be printed."), PyThreadState_Swap (NULL); PyEval_ReleaseLock (); + make_final_cleanup (finalize_python, NULL); #endif /* HAVE_PYTHON */ } diff --git a/gdb/testsuite/gdb.python/python.exp b/gdb/testsuite/gdb.python/python.exp index 9683b1c..177f94e 100644 --- a/gdb/testsuite/gdb.python/python.exp +++ b/gdb/testsuite/gdb.python/python.exp @@ -141,6 +141,24 @@ gdb_test "python print a" ".*aliases -- Aliases of other commands.*" "verify hel gdb_py_test_silent_cmd "python nothread = gdb.selected_thread()" "Attempt to aquire thread with no inferior" 1 gdb_test "python print nothread == None" "True" "Ensure that no threads are returned" +gdb_py_test_multiple "register atexit function" \ + "python" "" \ + "import atexit" "" \ + "def printit(arg):" "" \ + " print arg" "" \ + "atexit.register(printit, 'good bye world')" "" \ + "end" "" + +send_gdb "quit\n" +gdb_expect { + -re "good bye world" { + pass "atexit handling" + } + default { + fail "atexit handling" + } +} + # Start with a fresh gdb. clean_restart ${testfile}