This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Make target_ops->to_has_FOO functions instead of variables.


Continuing with the split of target debug interface vs target
inferior, here's another required infrastructure change for
multi-process/exec.

First, setting things straight: a single target interface can control
more than one inferior.  E.g., when remote debugging against a
multi-process aware server, a single connection (target interface)
can expose several inferiors.  On native, the same
interface (e.g., ptrace), can control several inferiors, either
because we'd run/attach them manually, or by following forks.

Throughout gdb, we use target_has_stack, target_has_registers,
etc., but, consider the case where you have simultaneously:

(gdb) fake-info-inferiors-command
  1  /bin/cat, loaded and running, pid 1234
* 2  /bin/echo, loaded but not running.

If you have the focus on echo, you'd want target_has_execution,
target_has_stack, target_has_registers to return false, although
the same target interface that is managing cat will run
echo, and it is already pushed, in fact.  This is so that
"backtrace" complains, set *foo = bar errors out, etc.,
in sum, so that GDB works the same as in the single-inferior/single-executable
case, when echo hadn't been running yet.

The patch below addresses this, by rewriting the target_has_FOO
properties as methods, so that they can return a different
result depending on the current inferior/program.

This actually gets rid of the need for the target_mark_exited and
target_mark_running functions.  In turn, this also means that (other
than to_data), we don't have any more mutable (non-function) member
in target_ops that change after the target is created/opened.

There are some places in gdb's core that want to check if the
current inferior has execution.  Those, will continue using
target_has_execution.  There are other places that want to
check if there's any inferior to debug yet.  Those are
adjusted to use have_inferiors or the new have_live_inferiors.

target_read_memory and friends got a little tweak to start reading
from the topmost target in the stack (current_target.beneath), instead
of from the flattened current_target, since that one doesn't implement
the to_has_FOO methods.

The target_has_execution hacks within thread.c:is_running|is_stopped
now go away.  We don't need them anymore, and are in fact wrong
with this patch --- these functions in thread.c must not depend on
the current inferior.

linux-nat.c:to_xfer_partial implementation then takes care of
realising that there's no inferior selected, so it should defer
memory reads to a lower stratum.  Note that this is what
remote.c:remote_xfer_partial has been doing this for a while, ever
since gdbserver extended-remote support went in.

Comments?

Tested on x86_64-linux, native and gdbserver.

-- 
Pedro Alves

2009-06-04  Pedro Alves  <pedro@codesourcery.com>

	* target.h (struct target_ops): Make to_has_all_memory,
	to_has_memory, to_has_stack, to_has_registers and to_has_execution
	methods instead of variables.
	(target_has_all_memory_1, target_has_memory_1, target_has_stack_1)
	(target_has_registers_1, target_has_execution_1): Declare
	functions.
	(target_has_all_memory): Rewrite to call target_has_all_memory_1.
	(target_has_memory): Rewrite to call target_has_memory_1.
	(target_has_stack): Rewrite to call target_has_all_stack_1.
	(target_has_registers): Rewrite to call target_has_registers_1.
	(target_has_execution): Rewrite to call target_has_execution_1.
	(default_child_has_all_memory, default_child_has_memory)
	(default_child_has_stack, default_child_has_registers)
	(default_child_has_execution): Declare.
	(target_mark_running, target_mark_exited): Delete declarations.
	* target.c (default_child_has_all_memory,
	default_child_has_memory, default_child_has_stack,
	default_child_has_registers, default_child_has_execution): New.
	(target_has_all_memory_1, target_has_memory_1, target_has_stack_1,
	target_has_registers_1, target_has_execution_1): New.
	(add_target): Default the to_has_all_memory, to_has_all_memory,
	to_has_memory, to_has_stack, to_has_registers and to_has_execution
	callbacks to return 0.
	(update_current_target): Do not inherit to_has_all_memory,
	to_has_memory, to_has_stack, to_has_registers or to_has_execution.
	(target_mark_running, target_mark_exited): Delete.
	(memory_xfer_partial): Adjust.
	(target_read_memory, target_write_memory, target_search_memory):
	Dispatch to the the top-most target, not the flattened
	current_target.
	(target_info): Adjust.
	(init_dummy_target): Install return_zero as callback for
	to_has_all_memory, to_has_memory, to_has_stack, to_has_registers,
	to_has_execution.
	(set_maintenance_target_async_permitted): Use have_live_inferiors
	instead of target_has_execution.

	* breakpoint.c (insert_breakpoints): Don't check for
	target_has_execution here.
	(update_global_location_list): Check if there are live inferiors
	to debug instead of target_has_execution.
	* infcmd.c (kill_command, detach_command): Check if there are
	inferiors instead of target_has_execution.
	* inferior.h (have_live_inferiors): Declare.
	* inferior.c (have_live_inferiors): New.
	* infrun.c (normal_stop): Don't check for target_has_execution to
	finish the thread states.
	* thread.c (is_thread_state, is_stopped, is_exited, is_running)
	(any_running, is_executing): Remove checks for
	target_has_execution.
	* top.c (kill_or_detach): Don't try to kill core inferiors.
	(quit_target): Don't check for target_has_execution.

	* corelow.c (core_has_memory, core_has_stack, core_has_registers):
	New.
	(init_core_ops): Install core_has_memory, core_has_stack and
	core_has_registers.
	* exec.c (exec_has_memory): New.
	(init_exec_ops): Install exec_has_memory.
	* remote.c (remote_add_inferior): Don't call target_mark_running.
	(remote_start_remote): Don't call target_mark_exited or call
	target_mark_running.
	(remote_open_1): Use have_inferiors instead of
	target_has_execution.  Don't use target_mark_exited.
	(init_remote_ops): Install deafult_child_has_all_memory,
	default_child_has_memory, default_child_has_stack,
	default_child_has_registers, default_child_has_execution.
	* bsd-kvm.c (bsd_kvm_return_one): New.
	(bsd_kvm_add_target): Register bsd_kvm_return_one as
	to_has_memory, to_has_stack and to_has_registers callbacks.
	* remote-m32r-sdi.c (m32r_return_one): New.
	(init_m32r_ops): Register it.
	* inf-child.c (inf_child_target): Adjust to register
	default_child_has_all_memory, default_child_has_memory,
	default_child_has_stack, default_child_has_registers,
	default_child_has_execution callbacks.
	* gnu-nat.c (init_gnu_ops): Likewise.
	* go32-nat.c (init_go32_ops): Likewise.
	* hpux-thread.c (init_hpux_thread_ops): Likewise.
	* monitor.c (init_base_monitor_ops): Likewise.
	* nto-procfs.c (init_procfs_ops): Likewise.
	* remote-mips.c (_initialize_remote_mips): Likewise.
	* windows-nat.c (init_windows_ops): Likewise.
	* remote-sim.c (gdbsim_create_inferior): Don't use
	target_mark_running or target_mark_exited.
	(gdbsim_mourn_inferior): Don't call target_mark_exited.
	(init_gdbsim_ops): Adjust to register
	default_child_has_all_memory, default_child_has_memory,
	default_child_has_stack, default_child_has_registers,
	default_child_has_execution callbacks.

	* linux-nat.c (linux_nat_xfer_partial): If reading memory, and
	there's no inferior selected, defer to a lower stratum.

