Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* RFA: fix PR mi/12661
@ 2011-04-27 18:08 Tom Tromey
  2011-04-27 18:26 ` Pedro Alves
  0 siblings, 1 reply; 10+ messages in thread
From: Tom Tromey @ 2011-04-27 18:08 UTC (permalink / raw)
  To: gdb-patches

This needs at least a doc review.
In the absence of other comments I will self-approve the code bits.

The bug here is that a thread-group exit looks like this in MI:

=thread-group-exited,id="i1"
*stopped,reason="exited",exit-code="02"

That is, one notification contains the thread group ID, and the other
contains the exit code, but neither contains both.

This patch implements the second suggestion in the PR, namely to put the
exit code into the exited event:

=thread-group-exited,id="i1",exit-code="02"

I took the same implementation approach as used by the python exit
handler.

Built and regtested on our internal buildbot.  This showed some
regressions in one mode (x86-64, Fedora 14, using .gdb_index for the
tests), but I believe those to be some problem on the VM.  The other 3
build modes went fine, modulo the usual inconsistent tests.

Tom

2011-04-27  Tom Tromey  <tromey@redhat.com>

	PR mi/12661:
	* mi/mi-interp.c (mi_inferior_exit): Print exit code.

2011-04-27  Tom Tromey  <tromey@redhat.com>

	* gdb.texinfo (GDB/MI Async Records): Document exit-code.

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 15ccf2e..472e0dc 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -25143,11 +25143,12 @@ was attached to a program.  The @var{id} field contains the
 @value{GDBN} identifier of the thread group.  The @var{pid} field
 contains process identifier, specific to the operating system.
 
-@itemx =thread-group-exited,id="@var{id}"
+@itemx =thread-group-exited,id="@var{id}",exit-code="@var{code}"
 A thread group is no longer associated with a running program,
 either because the program has exited, or because it was detached
 from.  The @var{id} field contains the @value{GDBN} identifier of the
-thread group.
+thread group.  The @var{code} field contains the exit code from the
+inferior.
 
 @item =thread-created,id="@var{id}",group-id="@var{gid}"
 @itemx =thread-exited,id="@var{id}",group-id="@var{gid}"
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index c075b0c..9af6949 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -364,10 +364,16 @@ static void
 mi_inferior_exit (struct inferior *inf)
 {
   struct mi_interp *mi = top_level_interpreter_data ();
+  LONGEST exit_code;
+  struct target_waitstatus status;
+  ptid_t ptidp;
 
   target_terminal_ours ();
-  fprintf_unfiltered (mi->event_channel, "thread-group-exited,id=\"i%d\"",
-		      inf->num);
+  get_last_target_status (&ptidp, &status);
+  exit_code = status.value.integer;
+  fprintf_unfiltered (mi->event_channel,
+ 		      "thread-group-exited,id=\"i%d\",exit-code=\"%s\"",
+ 		      inf->num, int_string (exit_code, 8, 0, 0, 1));
   gdb_flush (mi->event_channel);  
 }
 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: RFA: fix PR mi/12661
  2011-04-27 18:08 RFA: fix PR mi/12661 Tom Tromey
@ 2011-04-27 18:26 ` Pedro Alves
  2011-06-02 17:09   ` Tom Tromey
  0 siblings, 1 reply; 10+ messages in thread
From: Pedro Alves @ 2011-04-27 18:26 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

On Wednesday 27 April 2011 19:08:25, Tom Tromey wrote:
> @@ -364,10 +364,16 @@ static void
>  mi_inferior_exit (struct inferior *inf)
>  {
>    struct mi_interp *mi = top_level_interpreter_data ();
> +  LONGEST exit_code;
> +  struct target_waitstatus status;
> +  ptid_t ptidp;
>  
>    target_terminal_ours ();
> -  fprintf_unfiltered (mi->event_channel, "thread-group-exited,id=\"i%d\"",
> -                     inf->num);
> +  get_last_target_status (&ptidp, &status);
> +  exit_code = status.value.integer;
> +  fprintf_unfiltered (mi->event_channel,
> +                     "thread-group-exited,id=\"i%d\",exit-code=\"%s\"",
> +                     inf->num, int_string (exit_code, 8, 0, 0, 1));
>    gdb_flush (mi->event_channel);  
>  }

1 - I think this observer is called at places where get_last_target_status
will not make sense --- the last status may well be of another inferior.
E.g., debug against a live target, let it hit a break, detach.  Then in the same
gdb, open and close a core.

2 - this observer is called at places where the last target status
wasn't an exit event, thus status.value.integer will not be an exit code.
(e.g., infrun.c:follow_exec).

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: RFA: fix PR mi/12661
  2011-04-27 18:26 ` Pedro Alves
@ 2011-06-02 17:09   ` Tom Tromey
  2011-06-02 17:35     ` Pedro Alves
  0 siblings, 1 reply; 10+ messages in thread
From: Tom Tromey @ 2011-06-02 17:09 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

>>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> 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  <tromey@redhat.com>

	* 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) <has_exit_code, exit_code>: 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);


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: RFA: fix PR mi/12661
  2011-06-02 17:09   ` Tom Tromey
@ 2011-06-02 17:35     ` Pedro Alves
  2011-06-02 19:21       ` Tom Tromey
  0 siblings, 1 reply; 10+ messages in thread
From: Pedro Alves @ 2011-06-02 17:35 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

On Thursday 02 June 2011 18:09:21, Tom Tromey wrote:
> >>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> 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.

Looks good to me, thanks.  I've thought before of adding such
a field, so we could show it in "info inferiors".

You'll want to update the docs to mention the exit_code/exit-code
fields aren't always present, I think.

> 
> Tom
> 
> 2011-06-02  Tom Tromey  <tromey@redhat.com>
> 
> 	* 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) <has_exit_code, exit_code>: 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);
> 

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: RFA: fix PR mi/12661
  2011-06-02 17:35     ` Pedro Alves
@ 2011-06-02 19:21       ` Tom Tromey
  2011-06-02 20:54         ` Eli Zaretskii
  0 siblings, 1 reply; 10+ messages in thread
From: Tom Tromey @ 2011-06-02 19:21 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

>>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes:

Pedro> Looks good to me, thanks.  I've thought before of adding such
Pedro> a field, so we could show it in "info inferiors".

Pedro> You'll want to update the docs to mention the exit_code/exit-code
Pedro> fields aren't always present, I think.

Good point, here is the patch with a doc addition.

Ok?

I plan to add this to 7.3, as the Python event is new there, and it is
best to start it off correctly.

Tom

2011-06-02  Tom Tromey  <tromey@redhat.com>

	* 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) <has_exit_code, exit_code>: New
	fields.
	* inferior.c (exit_inferior_1): Initialize new fields.

2011-06-02  Tom Tromey  <tromey@redhat.com>

	* gdb.texinfo (GDB/MI Async Records): Document 'exit-code' field.
	(Events In Python): Note that exit_code is optional.

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 0ac5672..ad75867 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -22093,7 +22093,9 @@ inherited attribute refer to @code{gdb.ThreadEvent} above.
 
 @item events.exited
 Emits @code{events.ExitedEvent} which indicates that the inferior has exited.
-@code{events.ExitedEvent} has one attribute:
+@code{events.ExitedEvent} has one optional attribute.  This attribute
+will exist only in the case that the inferior exited with some
+status.
 @table @code
 @defivar ExitedEvent exit_code
 An integer representing the exit code which the inferior has returned.
@@ -25140,11 +25142,12 @@ was attached to a program.  The @var{id} field contains the
 @value{GDBN} identifier of the thread group.  The @var{pid} field
 contains process identifier, specific to the operating system.
 
-@itemx =thread-group-exited,id="@var{id}"
+@itemx =thread-group-exited,id="@var{id}"[,exit-code="@var{code}"]
 A thread group is no longer associated with a running program,
 either because the program has exited, or because it was detached
 from.  The @var{id} field contains the @value{GDBN} identifier of the
-thread group.
+thread group.  The @var{code} field is the exit code of the inferior;
+it exists only when the inferior exited with some code.
 
 @item =thread-created,id="@var{id}",group-id="@var{gid}"
 @itemx =thread-exited,id="@var{id}",group-id="@var{gid}"
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);


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: RFA: fix PR mi/12661
  2011-06-02 19:21       ` Tom Tromey
@ 2011-06-02 20:54         ` Eli Zaretskii
  2011-06-02 21:01           ` Tom Tromey
  2011-06-03 15:14           ` Tom Tromey
  0 siblings, 2 replies; 10+ messages in thread
From: Eli Zaretskii @ 2011-06-02 20:54 UTC (permalink / raw)
  To: Tom Tromey; +Cc: pedro, gdb-patches

> From: Tom Tromey <tromey@redhat.com>
> Cc: gdb-patches@sourceware.org
> Date: Thu, 02 Jun 2011 13:20:57 -0600
> 
> Pedro> You'll want to update the docs to mention the exit_code/exit-code
> Pedro> fields aren't always present, I think.
> 
> Good point, here is the patch with a doc addition.

