Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Tom Tromey <tromey@redhat.com>
To: Pedro Alves <pedro@codesourcery.com>
Cc: gdb-patches@sourceware.org
Subject: Re: RFA: fix PR mi/12661
Date: Thu, 02 Jun 2011 17:09:00 -0000	[thread overview]
Message-ID: <m3pqmwnose.fsf@fleche.redhat.com> (raw)
In-Reply-To: <201104271926.30493.pedro@codesourcery.com> (Pedro Alves's	message of "Wed, 27 Apr 2011 19:26:30 +0100")

>>>>> "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);


  reply	other threads:[~2011-06-02 17:09 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-27 18:08 Tom Tromey
2011-04-27 18:26 ` Pedro Alves
2011-06-02 17:09   ` Tom Tromey [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m3pqmwnose.fsf@fleche.redhat.com \
    --to=tromey@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=pedro@codesourcery.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox