2010-05-05 Michael Snyder <msnyder@vmware.com>
[deliverable/binutils-gdb.git] / gdb / mi / mi-interp.c
index e601ecd52935e7851a1388f52f74c8d981d23285..c6d7160e231c7be9bb8f71518380902ae22402e4 100644 (file)
@@ -1,6 +1,6 @@
 /* MI Interpreter Definitions and Commands for GDB, the GNU debugger.
 
-   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009
+   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -44,7 +44,7 @@ static void mi_command_loop (int mi_version);
    so we can report interesting things that happened "behind the mi's
    back" in this command */
 static int mi_interp_query_hook (const char *ctlstr, va_list ap)
-     ATTR_FORMAT (printf, 1, 0);
+     ATTRIBUTE_PRINTF (1, 0);
 
 static void mi3_command_loop (void);
 static void mi2_command_loop (void);
@@ -56,13 +56,17 @@ static void mi_on_normal_stop (struct bpstats *bs, int print_frame);
 
 static void mi_new_thread (struct thread_info *t);
 static void mi_thread_exit (struct thread_info *t, int silent);
-static void mi_new_inferior (int pid);
-static void mi_inferior_exit (int pid);
+static void mi_inferior_added (struct inferior *inf);
+static void mi_inferior_appeared (struct inferior *inf);
+static void mi_inferior_exit (struct inferior *inf);
+static void mi_inferior_removed (struct inferior *inf);
 static void mi_on_resume (ptid_t ptid);
 static void mi_solib_loaded (struct so_list *solib);
 static void mi_solib_unloaded (struct so_list *solib);
 static void mi_about_to_proceed (void);
 
+static int report_initial_inferior (struct inferior *inf, void *closure);
+
 static void *
 mi_interpreter_init (int top_level)
 {
@@ -86,13 +90,20 @@ mi_interpreter_init (int top_level)
     {
       observer_attach_new_thread (mi_new_thread);
       observer_attach_thread_exit (mi_thread_exit);
-      observer_attach_new_inferior (mi_new_inferior);
+      observer_attach_inferior_added (mi_inferior_added);
+      observer_attach_inferior_appeared (mi_inferior_appeared);
       observer_attach_inferior_exit (mi_inferior_exit);
+      observer_attach_inferior_removed (mi_inferior_removed);
       observer_attach_normal_stop (mi_on_normal_stop);
       observer_attach_target_resumed (mi_on_resume);
       observer_attach_solib_loaded (mi_solib_loaded);
       observer_attach_solib_unloaded (mi_solib_unloaded);
       observer_attach_about_to_proceed (mi_about_to_proceed);
+
+      /* The initial inferior is created before this function is called, so we
+        need to report it explicitly.  Use iteration in case future version
+        of GDB creates more than one inferior up-front.  */
+      iterate_over_inferiors (report_initial_inferior, mi);
     }
 
   return mi;
@@ -158,7 +169,6 @@ mi_interpreter_suspend (void *data)
 static struct gdb_exception
 mi_interpreter_exec (void *data, const char *command)
 {
-  static struct gdb_exception ok;
   char *tmp = alloca (strlen (command) + 1);
   strcpy (tmp, command);
   mi_execute_command_wrapper (tmp);
@@ -177,7 +187,6 @@ mi_cmd_interpreter_exec (char *command, char **argv, int argc)
 {
   struct interp *interp_to_use;
   int i;
-  struct interp_procs *procs;
   char *mi_error_message = NULL;
   struct cleanup *old_chain;
 
@@ -285,10 +294,13 @@ static void
 mi_new_thread (struct thread_info *t)
 {
   struct mi_interp *mi = top_level_interpreter_data ();
+  struct inferior *inf = find_inferior_pid (ptid_get_pid (t->ptid));
+
+  gdb_assert (inf);
 
   fprintf_unfiltered (mi->event_channel, 
-                     "thread-created,id=\"%d\",group-id=\"%d\"", 
-                     t->num, t->ptid.pid);
+                     "thread-created,id=\"%d\",group-id=\"i%d\"",
+                     t->num, inf->num);
   gdb_flush (mi->event_channel);
 }
 
@@ -296,38 +308,64 @@ static void
 mi_thread_exit (struct thread_info *t, int silent)
 {
   struct mi_interp *mi;
+  struct inferior *inf;
 
   if (silent)
     return;
 
+  inf = find_inferior_pid (ptid_get_pid (t->ptid));
+
   mi = top_level_interpreter_data ();
   target_terminal_ours ();
   fprintf_unfiltered (mi->event_channel, 
-                     "thread-exited,id=\"%d\",group-id=\"%d\"", 
-                     t->num,t->ptid.pid);
+                     "thread-exited,id=\"%d\",group-id=\"i%d\"",
+                     t->num, inf->num);
+  gdb_flush (mi->event_channel);
+}
+
+static void
+mi_inferior_added (struct inferior *inf)
+{
+  struct mi_interp *mi = top_level_interpreter_data ();
+  target_terminal_ours ();
+  fprintf_unfiltered (mi->event_channel,
+                     "thread-group-added,id=\"i%d\"",
+                     inf->num);
   gdb_flush (mi->event_channel);
 }
 
 static void
-mi_new_inferior (int pid)
+mi_inferior_appeared (struct inferior *inf)
 {
   struct mi_interp *mi = top_level_interpreter_data ();
   target_terminal_ours ();
-  fprintf_unfiltered (mi->event_channel, "thread-group-created,id=\"%d\"", 
-                     pid);
+  fprintf_unfiltered (mi->event_channel,
+                     "thread-group-started,id=\"i%d\",pid=\"%d\"",
+                     inf->num, inf->pid);
   gdb_flush (mi->event_channel);
 }
 
 static void
-mi_inferior_exit (int pid)
+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=\"%d\"", 
-                     pid);
+  fprintf_unfiltered (mi->event_channel, "thread-group-exited,id=\"i%d\"",
+                     inf->num);
   gdb_flush (mi->event_channel);  
 }
 
+static void
+mi_inferior_removed (struct inferior *inf)
+{
+  struct mi_interp *mi = top_level_interpreter_data ();
+  target_terminal_ours ();
+  fprintf_unfiltered (mi->event_channel,
+                     "thread-group-removed,id=\"i%d\"",
+                     inf->num);
+  gdb_flush (mi->event_channel);
+}
+
 static void
 mi_on_normal_stop (struct bpstats *bs, int print_frame)
 {
@@ -335,10 +373,10 @@ mi_on_normal_stop (struct bpstats *bs, int print_frame)
      using cli interpreter, be sure to use MI uiout for output,
      not the current one.  */
   struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
-  struct mi_interp *mi = top_level_interpreter_data ();
 
   if (print_frame)
     {
+      int core;
       if (uiout != mi_uiout)
        {
          /* The normal_stop function has printed frame information into 
@@ -364,6 +402,10 @@ mi_on_normal_stop (struct bpstats *bs, int print_frame)
        }
       else
        ui_out_field_string (mi_uiout, "stopped-threads", "all");
+
+      core = target_core_of_thread (inferior_ptid);
+      if (core != -1)
+       ui_out_field_int (mi_uiout, "core", core);
     }
   
   fputs_unfiltered ("*stopped", raw_stdout);
@@ -422,7 +464,7 @@ mi_on_resume (ptid_t ptid)
   if (ptid_equal (ptid, minus_one_ptid) || ptid_is_pid (ptid))
     tp = inferior_thread ();
   else
-    tp = find_thread_pid (ptid);
+    tp = find_thread_ptid (ptid);
 
   /* Suppress output while calling an inferior function.  */
   if (tp->in_infcall)
@@ -438,16 +480,15 @@ mi_on_resume (ptid_t ptid)
      In future (MI3), we'll be outputting "^done" here.  */
   if (!running_result_record_printed && mi_proceeded)
     {
-      if (current_token)
-       fputs_unfiltered (current_token, raw_stdout);
-      fputs_unfiltered ("^running\n", raw_stdout);
+      fprintf_unfiltered (raw_stdout, "%s^running\n",
+                         current_token ? current_token : "");
     }
 
   if (PIDGET (ptid) == -1)
     fprintf_unfiltered (raw_stdout, "*running,thread-id=\"all\"\n");
   else if (ptid_is_pid (ptid))
     {
-      int count;
+      int count = 0;
 
       /* Backwards compatibility.  If there's only one inferior,
         output "all", otherwise, output each resumed thread
@@ -461,7 +502,7 @@ mi_on_resume (ptid_t ptid)
     }
   else
     {
-      struct thread_info *ti = find_thread_pid (ptid);
+      struct thread_info *ti = find_thread_ptid (ptid);
       gdb_assert (ti);
       fprintf_unfiltered (raw_stdout, "*running,thread-id=\"%d\"\n", ti->num);
     }
@@ -485,10 +526,21 @@ mi_solib_loaded (struct so_list *solib)
 {
   struct mi_interp *mi = top_level_interpreter_data ();
   target_terminal_ours ();
-  fprintf_unfiltered (mi->event_channel, 
-                     "library-loaded,id=\"%s\",target-name=\"%s\",host-name=\"%s\",symbols-loaded=\"%d\"", 
-                     solib->so_original_name, solib->so_original_name, 
-                     solib->so_name, solib->symbols_loaded);
+  if (gdbarch_has_global_solist (target_gdbarch))
+    fprintf_unfiltered (mi->event_channel,
+                       "library-loaded,id=\"%s\",target-name=\"%s\","
+                       "host-name=\"%s\",symbols-loaded=\"%d\"",
+                       solib->so_original_name, solib->so_original_name,
+                       solib->so_name, solib->symbols_loaded);
+  else
+    fprintf_unfiltered (mi->event_channel,
+                       "library-loaded,id=\"%s\",target-name=\"%s\","
+                       "host-name=\"%s\",symbols-loaded=\"%d\","
+                       "thread-group=\"i%d\"",
+                       solib->so_original_name, solib->so_original_name,
+                       solib->so_name, solib->symbols_loaded,
+                       current_inferior ()->num);
+
   gdb_flush (mi->event_channel);
 }
 
@@ -497,13 +549,37 @@ mi_solib_unloaded (struct so_list *solib)
 {
   struct mi_interp *mi = top_level_interpreter_data ();
   target_terminal_ours ();
-  fprintf_unfiltered (mi->event_channel, 
-                     "library-unloaded,id=\"%s\",target-name=\"%s\",host-name=\"%s\"", 
-                     solib->so_original_name, solib->so_original_name, 
-                     solib->so_name);
+  if (gdbarch_has_global_solist (target_gdbarch))
+    fprintf_unfiltered (mi->event_channel,
+                       "library-unloaded,id=\"%s\",target-name=\"%s\","
+                       "host-name=\"%s\"",
+                       solib->so_original_name, solib->so_original_name,
+                       solib->so_name);
+  else
+    fprintf_unfiltered (mi->event_channel,
+                       "library-unloaded,id=\"%s\",target-name=\"%s\","
+                       "host-name=\"%s\",thread-group=\"i%d\"",
+                       solib->so_original_name, solib->so_original_name,
+                       solib->so_name, current_inferior ()->num);
+
   gdb_flush (mi->event_channel);
 }
 
+static int
+report_initial_inferior (struct inferior *inf, void *closure)
+{
+  /* This function is called from mi_intepreter_init, and since
+     mi_inferior_added assumes that inferior is fully initialized
+     and top_level_interpreter_data is set, we cannot call
+     it here.  */
+  struct mi_interp *mi = closure;
+  target_terminal_ours ();
+  fprintf_unfiltered (mi->event_channel,
+                     "thread-group-added,id=\"i%d\"",
+                     inf->num);
+  gdb_flush (mi->event_channel);
+  return 0;
+}
 
 extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */
 
This page took 0.028265 seconds and 4 git commands to generate.