From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31374 invoked by alias); 2 Jun 2011 17:09:54 -0000 Received: (qmail 31363 invoked by uid 22791); 2 Jun 2011 17:09:53 -0000 X-SWARE-Spam-Status: No, hits=-6.9 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,T_RP_MATCHES_RCVD 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; Thu, 02 Jun 2011 17:09:32 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p52H9Ob8017105 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 2 Jun 2011 13:09:24 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p52H9NP0022701; Thu, 2 Jun 2011 13:09:23 -0400 Received: from opsy.redhat.com (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id p52H9MGl008480; Thu, 2 Jun 2011 13:09:23 -0400 Received: by opsy.redhat.com (Postfix, from userid 500) id 3FEF9378142; Thu, 2 Jun 2011 11:09:22 -0600 (MDT) From: Tom Tromey To: Pedro Alves Cc: gdb-patches@sourceware.org Subject: Re: RFA: fix PR mi/12661 References: <201104271926.30493.pedro@codesourcery.com> Date: Thu, 02 Jun 2011 17:09:00 -0000 In-Reply-To: <201104271926.30493.pedro@codesourcery.com> (Pedro Alves's message of "Wed, 27 Apr 2011 19:26:30 +0100") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii 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: 2011-06/txt/msg00026.txt.bz2 >>>>> "Pedro" == Pedro Alves writes: Pedro> 1 - I think this observer is called at places where Pedro> get_last_target_status will not make sense --- the last status Pedro> may well be of another inferior. E.g., debug against a live Pedro> target, let it hit a break, detach. Then in the same gdb, open Pedro> and close a core. Pedro> 2 - this observer is called at places where the last target status Pedro> wasn't an exit event, thus status.value.integer will not be an exit code. Pedro> (e.g., infrun.c:follow_exec). Thanks. What do you think of this? It adds information about the exit code to struct inferior. Then it updates the Python API to suit, and also makes the desired change to MI. Tom 2011-06-02 Tom Tromey * python/py-inferior.c (python_inferior_exit): Use inferior's exit code fields. * python/py-exitedevent.c (create_exited_event_object): Change type of 'exit_code'. Optionally add exit_code attribute. (emit_exited_event): Change type of 'exit_code'. * python/py-event.h (emit_exited_event): Update. * mi/mi-interp.c (mi_inferior_exit): Print exit code. * infrun.c (handle_inferior_event): Set exit code fields on inferior. * inferior.h (struct inferior) : New fields. * inferior.c (exit_inferior_1): Initialize new fields. diff --git a/gdb/inferior.c b/gdb/inferior.c index db4dd41..48bb181 100644 --- a/gdb/inferior.c +++ b/gdb/inferior.c @@ -280,6 +280,9 @@ exit_inferior_1 (struct inferior *inftoex, int silent) inf->vfork_parent->vfork_child = NULL; inf->vfork_parent = NULL; } + + inf->has_exit_code = 0; + inf->exit_code = 0; } void diff --git a/gdb/inferior.h b/gdb/inferior.h index f8adb6c..acae0f7 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -509,6 +509,11 @@ struct inferior /* Private data used by the target vector implementation. */ struct private_inferior *private; + /* HAS_EXIT_CODE is true if the inferior exited with an exit code. + In this case, the EXIT_CODE field is also valid. */ + int has_exit_code; + LONGEST exit_code; + /* We keep a count of the number of times the user has requested a particular syscall to be tracked, and pass this information to the target. This lets capable targets implement filtering directly. */ diff --git a/gdb/infrun.c b/gdb/infrun.c index 2d6d523..63f2035 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -3298,6 +3298,11 @@ handle_inferior_event (struct execution_control_state *ecs) that the user can inspect this again later. */ set_internalvar_integer (lookup_internalvar ("_exitcode"), (LONGEST) ecs->ws.value.integer); + + /* Also record this in the inferior itself. */ + current_inferior ()->has_exit_code = 1; + current_inferior ()->exit_code = (LONGEST) ecs->ws.value.integer; + gdb_flush (gdb_stdout); target_mourn_inferior (); singlestep_breakpoints_inserted_p = 0; diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c index c075b0c..7358b73 100644 --- a/gdb/mi/mi-interp.c +++ b/gdb/mi/mi-interp.c @@ -366,8 +366,14 @@ mi_inferior_exit (struct inferior *inf) struct mi_interp *mi = top_level_interpreter_data (); target_terminal_ours (); - fprintf_unfiltered (mi->event_channel, "thread-group-exited,id=\"i%d\"", - inf->num); + if (inf->has_exit_code) + fprintf_unfiltered (mi->event_channel, + "thread-group-exited,id=\"i%d\",exit-code=\"%s\"", + inf->num, int_string (inf->exit_code, 8, 0, 0, 1)); + else + fprintf_unfiltered (mi->event_channel, + "thread-group-exited,id=\"i%d\"", inf->num); + gdb_flush (mi->event_channel); } diff --git a/gdb/python/py-event.h b/gdb/python/py-event.h index bc95521..f4b3ee2 100644 --- a/gdb/python/py-event.h +++ b/gdb/python/py-event.h @@ -104,7 +104,7 @@ typedef struct } event_object; extern int emit_continue_event (ptid_t ptid); -extern int emit_exited_event (LONGEST exit_code); +extern int emit_exited_event (const LONGEST *exit_code); extern int evpy_emit_event (PyObject *event, eventregistry_object *registry); diff --git a/gdb/python/py-exitedevent.c b/gdb/python/py-exitedevent.c index 457a4fe..08150e5 100644 --- a/gdb/python/py-exitedevent.c +++ b/gdb/python/py-exitedevent.c @@ -21,8 +21,8 @@ static PyTypeObject exited_event_object_type; -PyObject * -create_exited_event_object (LONGEST exit_code) +static PyObject * +create_exited_event_object (const LONGEST *exit_code) { PyObject *exited_event; @@ -31,9 +31,10 @@ create_exited_event_object (LONGEST exit_code) if (!exited_event) goto fail; - if (evpy_add_attribute (exited_event, - "exit_code", - PyLong_FromLongLong (exit_code)) < 0) + if (exit_code + && evpy_add_attribute (exited_event, + "exit_code", + PyLong_FromLongLong (*exit_code)) < 0) goto fail; return exited_event; @@ -47,7 +48,7 @@ create_exited_event_object (LONGEST exit_code) will create a new Python exited event object. */ int -emit_exited_event (LONGEST exit_code) +emit_exited_event (const LONGEST *exit_code) { PyObject *event; diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c index b9df394..eda31b5 100644 --- a/gdb/python/py-inferior.c +++ b/gdb/python/py-inferior.c @@ -112,18 +112,14 @@ static void python_inferior_exit (struct inferior *inf) { struct cleanup *cleanup; - LONGEST exit_code = -1; - ptid_t ptidp; - struct target_waitstatus status; + const LONGEST *exit_code = NULL; cleanup = ensure_python_env (get_current_arch (), current_language); - get_last_target_status (&ptidp, &status); + if (inf->has_exit_code) + exit_code = &inf->exit_code; - exit_code = status.value.integer; - - if (exit_code >= 0 - && emit_exited_event (exit_code) < 0) + if (emit_exited_event (exit_code) < 0) gdbpy_print_stack (); do_cleanups (cleanup);