Thanks.

> -@itemx =thread-group-exited,id="@var{id}"
> +@itemx =thread-group-exited,id="@var{id}"[,exit-code="@var{code}"]

This should be @item, not @itemx.  (Yes, the original text was also in
error.)

> +thread group.  The @var{code} field is the exit code of the inferior;

"Code" is not a field, it's the value of the "exit-code" field, isn't
it?

Okay with those changes.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: RFA: fix PR mi/12661
  2011-06-02 20:54         ` Eli Zaretskii
@ 2011-06-02 21:01           ` Tom Tromey
  2011-06-02 21:24             ` Eli Zaretskii
  2011-06-03 15:14           ` Tom Tromey
  1 sibling, 1 reply; 10+ messages in thread
From: Tom Tromey @ 2011-06-02 21:01 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: pedro, gdb-patches

>>>>> "Eli" == Eli Zaretskii <eliz@gnu.org> writes:

>> +thread group.  The @var{code} field is the exit code of the inferior;

Eli> "Code" is not a field, it's the value of the "exit-code" field, isn't
Eli> it?

Yes, I see what you mean, but I am not sure exactly what change you
want.

Perhaps, "@var{code} is the exit code of the inferior; ..."?

Tom


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: RFA: fix PR mi/12661
  2011-06-02 21:01           ` Tom Tromey
@ 2011-06-02 21:24             ` Eli Zaretskii
  2011-06-03 15:26               ` Tom Tromey
  0 siblings, 1 reply; 10+ messages in thread
From: Eli Zaretskii @ 2011-06-02 21:24 UTC (permalink / raw)
  To: Tom Tromey; +Cc: pedro, gdb-patches

> From: Tom Tromey <tromey@redhat.com>
> Cc: pedro@codesourcery.com, gdb-patches@sourceware.org
> Date: Thu, 02 Jun 2011 15:00:32 -0600
> 
> Perhaps, "@var{code} is the exit code of the inferior; ..."?

Yes, that'd be good.  Alternatively, you could say

  The value of the @code{exit-code} field is the exit code of the inferior


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: RFA: fix PR mi/12661
  2011-06-02 20:54         ` Eli Zaretskii
  2011-06-02 21:01           ` Tom Tromey
@ 2011-06-03 15:14           ` Tom Tromey
  1 sibling, 0 replies; 10+ messages in thread
From: Tom Tromey @ 2011-06-03 15:14 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: pedro, gdb-patches

>>>>> "Eli" == Eli Zaretskii <eliz@gnu.org> writes:

>> -@itemx =thread-group-exited,id="@var{id}"
>> +@itemx =thread-group-exited,id="@var{id}"[,exit-code="@var{code}"]

Eli> This should be @item, not @itemx.  (Yes, the original text was also in
Eli> error.)

I sent a note to bug-texinfo about this.
I think makeinfo ought to give an error in this case.

Tom


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: RFA: fix PR mi/12661
  2011-06-02 21:24             ` Eli Zaretskii
@ 2011-06-03 15:26               ` Tom Tromey
  0 siblings, 0 replies; 10+ messages in thread
From: Tom Tromey @ 2011-06-03 15:26 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: pedro, gdb-patches

>>>>> "Eli" == Eli Zaretskii <eliz@gnu.org> writes:

Eli> Yes, that'd be good.  Alternatively, you could say
Eli>   The value of the @code{exit-code} field is the exit code of the inferior

Here is what I am checking in.

Tom

2011-06-03  Tom Tromey  <tromey@redhat.com>

	* 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) <has_exit_code, exit_code>: New
	fields.
	* inferior.c (exit_inferior_1): Initialize new fields.

2011-06-03  Tom Tromey  <tromey@redhat.com>

	* gdb.texinfo (GDB/MI Async Records): Document 'exit-code' field.
	(Events In Python): Note that exit_code is optional.

Index: inferior.c
===================================================================
RCS file: /cvs/src/src/gdb/inferior.c,v
retrieving revision 1.28
diff -u -r1.28 inferior.c
--- inferior.c	27 May 2011 18:26:19 -0000	1.28
+++ inferior.c	3 Jun 2011 15:17:42 -0000
@@ -281,6 +281,9 @@
       inf->vfork_parent->vfork_child = NULL;
       inf->vfork_parent = NULL;
     }
+
+  inf->has_exit_code = 0;
+  inf->exit_code = 0;
 }
 
 void
Index: inferior.h
===================================================================
RCS file: /cvs/src/src/gdb/inferior.h,v
retrieving revision 1.159
diff -u -r1.159 inferior.h
--- inferior.h	26 May 2011 18:23:31 -0000	1.159
+++ inferior.h	3 Jun 2011 15:17:42 -0000
@@ -517,6 +517,11 @@
   /* 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.  */
Index: infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.490
diff -u -r1.490 infrun.c
--- infrun.c	30 May 2011 18:04:32 -0000	1.490
+++ infrun.c	3 Jun 2011 15:17:43 -0000
@@ -3308,6 +3308,11 @@
          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;
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.840
diff -u -r1.840 gdb.texinfo
--- doc/gdb.texinfo	17 May 2011 13:29:38 -0000	1.840
+++ doc/gdb.texinfo	3 Jun 2011 15:17:48 -0000
@@ -22127,7 +22127,9 @@
 
 @item events.exited
 Emits @code{events.ExitedEvent} which indicates that the inferior has exited.
-@code{events.ExitedEvent} has one attribute:
+@code{events.ExitedEvent} has one optional attribute.  This attribute
+will exist only in the case that the inferior exited with some
+status.
 @table @code
 @defivar ExitedEvent exit_code
 An integer representing the exit code which the inferior has returned.
@@ -25199,11 +25201,12 @@
 @value{GDBN} identifier of the thread group.  The @var{pid} field
 contains process identifier, specific to the operating system.
 
-@itemx =thread-group-exited,id="@var{id}"
+@item =thread-group-exited,id="@var{id}"[,exit-code="@var{code}"]
 A thread group is no longer associated with a running program,
 either because the program has exited, or because it was detached
 from.  The @var{id} field contains the @value{GDBN} identifier of the
-thread group.
+thread group.  @var{code} is the exit code of the inferior; it exists
+only when the inferior exited with some code.
 
 @item =thread-created,id="@var{id}",group-id="@var{gid}"
 @itemx =thread-exited,id="@var{id}",group-id="@var{gid}"
Index: mi/mi-interp.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-interp.c,v
retrieving revision 1.64
diff -u -r1.64 mi-interp.c
--- mi/mi-interp.c	27 Apr 2011 10:17:37 -0000	1.64
+++ mi/mi-interp.c	3 Jun 2011 15:17:48 -0000
@@ -366,8 +366,14 @@
   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);  
 }
 
Index: python/py-event.h
===================================================================
RCS file: /cvs/src/src/gdb/python/py-event.h,v
retrieving revision 1.1
diff -u -r1.1 py-event.h
--- python/py-event.h	5 Feb 2011 05:27:23 -0000	1.1
+++ python/py-event.h	3 Jun 2011 15:17:48 -0000
@@ -104,7 +104,7 @@
 } 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);
Index: python/py-exitedevent.c
===================================================================
RCS file: /cvs/src/src/gdb/python/py-exitedevent.c,v
retrieving revision 1.1
diff -u -r1.1 py-exitedevent.c
--- python/py-exitedevent.c	5 Feb 2011 05:27:23 -0000	1.1
+++ python/py-exitedevent.c	3 Jun 2011 15:17:48 -0000
@@ -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 @@
   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 @@
    will create a new Python exited event object.  */
 
 int
-emit_exited_event (LONGEST exit_code)
+emit_exited_event (const LONGEST *exit_code)
 {
   PyObject *event;
 
Index: python/py-inferior.c
===================================================================
RCS file: /cvs/src/src/gdb/python/py-inferior.c,v
retrieving revision 1.8
diff -u -r1.8 py-inferior.c
--- python/py-inferior.c	19 May 2011 18:41:23 -0000	1.8
+++ python/py-inferior.c	3 Jun 2011 15:17:48 -0000
@@ -112,18 +112,14 @@
 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 (target_gdbarch, 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);


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2011-06-03 15:26 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-27 18:08 RFA: fix PR mi/12661 Tom Tromey
2011-04-27 18:26 ` Pedro Alves
2011-06-02 17:09   ` Tom Tromey
2011-06-02 17:35     ` Pedro Alves
2011-06-02 19:21       ` Tom Tromey
2011-06-02 20:54         ` Eli Zaretskii
2011-06-02 21:01           ` Tom Tromey
2011-06-02 21:24             ` Eli Zaretskii
2011-06-03 15:26               ` Tom Tromey
2011-06-03 15:14           ` Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox