bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: core file writing


From: Roland McGrath
Subject: Re: core file writing
Date: Wed, 6 Mar 2002 23:20:21 -0500 (EST)

Can you put this into gdb and test it if you get a chance?  I'm CC'ing to
bug-hurd, in hopes that someone else might test this out and follow up
either with fixes or confirmation that it works.  I'm not quite sure if
gdb's "gcore" will be happy doing just the memory part when there is no
make_corefile_notes hook; if not, we could hack in a no-op hook for testing
purposes.  

I would also like your input on what the note segments ought to look like
in Hurd ELF core files.  With the new gcore target stuff in gdb 5.2, we can
work out the format details and the reading and writing code all in gdb first.
Then once we're satisfied with it, we can modify that code to go into the
crash server.



2002-03-06  Roland McGrath  <roland@frob.com>

        * gnu-nat.c (gnu_find_memory_regions): New function.
        (init_gnu_ops): Set `to_find_memory_regions' hook to that.

Index: gnu-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/gnu-nat.c,v
retrieving revision 1.18
diff -p -b -u -r1.18 gnu-nat.c
--- gnu-nat.c   2002/01/06 19:18:28     1.18
+++ gnu-nat.c   2002/03/07 04:12:30
@@ -2467,6 +2467,86 @@ gnu_xfer_memory (CORE_ADDR memaddr, char
     }
 }
 
+/* Call FUNC on each memory region in the task.  */
+static int
+gnu_find_memory_regions (int (*func) (CORE_ADDR,
+                                     unsigned long,
+                                     int, int, int,
+                                     void *),
+                          void *data)
+{
+  error_t err;
+  task_t task;
+  vm_address_t region_address, last_region_address, last_region_end;
+  vm_prot_t last_protection;
+
+  if (current_inferior == 0 || current_inferior->task == 0)
+    return 0;
+  task = current_inferior->task->port;
+  if (task == MACH_PORT_NULL)
+    return 0;
+
+  region_address = last_region_address = last_region_end = VM_MIN_ADDRESS;
+  last_protection = VM_PROT_NONE;
+  while (region_address < VM_MAX_ADDRESS)
+    {
+      vm_prot_t protection;
+      vm_prot_t max_protection;
+      vm_inherit_t inheritance;
+      boolean_t shared;
+      mach_port_t object_name;
+      vm_offset_t offset;
+      vm_size_t region_length = VM_MAX_ADDRESS - region_address;
+      vm_address_t old_address = region_address;
+
+      err = vm_region (task,
+                      &region_address,
+                      &region_length,
+                      &protection,
+                      &max_protection,
+                      &inheritance,
+                      &shared,
+                      &object_name,
+                      &offset);
+      if (err == KERN_NO_SPACE)
+       break;
+      if (err != KERN_SUCCESS)
+       {
+         warning ("vm_region failed: %s", mach_error_string (err));
+         return -1;
+       }
+
+      if (protection == last_protection && region_address == last_region_end)
+       /* This region is contiguous with and indistinguishable from
+          the previous one, so we just extend that one.  */
+       last_region_end = region_address += region_length;
+      else
+       {
+         /* This region is distinct from the last one we saw, so report
+            that previous one.  */
+         if (last_protection != VM_PROT_NONE)
+           (*func) (last_region_address,
+                    last_region_end - last_region_address,
+                    last_protection & VM_PROT_READ,
+                    last_protection & VM_PROT_WRITE,
+                    last_protection & VM_PROT_EXECUTE,
+                    data);
+         last_region_address = region_address;
+         last_region_end = region_address += region_length;
+         last_protection = protection;
+       }
+    }
+
+  /* Report the final region.  */
+  if (last_region_end > last_region_address && last_protection != VM_PROT_NONE)
+    (*func) (last_region_address, last_region_end - last_region_address,
+            last_protection & VM_PROT_READ,
+            last_protection & VM_PROT_WRITE,
+            last_protection & VM_PROT_EXECUTE,
+            data);
+
+  return 0;
+}
 
 /* Return printable description of proc.  */
 char *
@@ -2524,6 +2604,7 @@ init_gnu_ops (void)
   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_find_memory_regions = gnu_find_memory_regions;
   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;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]