---
 gdb/breakpoint.c      |   12 +-
 gdb/bsd-kvm.c         |   12 ++
 gdb/corelow.c         |   24 +++++
 gdb/exec.c            |   11 ++
 gdb/gnu-nat.c         |   10 +-
 gdb/go32-nat.c        |   10 +-
 gdb/hpux-thread.c     |   10 +-
 gdb/inf-child.c       |   10 +-
 gdb/infcmd.c          |   12 +-
 gdb/inferior.c        |    8 +
 gdb/inferior.h        |    4 
 gdb/infrun.c          |   13 +--
 gdb/linux-nat.c       |    5 +
 gdb/monitor.c         |   10 +-
 gdb/nto-procfs.c      |   10 +-
 gdb/remote-m32r-sdi.c |   15 ++-
 gdb/remote-mips.c     |   10 +-
 gdb/remote-sim.c      |   13 +--
 gdb/remote.c          |   65 ++++-----------
 gdb/target.c          |  208 +++++++++++++++++++++++++++++++++++---------------
 gdb/target.h          |   46 +++++------
 gdb/thread.c          |   21 -----
 gdb/top.c             |   16 ++-
 gdb/windows-nat.c     |   10 +-
 24 files changed, 325 insertions(+), 240 deletions(-)

Index: src/gdb/target.h
===================================================================
--- src.orig/gdb/target.h	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/target.h	2009-06-04 15:04:30.000000000 +0100
@@ -415,11 +415,11 @@ struct target_ops
     void (*to_log_command) (const char *);
     struct target_section_table *(*to_get_section_table) (struct target_ops *);
     enum strata to_stratum;
-    int to_has_all_memory;
-    int to_has_memory;
-    int to_has_stack;
-    int to_has_registers;
-    int to_has_execution;
+    int (*to_has_all_memory) (struct target_ops *);
+    int (*to_has_memory) (struct target_ops *);
+    int (*to_has_stack) (struct target_ops *);
+    int (*to_has_registers) (struct target_ops *);
+    int (*to_has_execution) (struct target_ops *);
     int to_has_thread_control;	/* control thread execution */
     int to_attach_no_wait;
     /* ASYNC target controls */
@@ -931,24 +931,24 @@ extern void target_find_new_threads (voi
    determines whether we look up the target chain for other parts of
    memory if this target can't satisfy a request.  */
 
-#define	target_has_all_memory	\
-     (current_target.to_has_all_memory)
+extern int target_has_all_memory_1 (void);
+#define target_has_all_memory target_has_all_memory_1 ()
 
 /* Does the target include memory?  (Dummy targets don't.)  */
 
-#define	target_has_memory	\
-     (current_target.to_has_memory)
+extern int target_has_memory_1 (void);
+#define target_has_memory target_has_memory_1 ()
 
 /* Does the target have a stack?  (Exec files don't, VxWorks doesn't, until
    we start a process.)  */
 
-#define	target_has_stack	\
-     (current_target.to_has_stack)
+extern int target_has_stack_1 (void);
+#define target_has_stack target_has_stack_1 ()
 
 /* Does the target have registers?  (Exec files don't.)  */
 
-#define	target_has_registers	\
-     (current_target.to_has_registers)
+extern int target_has_registers_1 (void);
+#define target_has_registers target_has_registers_1 ()
 
 /* Does the target have execution?  Can we make it jump (through
    hoops), or pop its stack a few times?  This means that the current
@@ -958,8 +958,17 @@ extern void target_find_new_threads (voi
    case this will become true after target_create_inferior or
    target_attach.  */
 
-#define	target_has_execution	\
-     (current_target.to_has_execution)
+extern int target_has_execution_1 (void);
+#define target_has_execution target_has_execution_1 ()
+
+/* Default implementations for process_stratum targets.  Return true
+   if there's a selected inferior, false otherwise.  */
+
+extern int default_child_has_all_memory (struct target_ops *ops);
+extern int default_child_has_memory (struct target_ops *ops);
+extern int default_child_has_stack (struct target_ops *ops);
+extern int default_child_has_registers (struct target_ops *ops);
+extern int default_child_has_execution (struct target_ops *ops);
 
 /* Can the target support the debugger control of thread execution?
    Can it lock the thread scheduler?  */
@@ -1178,13 +1187,6 @@ extern void pop_all_targets_above (enum 
 extern CORE_ADDR target_translate_tls_address (struct objfile *objfile,
 					       CORE_ADDR offset);
 
-/* Mark a pushed target as running or exited, for targets which do not
-   automatically pop when not active.  */
-
-void target_mark_running (struct target_ops *);
-
-void target_mark_exited (struct target_ops *);
-
 /* Struct target_section maps address ranges to file sections.  It is
    mostly used with BFD files, but can be used without (e.g. for handling
    raw disks, or files not in formats handled by BFD).  */
Index: src/gdb/inf-child.c
===================================================================
--- src.orig/gdb/inf-child.c	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/inf-child.c	2009-06-04 15:04:30.000000000 +0100
@@ -193,11 +193,11 @@ inf_child_target (void)
   t->to_can_run = inf_child_can_run;
   t->to_pid_to_exec_file = inf_child_pid_to_exec_file;
   t->to_stratum = process_stratum;
-  t->to_has_all_memory = 1;
-  t->to_has_memory = 1;
-  t->to_has_stack = 1;
-  t->to_has_registers = 1;
-  t->to_has_execution = 1;
+  t->to_has_all_memory = default_child_has_all_memory;
+  t->to_has_memory = default_child_has_memory;
+  t->to_has_stack = default_child_has_stack;
+  t->to_has_registers = default_child_has_registers;
+  t->to_has_execution = default_child_has_execution;
   t->to_magic = OPS_MAGIC;
   return t;
 }
Index: src/gdb/target.c
===================================================================
--- src.orig/gdb/target.c	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/target.c	2009-06-04 15:04:30.000000000 +0100
@@ -213,6 +213,120 @@ target_command (char *arg, int from_tty)
 		  gdb_stdout);
 }
 
+/* Default target_has_* methods for process_stratum targets.  */
+
+int
+default_child_has_all_memory (struct target_ops *ops)
+{
+  /* If no inferior selected, then we can't read memory here.  */
+  if (ptid_equal (inferior_ptid, null_ptid))
+    return 0;
+
+  return 1;
+}
+
+int
+default_child_has_memory (struct target_ops *ops)
+{
+  /* If no inferior selected, then we can't read memory here.  */
+  if (ptid_equal (inferior_ptid, null_ptid))
+    return 0;
+
+  return 1;
+}
+
+int
+default_child_has_stack (struct target_ops *ops)
+{
+  /* If no inferior selected, there's no stack.  */
+  if (ptid_equal (inferior_ptid, null_ptid))
+    return 0;
+
+  return 1;
+}
+
+int
+default_child_has_registers (struct target_ops *ops)
+{
+  /* Can't read registers from no inferior.  */
+  if (ptid_equal (inferior_ptid, null_ptid))
+    return 0;
+
+  return 1;
+}
+
+int
+default_child_has_execution (struct target_ops *ops)
+{
+  /* If there's no thread selected, then we can't make it run through
+     hoops.  */
+  if (ptid_equal (inferior_ptid, null_ptid))
+    return 0;
+
+  return 1;
+}
+
+
+int
+target_has_all_memory_1 (void)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_has_all_memory (t))
+      return 1;
+
+  return 0;
+}
+
+int
+target_has_memory_1 (void)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_has_memory (t))
+      return 1;
+
+  return 0;
+}
+
+int
+target_has_stack_1 (void)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_has_stack (t))
+      return 1;
+
+  return 0;
+}
+
+int
+target_has_registers_1 (void)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_has_registers (t))
+      return 1;
+
+  return 0;
+}
+
+int
+target_has_execution_1 (void)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_has_execution (t))
+      return 1;
+
+  return 0;
+}
+
 /* Add a possible target architecture to the list.  */
 
 void
@@ -222,6 +336,21 @@ add_target (struct target_ops *t)
   if (t->to_xfer_partial == NULL)
     t->to_xfer_partial = default_xfer_partial;
 
+  if (t->to_has_all_memory == NULL)
+    t->to_has_all_memory = (int (*) (struct target_ops *)) return_zero;
+
+  if (t->to_has_memory == NULL)
+    t->to_has_memory = (int (*) (struct target_ops *)) return_zero;
+
+  if (t->to_has_stack == NULL)
+    t->to_has_stack = (int (*) (struct target_ops *)) return_zero;
+
+  if (t->to_has_registers == NULL)
+    t->to_has_registers = (int (*) (struct target_ops *)) return_zero;
+
+  if (t->to_has_execution == NULL)
+    t->to_has_execution = (int (*) (struct target_ops *)) return_zero;
+
   if (!target_structs)
     {
       target_struct_allocsize = DEFAULT_ALLOCSIZE;
@@ -486,11 +615,11 @@ update_current_target (void)
       INHERIT (to_pid_to_exec_file, t);
       INHERIT (to_log_command, t);
       INHERIT (to_stratum, t);
-      INHERIT (to_has_all_memory, t);
-      INHERIT (to_has_memory, t);
-      INHERIT (to_has_stack, t);
-      INHERIT (to_has_registers, t);
-      INHERIT (to_has_execution, t);
+      /* Do not inherit to_has_all_memory */
+      /* Do not inherit to_has_memory */
+      /* Do not inherit to_has_stack */
+      /* Do not inherit to_has_registers */
+      /* Do not inherit to_has_execution */
       INHERIT (to_has_thread_control, t);
       INHERIT (to_can_async_p, t);
       INHERIT (to_is_async_p, t);
@@ -658,56 +787,6 @@ update_current_target (void)
     setup_target_debug ();
 }
 
-/* Mark OPS as a running target.  This reverses the effect
-   of target_mark_exited.  */
-
-void
-target_mark_running (struct target_ops *ops)
-{
-  struct target_ops *t;
-
-  for (t = target_stack; t != NULL; t = t->beneath)
-    if (t == ops)
-      break;
-  if (t == NULL)
-    internal_error (__FILE__, __LINE__,
-		    "Attempted to mark unpushed target \"%s\" as running",
-		    ops->to_shortname);
-
-  ops->to_has_execution = 1;
-  ops->to_has_all_memory = 1;
-  ops->to_has_memory = 1;
-  ops->to_has_stack = 1;
-  ops->to_has_registers = 1;
-
-  update_current_target ();
-}
-
-/* Mark OPS as a non-running target.  This reverses the effect
-   of target_mark_running.  */
-
-void
-target_mark_exited (struct target_ops *ops)
-{
-  struct target_ops *t;
-
-  for (t = target_stack; t != NULL; t = t->beneath)
-    if (t == ops)
-      break;
-  if (t == NULL)
-    internal_error (__FILE__, __LINE__,
-		    "Attempted to mark unpushed target \"%s\" as running",
-		    ops->to_shortname);
-
-  ops->to_has_execution = 0;
-  ops->to_has_all_memory = 0;
-  ops->to_has_memory = 0;
-  ops->to_has_stack = 0;
-  ops->to_has_registers = 0;
-
-  update_current_target ();
-}
-
 /* Push a new target type into the stack of the existing target accessors,
    possibly superseding some of the existing accessors.
 
@@ -1176,7 +1255,7 @@ memory_xfer_partial (struct target_ops *
 
       /* We want to continue past core files to executables, but not
 	 past a running target's memory.  */
-      if (ops->to_has_all_memory)
+      if (ops->to_has_all_memory (ops))
 	break;
 
       ops = ops->beneath;
@@ -1293,7 +1372,7 @@ target_xfer_partial (struct target_ops *
 int
 target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
 {
-  if (target_read (&current_target, TARGET_OBJECT_MEMORY, NULL,
+  if (target_read (current_target.beneath, TARGET_OBJECT_MEMORY, NULL,
 		   myaddr, memaddr, len) == len)
     return 0;
   else
@@ -1303,7 +1382,7 @@ target_read_memory (CORE_ADDR memaddr, g
 int
 target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, int len)
 {
-  if (target_write (&current_target, TARGET_OBJECT_MEMORY, NULL,
+  if (target_write (current_target.beneath, TARGET_OBJECT_MEMORY, NULL,
 		    myaddr, memaddr, len) == len)
     return 0;
   else
@@ -1756,7 +1835,7 @@ target_info (char *args, int from_tty)
 
   for (t = target_stack; t != NULL; t = t->beneath)
     {
-      if (!t->to_has_memory)
+      if (!(*t->to_has_memory) (t))
 	continue;
 
       if ((int) (t->to_stratum) <= (int) dummy_stratum)
@@ -1765,7 +1844,7 @@ target_info (char *args, int from_tty)
 	printf_unfiltered (_("\tWhile running this, GDB does not access memory from...\n"));
       printf_unfiltered ("%s:\n", t->to_longname);
       (t->to_files_info) (t);
-      has_all_mem = t->to_has_all_memory;
+      has_all_mem = (*t->to_has_all_memory) (t);
     }
 }
 
@@ -2169,7 +2248,7 @@ target_search_memory (CORE_ADDR start_ad
     {
       /* If a special version of to_search_memory isn't available, use the
 	 simple version.  */
-      found = simple_search_memory (&current_target,
+      found = simple_search_memory (current_target.beneath,
 				    start_addr, search_space_len,
 				    pattern, pattern_len, found_addrp);
     }
@@ -2541,6 +2620,11 @@ init_dummy_target (void)
   dummy_target.to_find_memory_regions = dummy_find_memory_regions;
   dummy_target.to_make_corefile_notes = dummy_make_corefile_notes;
   dummy_target.to_xfer_partial = default_xfer_partial;
+  dummy_target.to_has_all_memory = (int (*) (struct target_ops *)) return_zero;
+  dummy_target.to_has_memory = (int (*) (struct target_ops *)) return_zero;
+  dummy_target.to_has_stack = (int (*) (struct target_ops *)) return_zero;
+  dummy_target.to_has_registers = (int (*) (struct target_ops *)) return_zero;
+  dummy_target.to_has_execution = (int (*) (struct target_ops *)) return_zero;
   dummy_target.to_magic = OPS_MAGIC;
 }
 
@@ -3264,7 +3348,7 @@ static void
 set_maintenance_target_async_permitted (char *args, int from_tty,
 					struct cmd_list_element *c)
 {
-  if (target_has_execution)
+  if (have_live_inferiors ())
     {
       target_async_permitted_1 = target_async_permitted;
       error (_("Cannot change this setting while the inferior is running."));
Index: src/gdb/breakpoint.c
===================================================================
--- src.orig/gdb/breakpoint.c	2009-06-04 15:04:27.000000000 +0100
+++ src/gdb/breakpoint.c	2009-06-04 15:04:30.000000000 +0100
@@ -1286,12 +1286,10 @@ insert_breakpoints (void)
 
   update_global_location_list (1);
 
-  if (!breakpoints_always_inserted_mode ()
-      && (target_has_execution
- 	  || gdbarch_has_global_breakpoints (target_gdbarch)))
-    /* update_global_location_list does not insert breakpoints
-       when always_inserted_mode is not enabled.  Explicitly
-       insert them now.  */
+  /* update_global_location_list does not insert breakpoints when
+     always_inserted_mode is not enabled.  Explicitly insert them
+     now.  */
+  if (!breakpoints_always_inserted_mode ())
     insert_breakpoint_locations ();
 }
 
@@ -7232,7 +7230,7 @@ update_global_location_list (int should_
     }
 
   if (breakpoints_always_inserted_mode () && should_insert
-      && (target_has_execution
+      && (have_live_inferiors ()
 	  || (gdbarch_has_global_breakpoints (target_gdbarch))))
     insert_breakpoint_locations ();
 
Index: src/gdb/infcmd.c
===================================================================
--- src.orig/gdb/infcmd.c	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/infcmd.c	2009-06-04 15:04:30.000000000 +0100
@@ -2052,9 +2052,9 @@ kill_command (char *arg, int from_tty)
     error (_("Not confirmed."));
   target_kill ();
 
-  /* If the current target interface claims there's still execution,
-     then don't mess with threads of other processes.  */
-  if (!target_has_execution)
+  /* If we still have other inferiors to debug, then don't mess with
+     with their threads.  */
+  if (!have_inferiors ())
     {
       init_thread_list ();		/* Destroy thread info */
 
@@ -2442,9 +2442,9 @@ detach_command (char *args, int from_tty
   if (!gdbarch_has_global_solist (target_gdbarch))
     no_shared_libraries (NULL, from_tty);
 
-  /* If the current target interface claims there's still execution,
-     then don't mess with threads of other processes.  */
-  if (!target_has_execution)
+  /* If we still have inferiors to debug, then don't mess with their
+     threads.  */
+  if (!have_inferiors ())
     init_thread_list ();
 
   if (deprecated_detach_hook)
Index: src/gdb/inferior.c
===================================================================
--- src.orig/gdb/inferior.c	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/inferior.c	2009-06-04 15:04:30.000000000 +0100
@@ -284,6 +284,14 @@ have_inferiors (void)
   return inferior_list != NULL;
 }
 
+int
+have_live_inferiors (void)
+{
+  /* The check on stratum suffices, as GDB doesn't currently support
+     multiple target interfaces.  */
+  return (current_target.to_stratum >= process_stratum && have_inferiors ());
+}
+
 /* Prints the list of inferiors and their details on UIOUT.  This is a
    version of 'info_inferior_command' suitable for use from MI.
 
Index: src/gdb/inferior.h
===================================================================
--- src.orig/gdb/inferior.h	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/inferior.h	2009-06-04 15:04:30.000000000 +0100
@@ -491,6 +491,10 @@ extern void print_inferior (struct ui_ou
 /* Returns true if the inferior list is not empty.  */
 extern int have_inferiors (void);
 
+/* Returns true if there are any live inferiors in the inferior list
+   (not cores, not executables, real live processes).  */
+extern int have_live_inferiors (void);
+
 /* Return a pointer to the current inferior.  It is an error to call
    this if there is no current inferior.  */
 extern struct inferior *current_inferior (void);
Index: src/gdb/infrun.c
===================================================================
--- src.orig/gdb/infrun.c	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/infrun.c	2009-06-04 15:04:30.000000000 +0100
@@ -4437,14 +4437,11 @@ normal_stop (void)
      propagate GDB's knowledge of the executing state to the
      frontend/user running state.  A QUIT is an easy exception to see
      here, so do this before any filtered output.  */
-  if (target_has_execution)
-    {
-      if (!non_stop)
-	make_cleanup (finish_thread_state_cleanup, &minus_one_ptid);
-      else if (last.kind != TARGET_WAITKIND_SIGNALLED
-	       && last.kind != TARGET_WAITKIND_EXITED)
-	make_cleanup (finish_thread_state_cleanup, &inferior_ptid);
-    }
+  if (!non_stop)
+    make_cleanup (finish_thread_state_cleanup, &minus_one_ptid);
+  else if (last.kind != TARGET_WAITKIND_SIGNALLED
+	   && last.kind != TARGET_WAITKIND_EXITED)
+    make_cleanup (finish_thread_state_cleanup, &inferior_ptid);
 
   /* In non-stop mode, we don't want GDB to switch threads behind the
      user's back, to avoid races where the user is typing a command to
Index: src/gdb/thread.c
===================================================================
--- src.orig/gdb/thread.c	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/thread.c	2009-06-04 15:04:30.000000000 +0100
@@ -559,9 +559,6 @@ is_thread_state (ptid_t ptid, enum threa
 {
   struct thread_info *tp;
 
-  if (!target_has_execution)
-    return 0;
-
   tp = find_thread_ptid (ptid);
   gdb_assert (tp);
   return tp->state_ == state;
@@ -570,30 +567,18 @@ is_thread_state (ptid_t ptid, enum threa
 int
 is_stopped (ptid_t ptid)
 {
-  /* Without execution, this property is always true.  */
-  if (!target_has_execution)
-    return 1;
-
   return is_thread_state (ptid, THREAD_STOPPED);
 }
 
 int
 is_exited (ptid_t ptid)
 {
-  /* Without execution, this property is always false.  */
-  if (!target_has_execution)
-    return 0;
-
   return is_thread_state (ptid, THREAD_EXITED);
 }
 
 int
 is_running (ptid_t ptid)
 {
-   /* Without execution, this property is always false.  */
-  if (!target_has_execution)
-    return 0;
-
   return is_thread_state (ptid, THREAD_RUNNING);
 }
 
@@ -602,9 +587,6 @@ any_running (void)
 {
   struct thread_info *tp;
 
-  if (!target_has_execution)
-    return 0;
-
   for (tp = thread_list; tp; tp = tp->next)
     if (tp->state_ == THREAD_RUNNING)
       return 1;
@@ -617,9 +599,6 @@ is_executing (ptid_t ptid)
 {
   struct thread_info *tp;
 
-  if (!target_has_execution)
-    return 0;
-
   tp = find_thread_ptid (ptid);
   gdb_assert (tp);
   return tp->executing_;
Index: src/gdb/top.c
===================================================================
--- src.orig/gdb/top.c	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/top.c	2009-06-04 15:04:30.000000000 +0100
@@ -1222,10 +1222,15 @@ kill_or_detach (struct inferior *inf, vo
   if (thread)
     {
       switch_to_thread (thread->ptid);
-      if (inf->attach_flag)
-	target_detach (qt->args, qt->from_tty);
-      else
-	target_kill ();
+
+      /* Leave core files alone.  */
+      if (target_has_execution)
+	{
+	  if (inf->attach_flag)
+	    target_detach (qt->args, qt->from_tty);
+	  else
+	    target_kill ();
+	}
     }
 
   return 0;
@@ -1239,8 +1244,7 @@ quit_target (void *arg)
   struct qt_args *qt = (struct qt_args *)arg;
 
   /* Kill or detach all inferiors.  */
-  if (target_has_execution)
-    iterate_over_inferiors (kill_or_detach, qt);
+  iterate_over_inferiors (kill_or_detach, qt);
 
   /* Give all pushed targets a chance to do minimal cleanup, and pop
      them all out.  */
Index: src/gdb/corelow.c
===================================================================
--- src.orig/gdb/corelow.c	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/corelow.c	2009-06-04 15:04:30.000000000 +0100
@@ -746,6 +746,24 @@ core_pid_to_str (struct target_ops *ops,
   return buf;
 }
 
+static int
+core_has_memory (struct target_ops *ops)
+{
+  return (core_bfd != NULL);
+}
+
+static int
+core_has_stack (struct target_ops *ops)
+{
+  return (core_bfd != NULL);
+}
+
+static int
+core_has_registers (struct target_ops *ops)
+{
+  return (core_bfd != NULL);
+}
+
 /* Fill in core_ops with its defined operations and properties.  */
 
 static void
@@ -769,9 +787,9 @@ init_core_ops (void)
   core_ops.to_read_description = core_read_description;
   core_ops.to_pid_to_str = core_pid_to_str;
   core_ops.to_stratum = core_stratum;
-  core_ops.to_has_memory = 1;
-  core_ops.to_has_stack = 1;
-  core_ops.to_has_registers = 1;
+  core_ops.to_has_memory = core_has_memory;
+  core_ops.to_has_stack = core_has_stack;
+  core_ops.to_has_registers = core_has_registers;
   core_ops.to_magic = OPS_MAGIC;
 }
 
Index: src/gdb/exec.c
===================================================================
--- src.orig/gdb/exec.c	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/exec.c	2009-06-04 15:04:30.000000000 +0100
@@ -802,6 +802,15 @@ ignore (struct bp_target_info *bp_tgt)
   return 0;
 }
 
+static int
+exec_has_memory (struct target_ops *ops)
+{
+  /* We can provide memory if we have any file/target sections to read
+     from.  */
+  return (current_target_sections->sections
+	  != current_target_sections->sections_end);
+}
+
 /* Find mapped memory. */
 
 extern void
@@ -836,7 +845,7 @@ Specify the filename of the executable f
   exec_ops.to_remove_breakpoint = ignore;
   exec_ops.to_create_inferior = find_default_create_inferior;
   exec_ops.to_stratum = file_stratum;
-  exec_ops.to_has_memory = 1;
+  exec_ops.to_has_memory = exec_has_memory;
   exec_ops.to_make_corefile_notes = exec_make_note_section;
   exec_ops.to_magic = OPS_MAGIC;
 }
Index: src/gdb/remote.c
===================================================================
--- src.orig/gdb/remote.c	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/remote.c	2009-06-04 15:04:30.000000000 +0100
@@ -1179,15 +1179,6 @@ remote_add_inferior (int pid, int attach
 
   inf->attach_flag = attached;
 
-  /* This may be the first inferior we hear about.  */
-  if (!target_has_execution)
-    {
-      if (rs->extended)
-	target_mark_running (&extended_remote_ops);
-      else
-	target_mark_running (&remote_ops);
-    }
-
   return inf;
 }
 
@@ -2688,15 +2679,12 @@ remote_start_remote (struct ui_out *uiou
     {
       if (rs->buf[0] == 'W' || rs->buf[0] == 'X')
 	{
-	  if (args->extended_p)
-	    {
-	      /* We're connected, but not running.  Drop out before we
-		 call start_remote.  */
-	      target_mark_exited (args->target);
-	      return;
-	    }
-	  else
+	  if (!args->extended_p)
 	    error (_("The target is not running (try extended-remote?)"));
+
+	  /* We're connected, but not running.  Drop out before we
+	     call start_remote.  */
+	  return;
 	}
       else
 	{
@@ -2786,19 +2774,13 @@ remote_start_remote (struct ui_out *uiou
 
       if (thread_count () == 0)
 	{
-	  if (args->extended_p)
-	    {
-	      /* We're connected, but not running.  Drop out before we
-		 call start_remote.  */
-	      target_mark_exited (args->target);
-	      return;
-	    }
-	  else
+	  if (!args->extended_p)
 	    error (_("The target is not running (try extended-remote?)"));
-	}
 
-      if (args->extended_p)
-	target_mark_running (args->target);
+	  /* We're connected, but not running.  Drop out before we
+	     call start_remote.  */
+	  return;
+	}
 
       /* Let the stub know that we want it to return the thread.  */
 
@@ -3209,7 +3191,7 @@ remote_open_1 (char *name, int from_tty,
      But if we're connected to a target system with no running process,
      then we will still be connected when it returns.  Ask this question
      first, before target_preopen has a chance to kill anything.  */
-  if (remote_desc != NULL && !target_has_execution)
+  if (remote_desc != NULL && !have_inferiors ())
     {
       if (!from_tty
 	  || query (_("Already connected to a remote target.  Disconnect? ")))
@@ -3227,7 +3209,7 @@ remote_open_1 (char *name, int from_tty,
      process, we may still be connected.  If we are starting "target
      remote" now, the extended-remote target will not have been
      removed by unpush_target.  */
-  if (remote_desc != NULL && !target_has_execution)
+  if (remote_desc != NULL && !have_inferiors ())
     pop_target ();
 
   /* Make sure we send the passed signals list the next time we resume.  */
@@ -3270,10 +3252,6 @@ remote_open_1 (char *name, int from_tty,
     }
   push_target (target);		/* Switch to using remote target now.  */
 
-  /* Assume that the target is not running, until we learn otherwise.  */
-  if (extended_p)
-    target_mark_exited (target);
-
   /* Register extra event sources in the event loop.  */
   remote_async_inferior_event_token
     = create_async_event_handler (remote_async_inferior_event_handler,
@@ -6680,16 +6658,7 @@ extended_remote_mourn_1 (struct target_o
 		 so that the user can say "kill" again.	 */
 	      inferior_ptid = magic_null_ptid;
 	    }
-	  else
-	    {
-	      /* Mark this (still pushed) target as not executable until we
-		 restart it.  */
-	      target_mark_exited (target);
-	    }
 	}
-      else
-	/* Always remove execution if this was the last process.  */
-	target_mark_exited (target);
     }
 }
 
@@ -8803,11 +8772,11 @@ Specify the serial device it is connecte
   remote_ops.to_log_command = serial_log_command;
   remote_ops.to_get_thread_local_address = remote_get_thread_local_address;
   remote_ops.to_stratum = process_stratum;
-  remote_ops.to_has_all_memory = 1;
-  remote_ops.to_has_memory = 1;
-  remote_ops.to_has_stack = 1;
-  remote_ops.to_has_registers = 1;
-  remote_ops.to_has_execution = 1;
+  remote_ops.to_has_all_memory = default_child_has_all_memory;
+  remote_ops.to_has_memory = default_child_has_memory;
+  remote_ops.to_has_stack = default_child_has_stack;
+  remote_ops.to_has_registers = default_child_has_registers;
+  remote_ops.to_has_execution = default_child_has_execution;
   remote_ops.to_has_thread_control = tc_schedlock;	/* can lock scheduler */
   remote_ops.to_can_execute_reverse = remote_can_execute_reverse;
   remote_ops.to_magic = OPS_MAGIC;
Index: src/gdb/bsd-kvm.c
===================================================================
--- src.orig/gdb/bsd-kvm.c	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/bsd-kvm.c	2009-06-04 15:04:30.000000000 +0100
@@ -325,6 +325,12 @@ bsd_kvm_pid_to_str (struct target_ops *o
   return buf;
 }
 
+static int
+bsd_kvm_return_one (struct target_ops *ops)
+{
+  return 1;
+}
+
 /* Add the libkvm interface to the list of all possible targets and
    register CUPPLY_PCB as the architecture-specific process control
    block interpreter.  */
@@ -347,9 +353,9 @@ Optionally specify the filename of a cor
   bsd_kvm_ops.to_thread_alive = bsd_kvm_thread_alive;
   bsd_kvm_ops.to_pid_to_str = bsd_kvm_pid_to_str;
   bsd_kvm_ops.to_stratum = process_stratum;
-  bsd_kvm_ops.to_has_memory = 1;
-  bsd_kvm_ops.to_has_stack = 1;
-  bsd_kvm_ops.to_has_registers = 1;
+  bsd_kvm_ops.to_has_memory = bsd_kvm_return_one;
+  bsd_kvm_ops.to_has_stack = bsd_kvm_return_one;
+  bsd_kvm_ops.to_has_registers = bsd_kvm_return_one;
   bsd_kvm_ops.to_magic = OPS_MAGIC;
 
   add_target (&bsd_kvm_ops);
Index: src/gdb/gnu-nat.c
===================================================================
--- src.orig/gdb/gnu-nat.c	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/gnu-nat.c	2009-06-04 15:04:30.000000000 +0100
@@ -2654,11 +2654,11 @@ init_gnu_ops (void)
   gnu_ops.to_pid_to_str = gnu_pid_to_str;   /* to_pid_to_str */
   gnu_ops.to_stop = gnu_stop;	/* to_stop */
   gnu_ops.to_stratum = process_stratum;		/* to_stratum */
-  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_has_all_memory = default_child_has_all_memory;
+  gnu_ops.to_has_memory = default_child_has_memory;
+  gnu_ops.to_has_stack = default_child_has_stack;
+  gnu_ops.to_has_registers = default_child_has_registers;
+  gnu_ops.to_has_execution = default_child_has_execution;
   gnu_ops.to_magic = OPS_MAGIC;		/* to_magic */
 }				/* init_gnu_ops */
 
Index: src/gdb/go32-nat.c
===================================================================
--- src.orig/gdb/go32-nat.c	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/go32-nat.c	2009-06-04 15:04:30.000000000 +0100
@@ -968,11 +968,11 @@ init_go32_ops (void)
   go32_ops.to_thread_alive = go32_thread_alive;
   go32_ops.to_pid_to_str = go32_pid_to_str;
   go32_ops.to_stratum = process_stratum;
-  go32_ops.to_has_all_memory = 1;
-  go32_ops.to_has_memory = 1;
-  go32_ops.to_has_stack = 1;
-  go32_ops.to_has_registers = 1;
-  go32_ops.to_has_execution = 1;
+  go32_ops.to_has_all_memory = default_child_has_all_memory;
+  go32_ops.to_has_memory = default_child_has_memory;
+  go32_ops.to_has_stack = default_child_has_stack;
+  go32_ops.to_has_registers = default_child_has_registers;
+  go32_ops.to_has_execution = default_child_has_execution;
 
   i386_use_watchpoints (&go32_ops);
 
Index: src/gdb/hpux-thread.c
===================================================================
--- src.orig/gdb/hpux-thread.c	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/hpux-thread.c	2009-06-04 15:04:30.000000000 +0100
@@ -565,11 +565,11 @@ init_hpux_thread_ops (void)
   hpux_thread_ops.to_thread_alive = hpux_thread_alive;
   hpux_thread_ops.to_stop = hpux_thread_stop;
   hpux_thread_ops.to_stratum = process_stratum;
-  hpux_thread_ops.to_has_all_memory = 1;
-  hpux_thread_ops.to_has_memory = 1;
-  hpux_thread_ops.to_has_stack = 1;
-  hpux_thread_ops.to_has_registers = 1;
-  hpux_thread_ops.to_has_execution = 1;
+  hpux_thread_ops.to_has_all_memory = default_child_has_all_memory;
+  hpux_thread_ops.to_has_memory = default_child_has_memory;
+  hpux_thread_ops.to_has_stack = default_child_has_stack;
+  hpux_thread_ops.to_has_registers = default_child_has_registers;
+  hpux_thread_ops.to_has_execution = default_child_has_execution;
   hpux_thread_ops.to_magic = OPS_MAGIC;
 }
 
Index: src/gdb/monitor.c
===================================================================
--- src.orig/gdb/monitor.c	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/monitor.c	2009-06-04 15:04:30.000000000 +0100
@@ -2289,11 +2289,11 @@ init_base_monitor_ops (void)
   monitor_ops.to_thread_alive = monitor_thread_alive;
   monitor_ops.to_pid_to_str = monitor_pid_to_str;
   monitor_ops.to_stratum = process_stratum;
-  monitor_ops.to_has_all_memory = 1;
-  monitor_ops.to_has_memory = 1;
-  monitor_ops.to_has_stack = 1;
-  monitor_ops.to_has_registers = 1;
-  monitor_ops.to_has_execution = 1;
+  monitor_ops.to_has_all_memory = default_child_has_all_memory;
+  monitor_ops.to_has_memory = default_child_has_memory;
+  monitor_ops.to_has_stack = default_child_has_stack;
+  monitor_ops.to_has_registers = default_child_has_registers;
+  monitor_ops.to_has_execution = default_child_has_execution;
   monitor_ops.to_magic = OPS_MAGIC;
 }				/* init_base_monitor_ops */
 
Index: src/gdb/nto-procfs.c
===================================================================
--- src.orig/gdb/nto-procfs.c	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/nto-procfs.c	2009-06-04 15:04:30.000000000 +0100
@@ -1327,11 +1327,11 @@ init_procfs_ops (void)
   procfs_ops.to_pid_to_str = procfs_pid_to_str;
   procfs_ops.to_stop = procfs_stop;
   procfs_ops.to_stratum = process_stratum;
-  procfs_ops.to_has_all_memory = 1;
-  procfs_ops.to_has_memory = 1;
-  procfs_ops.to_has_stack = 1;
-  procfs_ops.to_has_registers = 1;
-  procfs_ops.to_has_execution = 1;
+  procfs_ops.to_has_all_memory = default_child_has_all_memory;
+  procfs_ops.to_has_memory = default_child_has_memory;
+  procfs_ops.to_has_stack = default_child_has_stack;
+  procfs_ops.to_has_registers = default_child_has_registers;
+  procfs_ops.to_has_execution = default_child_has_execution;
   procfs_ops.to_magic = OPS_MAGIC;
   procfs_ops.to_have_continuable_watchpoint = 1;
 }
Index: src/gdb/remote-m32r-sdi.c
===================================================================
--- src.orig/gdb/remote-m32r-sdi.c	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/remote-m32r-sdi.c	2009-06-04 15:04:30.000000000 +0100
@@ -1590,6 +1590,11 @@ use_dbt_breakpoints_command (char *args,
   use_ib_breakpoints = 0;
 }
 
+static int
+m32r_return_one (struct target_ops *target)
+{
+  return 1;
+}
 
 /* Define the target subroutine names */
 
@@ -1627,11 +1632,11 @@ init_m32r_ops (void)
   m32r_ops.to_thread_alive = m32r_thread_alive;
   m32r_ops.to_pid_to_str = m32r_pid_to_str;
   m32r_ops.to_stratum = process_stratum;
-  m32r_ops.to_has_all_memory = 1;
-  m32r_ops.to_has_memory = 1;
-  m32r_ops.to_has_stack = 1;
-  m32r_ops.to_has_registers = 1;
-  m32r_ops.to_has_execution = 1;
+  m32r_ops.to_has_all_memory = m32r_return_one;
+  m32r_ops.to_has_memory = m32r_return_one;
+  m32r_ops.to_has_stack = m32r_return_one;
+  m32r_ops.to_has_registers = m32r_return_one;
+  m32r_ops.to_has_execution = m32r_return_one;
   m32r_ops.to_magic = OPS_MAGIC;
 };
 
Index: src/gdb/remote-mips.c
===================================================================
--- src.orig/gdb/remote-mips.c	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/remote-mips.c	2009-06-04 15:04:30.000000000 +0100
@@ -3340,11 +3340,11 @@ _initialize_remote_mips (void)
   mips_ops.to_mourn_inferior = mips_mourn_inferior;
   mips_ops.to_log_command = serial_log_command;
   mips_ops.to_stratum = process_stratum;
-  mips_ops.to_has_all_memory = 1;
-  mips_ops.to_has_memory = 1;
-  mips_ops.to_has_stack = 1;
-  mips_ops.to_has_registers = 1;
-  mips_ops.to_has_execution = 1;
+  mips_ops.to_has_all_memory = default_child_has_all_memory;
+  mips_ops.to_has_memory = default_child_has_memory;
+  mips_ops.to_has_stack = default_child_has_stack;
+  mips_ops.to_has_registers = default_child_has_registers;
+  mips_ops.to_has_execution = default_child_has_execution;
   mips_ops.to_magic = OPS_MAGIC;
 
   /* Copy the common fields to all four target vectors.  */
Index: src/gdb/remote-sim.c
===================================================================
--- src.orig/gdb/remote-sim.c	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/remote-sim.c	2009-06-04 15:04:30.000000000 +0100
@@ -474,7 +474,6 @@ gdbsim_create_inferior (struct target_op
   add_inferior_silent (ptid_get_pid (inferior_ptid));
   add_thread_silent (inferior_ptid);
 
-  target_mark_running (&gdbsim_ops);
   insert_breakpoints ();	/* Needed to get correct instruction in cache */
 
   clear_proceed_status ();
@@ -552,7 +551,6 @@ gdbsim_open (char *args, int from_tty)
   /* There's nothing running after "target sim" or "load"; not until
      "run".  */
   inferior_ptid = null_ptid;
-  target_mark_exited (&gdbsim_ops);
 }
 
 /* Does whatever cleanup is required for a target that we are no longer
@@ -820,7 +818,6 @@ gdbsim_mourn_inferior (struct target_ops
     printf_filtered ("gdbsim_mourn_inferior:\n");
 
   remove_breakpoints ();
-  target_mark_exited (target);
   generic_mourn_inferior ();
   delete_thread_silent (remote_sim_ptid);
 }
@@ -913,11 +910,11 @@ init_gdbsim_ops (void)
   gdbsim_ops.to_thread_alive = gdbsim_thread_alive;
   gdbsim_ops.to_pid_to_str = gdbsim_pid_to_str;
   gdbsim_ops.to_stratum = process_stratum;
-  gdbsim_ops.to_has_all_memory = 1;
-  gdbsim_ops.to_has_memory = 1;
-  gdbsim_ops.to_has_stack = 1;
-  gdbsim_ops.to_has_registers = 1;
-  gdbsim_ops.to_has_execution = 1;
+  gdbsim_ops.to_has_all_memory = default_child_has_all_memory;
+  gdbsim_ops.to_has_memory = default_child_has_memory;
+  gdbsim_ops.to_has_stack = default_child_has_stack;
+  gdbsim_ops.to_has_registers = default_child_has_registers;
+  gdbsim_ops.to_has_execution = default_child_has_execution;
   gdbsim_ops.to_magic = OPS_MAGIC;
 }
 
Index: src/gdb/windows-nat.c
===================================================================
--- src.orig/gdb/windows-nat.c	2009-06-04 15:04:28.000000000 +0100
+++ src/gdb/windows-nat.c	2009-06-04 15:04:30.000000000 +0100
@@ -2164,11 +2164,11 @@ init_windows_ops (void)
   windows_ops.to_pid_to_str = windows_pid_to_str;
   windows_ops.to_stop = windows_stop;
   windows_ops.to_stratum = process_stratum;
-  windows_ops.to_has_all_memory = 1;
-  windows_ops.to_has_memory = 1;
-  windows_ops.to_has_stack = 1;
-  windows_ops.to_has_registers = 1;
-  windows_ops.to_has_execution = 1;
+  windows_ops.to_has_all_memory = default_child_has_all_memory;
+  windows_ops.to_has_memory = default_child_has_memory;
+  windows_ops.to_has_stack = default_child_has_stack;
+  windows_ops.to_has_registers = default_child_has_registers;
+  windows_ops.to_has_execution = default_child_has_execution;
   windows_ops.to_pid_to_exec_file = windows_pid_to_exec_file;
   windows_ops.to_get_ada_task_ptid = windows_get_ada_task_ptid;
 
Index: src/gdb/linux-nat.c
===================================================================
--- src.orig/gdb/linux-nat.c	2009-06-04 15:45:26.000000000 +0100
+++ src/gdb/linux-nat.c	2009-06-04 15:46:30.000000000 +0100
@@ -3290,6 +3290,11 @@ linux_nat_xfer_partial (struct target_op
     return linux_xfer_siginfo (ops, object, annex, readbuf, writebuf,
 			       offset, len);
 
+  /* The target is connected but not running, we should pass this
+     request down to a lower stratum (e.g., the executable file).  */
+  if (object == TARGET_OBJECT_MEMORY && ptid_equal (inferior_ptid, null_ptid))
+    return 0;
+
   old_chain = save_inferior_ptid ();
 
   if (is_lwp (inferior_ptid))


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]