hp merge changes -- too numerous to mention here; see ChangeLog and
[deliverable/binutils-gdb.git] / gdb / gnu-nat.c
index 55953c0f334cc583a032fe1afdbad3842fe37164..1cad0aa4f777035ad4e7e710db102277b7a3838a 100644 (file)
@@ -1,5 +1,5 @@
 /* Interface GDB to the GNU Hurd
-   Copyright (C) 1992, 1995, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1995, 1996, 1997 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -67,7 +67,6 @@
 #include "notify_S.h"
 #include "process_reply_S.h"
 #include "msg_reply_S.h"
-
 #include "exc_request_U.h"
 #include "msg_U.h"
 
@@ -85,20 +84,22 @@ int gnu_debug_flag = 0;
 /* Forward decls */
 
 extern struct target_ops gnu_ops;
+extern char *strerror();
 
+int inf_update_procs (struct inf *inf);
 struct inf *make_inf ();
 void inf_clear_wait (struct inf *inf);
 void inf_cleanup (struct inf *inf);
-void inf_startup (struct inf *inf, int pid, task_t task);
+void inf_startup (struct inf *inf, int pid);
 int inf_update_suspends (struct inf *inf);
-void inf_set_task (struct inf *inf, task_t port);
+void inf_set_pid (struct inf *inf, pid_t pid);
 void inf_validate_procs (struct inf *inf);
 void inf_steal_exc_ports (struct inf *inf);
 void inf_restore_exc_ports (struct inf *inf);
-int inf_update_procs (struct inf *inf);
 struct proc *inf_tid_to_proc (struct inf *inf, int tid);
-inline void inf_set_threads_resume_sc (struct inf *inf, struct proc
-                                      *run_thread, int run_others);
+inline void inf_set_threads_resume_sc (struct inf *inf, 
+                                      struct proc *run_thread, 
+                                      int run_others);
 inline int inf_set_threads_resume_sc_for_signal_thread (struct inf *inf);
 inline void inf_suspend (struct inf *inf);
 inline void inf_resume (struct inf *inf);
@@ -111,11 +112,11 @@ void inf_signal (struct inf *inf, enum target_signal sig);
   do { struct inf *__inf = (_inf); \
        debug ("{inf %d %p}: " msg, __inf->pid, __inf , ##args); } while (0)
 
+void proc_abort (struct proc *proc, int force);
+thread_state_t proc_get_state (struct proc *proc, int force);
 struct proc *make_proc (struct inf *inf, mach_port_t port, int tid);
 struct proc *_proc_free (struct proc *proc);
 int proc_update_sc (struct proc *proc);
-void proc_abort (struct proc *proc, int force);
-thread_state_t proc_get_state (struct proc *proc, int force);
 error_t proc_get_exception_port (struct proc *proc, mach_port_t *port);
 error_t proc_set_exception_port (struct proc *proc, mach_port_t port);
 static mach_port_t _proc_get_exc_port (struct proc *proc);
@@ -238,6 +239,7 @@ struct inf
   int want_exceptions;
 };
 
+
 int __proc_pid (struct proc *proc)
 {
   return proc->inf->pid;
@@ -374,6 +376,7 @@ proc_get_state (struct proc *proc, int will_modify)
     return 0;
 }
 \f
+/* Set PORT to PROC's exception port.  */
 error_t
 proc_get_exception_port (struct proc *proc, mach_port_t *port)
 {
@@ -383,6 +386,7 @@ proc_get_exception_port (struct proc *proc, mach_port_t *port)
     return thread_get_exception_port (proc->port, port);
 }
 
+/* Set PROC's exception port to PORT.  */
 error_t
 proc_set_exception_port (struct proc *proc, mach_port_t port)
 {
@@ -456,9 +460,9 @@ proc_steal_exc_port (struct proc *proc, mach_port_t exc_port)
     }
 }
 
-/* If we previously replaced PROC's exception port, put back what we found
-   there at the time, unless *our* exception port has since be overwritten,
-   in which case who knows what's going on.  */
+/* If we previously replaced PROC's exception port, put back what we
+   found there at the time, unless *our* exception port has since been
+   overwritten, in which case who knows what's going on.  */
 void
 proc_restore_exc_port (struct proc *proc)
 {
@@ -486,7 +490,7 @@ proc_restore_exc_port (struct proc *proc)
     }
 }
 \f
-/* Turns hardware tracing in PROC on or off when SET is true or fals,
+/* Turns hardware tracing in PROC on or off when SET is true or false,
    respectively.  Returns true on success.  */
 int
 proc_trace (struct proc *proc, int set)
@@ -576,8 +580,8 @@ make_proc (struct inf *inf, mach_port_t port, int tid)
   return proc;
 }
 
-/* Frees PROC and any resources it uses, and returns the value of PROC's next
-   field.  */
+/* Frees PROC and any resources it uses, and returns the value of PROC's 
+   next field.  */
 struct proc *
 _proc_free (struct proc *proc)
 {
@@ -646,6 +650,7 @@ struct inf *make_inf ()
   return inf;
 }
 
+/* clear INF's target wait status.  */
 void
 inf_clear_wait (struct inf *inf)
 {
@@ -672,7 +677,7 @@ inf_cleanup (struct inf *inf)
 
   inf_clear_wait (inf);
 
-  inf_set_task (inf, MACH_PORT_NULL);
+  inf_set_pid (inf, -1);
   inf->pid = 0;
   inf->traced = 0;
   inf->no_wait = 0;
@@ -688,11 +693,11 @@ inf_cleanup (struct inf *inf)
 }
 
 void
-inf_startup (struct inf *inf, int pid, task_t task)
+inf_startup (struct inf *inf, int pid)
 {
   error_t err;
 
-  inf_debug (inf, "startup: pid = %d, task = %d", pid, task);
+  inf_debug (inf, "startup: pid = %d", pid);
 
   inf_cleanup (inf);
 
@@ -705,39 +710,53 @@ inf_startup (struct inf *inf, int pid, task_t task)
   /* Make a send right for it, so we can easily copy it for other people.  */
   mach_port_insert_right (mach_task_self (), inf->event_port,
                          inf->event_port, MACH_MSG_TYPE_MAKE_SEND);
-
-  if (inf->pause_sc)
-    task_suspend (task);
-
-  inf_set_task (inf, task); 
-
-  if (inf->task)
-    {
-      inf->pid = pid;
-      if (inf->pause_sc)
-       inf->task->sc = inf->task->cur_sc = 1; /* Reflect task_suspend above */
-    }
+  inf_set_pid (inf, pid);
 }
 \f
+/* close current process, if any, and attach INF to process PORT */
 void 
-inf_set_task (struct inf *inf, mach_port_t port)
+inf_set_pid (struct inf *inf, pid_t pid)
 {
+  task_t task_port;
   struct proc *task = inf->task;
 
-  inf_debug (inf, "setting task: %d", port);
+  inf_debug (inf, "setting pid: %d", pid);
 
-  if (task && task->port != port)
+  if (pid < 0)
+    task_port = MACH_PORT_NULL;
+  else
+    {
+      error_t err = proc_pid2task (proc_server, pid, &task_port);
+      if (err)
+       error ("Error getting task for pid %d: %s", pid, strerror (err));
+    }
+
+  inf_debug (inf, "setting task: %d", task_port);
+
+  if (inf->pause_sc)
+    task_suspend (task_port);
+
+  if (task && task->port != task_port)
     {
       inf->task = 0;
       inf_validate_procs (inf);        /* Trash all the threads. */
       _proc_free (task);       /* And the task. */
     }
 
-  if (port != MACH_PORT_NULL)
+  if (task_port != MACH_PORT_NULL)
     {
-      inf->task = make_proc (inf, port, PROC_TID_TASK);
+      inf->task = make_proc (inf, task_port, PROC_TID_TASK);
       inf->threads_up_to_date = 0;
     }
+
+  if (inf->task)
+    {
+      inf->pid = pid;
+      if (inf->pause_sc)
+       inf->task->sc = inf->task->cur_sc = 1; /* Reflect task_suspend above */
+    }
+  else
+    inf->pid = -1;
 }
 \f
 /* Validates INF's stopped field from the actual proc server state.  */
@@ -879,6 +898,7 @@ struct proc *
 inf_tid_to_thread (struct inf *inf, int tid)
 {
   struct proc *thread = inf->threads;
+
   while (thread)
     if (thread->tid == tid)
       return thread;
@@ -1063,9 +1083,9 @@ inf_suspend (struct inf *inf)
   inf_update_suspends (inf);
 }
 \f
-/* INF has one thread PROC that is in single-stepping mode.  This functions
+/* INF has one thread PROC that is in single-stepping mode.  This function
    changes it to be PROC, changing any old step_thread to be a normal one.  A
-   PROC of 0 clears an any existing value.  */
+   PROC of 0 clears any existing value.  */
 void
 inf_set_step_thread (struct inf *inf, struct proc *thread)
 {
@@ -1150,19 +1170,12 @@ inf_detach (struct inf *inf)
 void
 inf_attach (struct inf *inf, int pid)
 {
-  error_t err;
-  task_t task;
-
   inf_debug (inf, "attaching: %d", pid);
 
-  err = proc_pid2task (proc_server, pid, &task);
-  if (err)
-    error ("Error getting task for pid %d: %s", pid, strerror (err));
-
   if (inf->pid)
     inf_detach (inf);
 
-  inf_startup (inf, pid, task);
+  inf_startup (inf, pid);
 }
 \f
 /* Makes sure that we've got our exception ports entrenched in the process. */
@@ -1237,7 +1250,7 @@ inf_signal (struct inf *inf, enum target_signal sig)
   else
     /* A Unix signal.  */
     if (inf->stopped)
-      /* The process is stopped an expecting a signal.  Just send off a
+      /* The process is stopped and expecting a signal.  Just send off a
         request and let it get handled when we resume everything.  */
       {
        inf_debug (inf, "sending %s to stopped process", NAME);
@@ -1356,6 +1369,12 @@ gnu_wait (int tid, struct target_waitstatus *status)
   /* Re-suspend the task.  */
   inf_suspend (inf);
 
+  if (!inf->task && inf->pending_execs)
+    /* When doing an exec, it's possible that the old task wasn't reused
+       (e.g., setuid execs).  So if the task seems to have disappeared,
+       attempt to refetch it, as the pid should still be the same.  */
+    inf_set_pid (inf, inf->pid);
+
   if (err == EMACH_RCV_INTERRUPTED)
     inf_debug (inf, "interrupted");
   else if (err)
@@ -1407,12 +1426,21 @@ gnu_wait (int tid, struct target_waitstatus *status)
          if (--inf->pending_execs == 0)
            /* We're done!  */
            {
+#if 0  /* do we need this? */
              prune_threads (1);        /* Get rid of the old shell threads */
              renumber_threads (0); /* Give our threads reasonable names. */
+#endif
            }
          inf_debug (inf, "pending exec completed, pending_execs => %d",
                     inf->pending_execs);
        }
+      else if (kind == TARGET_WAITKIND_STOPPED)
+       /* It's possible that this signal is because of a crashed process
+          being handled by the hurd crash server; in this case, the process
+          will have an extra task suspend, which we need to know about.
+          Since the code in inf_resume that normally checks for this is
+          disabled while INF->pending_execs, we do the check here instead.  */
+       inf_validate_task_sc (inf);
     }
 
   if (inf->wait.suppress)
@@ -1438,7 +1466,7 @@ gnu_wait (int tid, struct target_waitstatus *status)
     if (inf_update_procs (inf) && inf->threads)
       tid = inf->threads->tid; /* The first available thread.  */
     else
-      tid = -1;
+      tid = inferior_pid; /* let wait_for_inferior handle exit case */
 
   if (thread && tid >= 0 && status->kind != TARGET_WAITKIND_SPURIOUS
       && inf->pause_sc == 0 && thread->pause_sc == 0)
@@ -1830,7 +1858,7 @@ gnu_kill_inferior ()
     {
       proc_debug (task, "terminating...");
       task_terminate (task->port);
-      inf_set_task (current_inferior, MACH_PORT_NULL);
+      inf_set_pid (current_inferior, -1);
     }
   target_mourn_inferior ();
 }
@@ -1849,15 +1877,15 @@ gnu_mourn_inferior ()
 /* Fork an inferior process, and start debugging it.  */
 
 /* Set INFERIOR_PID to the first thread available in the child, if any.  */
-static void
-pick_first_thread ()
+static int
+inf_pick_first_thread ()
 {
   if (current_inferior->task && current_inferior->threads)
     /* The first thread.  */
-    inferior_pid = current_inferior->threads->tid;
+    return current_inferior->threads->tid;
   else
     /* What may be the next thread.  */
-    inferior_pid = next_thread_id;
+    return next_thread_id;
 }
 
 static struct inf *
@@ -1889,7 +1917,6 @@ gnu_create_inferior (exec_file, allargs, env)
       inf_debug (inf, "attaching to child: %d", pid);
 
       inf_attach (inf, pid);
-      pick_first_thread ();
 
       attach_flag = 0;
       push_target (&gnu_ops);
@@ -1900,10 +1927,11 @@ gnu_create_inferior (exec_file, allargs, env)
       /* Now let the child run again, knowing that it will stop immediately
         because of the ptrace. */
       inf_resume (inf);
+      inferior_pid = inf_pick_first_thread ();
 
-      startup_inferior (pid, inf->pending_execs);
+      startup_inferior (inf->pending_execs);
 
-      return pid;
+      return inferior_pid;
     }
 
   inf_debug (inf, "creating inferior");
@@ -1971,7 +1999,7 @@ gnu_attach (args, from_tty)
   inf_attach (inf, pid);
   inf_update_procs (inf);
 
-  pick_first_thread ();
+  inferior_pid = inf_pick_first_thread ();
 
   attach_flag = 1;
   push_target (&gnu_ops);
@@ -1983,7 +2011,9 @@ gnu_attach (args, from_tty)
      time the user does a continue.  */
   inf_validate_stopped (inf);
 
+#if 0 /* Do we need this? */
   renumber_threads (0);                /* Give our threads reasonable names. */
+#endif
 }
 \f
 /* Take a program previously attached to and detaches it.
@@ -2052,6 +2082,13 @@ gnu_stop ()
   error ("to_stop target function not implemented");
 }
 
+static void
+gnu_pid_to_exec_file ()
+{
+  error ("to_pid_to_exec_file target function not implemented");
+}
+
 static int
 gnu_thread_alive (int tid)
 {
@@ -2111,8 +2148,8 @@ struct vm_region_list {
 struct obstack  region_obstack;
 
 /*
- * Write inferior task's LEN bytes from ADDR and copy it to MYADDR
- * in gdb's address space.
+ * Write gdb's LEN bytes from MYADDR and copy it to ADDR
+ * in inferior task's address space.
  */
 int
 gnu_write_inferior (task, addr, myaddr, length)
@@ -2310,50 +2347,77 @@ gnu_xfer_memory (memaddr, myaddr, len, write, target)
 extern void gnu_store_registers (int regno);
 extern void gnu_fetch_registers (int regno);
 
-struct target_ops gnu_ops = {
-  "GNU",                       /* to_shortname */
-  "GNU Hurd process",          /* to_longname */
-  "GNU Hurd process",          /* to_doc */
-  gnu_open,                    /* to_open */
-  0,                           /* to_close */
-  gnu_attach,                  /* to_attach */
-  gnu_detach,                  /* to_detach */
-  gnu_resume,                  /* to_resume */
-  gnu_wait,                    /* to_wait */
-  gnu_fetch_registers,         /* to_fetch_registers */
-  gnu_store_registers,         /* to_store_registers */
-  gnu_prepare_to_store,                /* to_prepare_to_store */
-  gnu_xfer_memory,             /* to_xfer_memory */
-  0,                           /* to_files_info */
-  memory_insert_breakpoint,    /* to_insert_breakpoint */
-  memory_remove_breakpoint,    /* to_remove_breakpoint */
-  gnu_terminal_init_inferior,  /* to_terminal_init */
-  terminal_inferior,           /* to_terminal_inferior */
-  terminal_ours_for_output,    /* to_terminal_ours_for_output */
-  terminal_ours,               /* to_terminal_ours */
-  child_terminal_info,         /* to_terminal_info */
-  gnu_kill_inferior,           /* to_kill */
-  0,                           /* to_load */
-  0,                           /* to_lookup_symbol */
-
-  gnu_create_inferior,         /* to_create_inferior */
-  gnu_mourn_inferior,          /* to_mourn_inferior */
-  gnu_can_run,                 /* to_can_run */
-  0,                           /* to_notice_signals */
-  gnu_thread_alive,            /* to_thread_alive */
-  gnu_stop,                    /* to_stop */
-  process_stratum,             /* to_stratum */
-  0,                           /* to_next */
-  1,                           /* to_has_all_memory */
-  1,                           /* to_has_memory */
-  1,                           /* to_has_stack */
-  1,                           /* to_has_registers */
-  1,                           /* to_has_execution */
-  0,                           /* sections */
-  0,                           /* sections_end */
-  OPS_MAGIC                    /* to_magic */
-};
+struct target_ops gnu_ops ;
+
+static void
+init_gnu_ops(void)
+{
+  gnu_ops.to_shortname =   "GNU";              /* to_shortname */
+  gnu_ops.to_longname =   "GNU Hurd process";  /* to_longname */
+  gnu_ops.to_doc =   "GNU Hurd process";       /* to_doc */
+  gnu_ops.to_open =   gnu_open;                        /* to_open */
+  gnu_ops.to_close =   0;                      /* to_close */
+  gnu_ops.to_attach =   gnu_attach;            /* to_attach */
+  gnu_ops.to_post_attach = NULL;
+  gnu_ops.to_require_attach = NULL;             /* to_require_attach */
+  gnu_ops.to_detach =   gnu_detach;            /* to_detach */
+  gnu_ops.to_require_detach = NULL;             /* to_require_detach */
+  gnu_ops.to_resume =   gnu_resume;            /* to_resume */
+  gnu_ops.to_wait  =   gnu_wait;               /* to_wait */
+  gnu_ops.to_post_wait = NULL;                         /* to_post_wait */
+  gnu_ops.to_fetch_registers  =   gnu_fetch_registers; /* to_fetch_registers */
+  gnu_ops.to_store_registers  =   gnu_store_registers; /* to_store_registers */
+  gnu_ops.to_prepare_to_store =   gnu_prepare_to_store;        /* to_prepare_to_store */
+  gnu_ops.to_xfer_memory  =   gnu_xfer_memory; /* to_xfer_memory */
+  gnu_ops.to_files_info  =   0;                        /* to_files_info */
+  gnu_ops.to_insert_breakpoint =   memory_insert_breakpoint;
+  gnu_ops.to_remove_breakpoint =   memory_remove_breakpoint;
+  gnu_ops.to_terminal_init  =   gnu_terminal_init_inferior;
+  gnu_ops.to_terminal_inferior =   terminal_inferior;
+  gnu_ops.to_terminal_ours_for_output =   terminal_ours_for_output;
+  gnu_ops.to_terminal_ours  =   terminal_ours;
+  gnu_ops.to_terminal_info  =   child_terminal_info;   
+  gnu_ops.to_kill  =   gnu_kill_inferior;      /* to_kill */
+  gnu_ops.to_load  =   0;                      /* to_load */
+  gnu_ops.to_lookup_symbol =   0;              /* to_lookup_symbol */
+  gnu_ops.to_create_inferior =   gnu_create_inferior;  /* to_create_inferior */
+  gnu_ops.to_post_startup_inferior = NULL;      /* to_post_startup_inferior */
+  gnu_ops.to_acknowledge_created_inferior = NULL; /* to_acknowledge_created_inferior */
+  gnu_ops.to_clone_and_follow_inferior = NULL;    /* to_clone_and_follow_inferior */
+  gnu_ops.to_post_follow_inferior_by_clone = NULL; /* to_post_follow_inferior_by_clone */
+  gnu_ops.to_insert_fork_catchpoint = NULL;
+  gnu_ops.to_remove_fork_catchpoint = NULL;
+  gnu_ops.to_insert_vfork_catchpoint = NULL;
+  gnu_ops.to_remove_vfork_catchpoint = NULL;
+  gnu_ops.to_has_forked = NULL;                    /* to_has_forked */
+  gnu_ops.to_has_vforked = NULL;                   /* to_has_vforked */
+  gnu_ops.to_can_follow_vfork_prior_to_exec = NULL;
+  gnu_ops.to_post_follow_vfork = NULL;             /* to_post_follow_vfork */
+  gnu_ops.to_insert_exec_catchpoint = NULL;
+  gnu_ops.to_remove_exec_catchpoint = NULL;
+  gnu_ops.to_has_execd = NULL;
+  gnu_ops.to_reported_exec_events_per_exec_call = NULL;
+  gnu_ops.to_has_exited = NULL;
+  gnu_ops.to_mourn_inferior =   gnu_mourn_inferior; /* to_mourn_inferior */
+  gnu_ops.to_can_run  =   gnu_can_run;         /* to_can_run */
+  gnu_ops.to_notice_signals =   0;             /* to_notice_signals */
+  gnu_ops.to_thread_alive  =   gnu_thread_alive;/* to_thread_alive */
+  gnu_ops.to_stop  =   gnu_stop;               /* to_stop */
+  gnu_ops.to_pid_to_exec_file = gnu_pid_to_exec_file;         /* to_pid_to_exec_file */
+  gnu_ops.to_core_file_to_sym_file = NULL;
+  gnu_ops.to_stratum =   process_stratum;      /* to_stratum */
+  gnu_ops.DONT_USE =   0;                      /* to_next */
+  gnu_ops.to_has_all_memory =   1;             /* to_has_all_memory */
+  gnu_ops.to_has_memory =   1;                 /* to_has_memory */
+  gnu_ops.to_has_stack =   1;                  /* to_has_stack */
+  gnu_ops.to_has_registers =   1;              /* to_has_registers */
+  gnu_ops.to_has_execution =   1;              /* to_has_execution */
+  gnu_ops.to_sections =   0;                   /* sections */
+  gnu_ops.to_sections_end =   0;               /* sections_end */
+  gnu_ops.to_magic =   OPS_MAGIC ;             /* to_magic */
+} /* init_gnu_ops */
 \f
+/* Return printable description of proc.  */
 char *proc_string (struct proc *proc)
 {
   static char tid_str[80];
@@ -2361,8 +2425,7 @@ char *proc_string (struct proc *proc)
     sprintf (tid_str, "process %d", proc->inf->pid);
   else
     sprintf (tid_str, "thread %d.%d",
-            proc->inf->pid,
-            pid_to_thread_id (proc->tid));
+            proc->inf->pid, pid_to_thread_id (proc->tid));
   return tid_str;
 }
 
@@ -2386,9 +2449,41 @@ gnu_target_pid_to_str (int tid)
 
 struct cmd_list_element *set_task_cmd_list = 0;
 struct cmd_list_element *show_task_cmd_list = 0;
+/* User thread commands.  */
 
-extern struct cmd_list_element *set_thread_default_cmd_list;
-extern struct cmd_list_element *show_thread_default_cmd_list;
+/* Commands with a prefix of `set/show thread'.  */
+extern struct cmd_list_element *thread_cmd_list;
+struct cmd_list_element *set_thread_cmd_list = NULL;
+struct cmd_list_element *show_thread_cmd_list = NULL;
+
+/* Commands with a prefix of `set/show thread default'.  */
+struct cmd_list_element *set_thread_default_cmd_list = NULL;
+struct cmd_list_element *show_thread_default_cmd_list = NULL;
+
+static void
+set_thread_cmd (char *args, int from_tty)
+{
+  printf_unfiltered ("\"set thread\" must be followed by the name of a thread
+property, or \"default\".\n");
+}
+
+static void
+show_thread_cmd (char *args, int from_tty)
+{
+  printf_unfiltered ("\"show thread\" must be followed by the name of a thread property, or \"default\".\n");
+}
+
+static void
+set_thread_default_cmd (char *args, int from_tty)
+{
+  printf_unfiltered ("\"set thread default\" must be followed by the name of a thread property.\n");
+}
+
+static void
+show_thread_default_cmd (char *args, int from_tty)
+{
+  printf_unfiltered ("\"show thread default\" must be followed by the name of a thread property.\n");
+}
 
 static int
 parse_int_arg (char *args, char *cmd_prefix)
@@ -2905,11 +3000,6 @@ them).",
   add_info_alias ("psets", "port-sets", 1);
 }
 \f
-/* User thread commands.  */
-
-extern struct cmd_list_element *set_thread_cmd_list;
-extern struct cmd_list_element *show_thread_cmd_list;
-extern struct cmd_list_element *thread_cmd_list;
 
 static void
 set_thread_pause_cmd (char *args, int from_tty)
@@ -2977,12 +3067,7 @@ set_thread_exc_port_cmd (char *args, int from_tty)
   steal_exc_port (thread, parse_and_eval_address (args));
 }
 
-static void 
-set_thread_cmd (char *args, int from_tty)
-{
-  printf_unfiltered ("\"set thread\" must be followed by the name of a thread property.\n");
-}
-
+#if 0
 static void
 show_thread_cmd (char *args, int from_tty)
 {
@@ -2993,6 +3078,7 @@ show_thread_cmd (char *args, int from_tty)
   if (thread->detach_sc != 0)
     show_thread_detach_sc_cmd (0, from_tty);
 }
+#endif
 
 static void
 thread_takeover_sc_cmd (char *args, int from_tty)
@@ -3014,6 +3100,21 @@ thread_takeover_sc_cmd (char *args, int from_tty)
 
 add_thread_commands ()
 {
+  add_prefix_cmd ("thread", no_class, set_thread_cmd,
+                 "Command prefix for setting thread properties.",
+                 &set_thread_cmd_list, "set thread ", 0, &setlist);
+  add_prefix_cmd ("default", no_class, show_thread_cmd,
+                 "Command prefix for setting default thread properties.",
+                 &set_thread_default_cmd_list, "set thread default ", 0,
+                 &set_thread_cmd_list);
+  add_prefix_cmd ("thread", no_class, set_thread_default_cmd,
+                 "Command prefix for showing thread properties.",
+                 &show_thread_cmd_list, "show thread ", 0, &showlist);
+  add_prefix_cmd ("default", no_class, show_thread_default_cmd,
+                 "Command prefix for showing default thread properties.",
+                 &show_thread_default_cmd_list, "show thread default ", 0,
+                 &show_thread_cmd_list);
+
   add_cmd ("pause", class_run, set_thread_pause_cmd,
           "Set whether the current thread is suspended while gdb has control.\n"
           "A value of \"on\" takes effect immediately, otherwise nothing\n"
@@ -3063,9 +3164,8 @@ void
 _initialize_gnu_nat ()
 {
   proc_server = getproc ();
-
+  init_gnu_ops() ;
   add_target (&gnu_ops);
-
   add_task_commands ();
   add_thread_commands ();
 
This page took 0.031382 seconds and 4 git commands to generate.