gdb/server/
authorPedro Alves <palves@redhat.com>
Mon, 7 Feb 2011 12:14:14 +0000 (12:14 +0000)
committerPedro Alves <palves@redhat.com>
Mon, 7 Feb 2011 12:14:14 +0000 (12:14 +0000)
* server.c (gdb_read_memory): Change return semantics to allow
partial transfers.
(handle_search_memory_1): Adjust.
(process_serial_event) <'m' packet>: Handle partial transfers.
* tracepoint.c (traceframe_read_mem): Handle partial transfers.

gdb/testsuite/
* gdb.trace/collection.c (global_pieces): New.
* gdb.trace/collection.exp (gdb_collect_global_in_pieces_test):
New procedure.
(gdb_trace_collection_test): Call it.

gdb/gdbserver/ChangeLog
gdb/gdbserver/server.c
gdb/gdbserver/tracepoint.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.trace/collection.c
gdb/testsuite/gdb.trace/collection.exp

index 79ed9096e4114bcebef70febdc97670838b784a7..a93ca7904bb78f4a8575d5cf146f9844f7968e13 100644 (file)
@@ -1,3 +1,11 @@
+2011-02-07  Pedro Alves  <pedro@codesourcery.com>
+
+       * server.c (gdb_read_memory): Change return semantics to allow
+       partial transfers.
+       (handle_search_memory_1): Adjust.
+       (process_serial_event) <'m' packet>: Handle partial transfers.
+       * tracepoint.c (traceframe_read_mem): Handle partial transfers.
+
 2011-01-28  Pedro Alves  <pedro@codesourcery.com>
 
        * regcache.c (init_register_cache): Initialize
index a170d85283e0632d6b15d703b4f86044cfefa1a0..9e1973929029d5bb955225cb1b547a128e8eae3f 100644 (file)
@@ -556,12 +556,20 @@ monitor_show_help (void)
   monitor_output ("    Quit GDBserver\n");
 }
 
-/* Read trace frame or inferior memory.  */
+/* Read trace frame or inferior memory.  Returns the number of bytes
+   actually read, zero when no further transfer is possible, and -1 on
+   error.  Return of a positive value smaller than LEN does not
+   indicate there's no more to be read, only the end of the transfer.
+   E.g., when GDB reads memory from a traceframe, a first request may
+   be served from a memory block that does not cover the whole request
+   length.  A following request gets the rest served from either
+   another block (of the same traceframe) or from the read-only
+   regions.  */
 
 static int
 gdb_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
 {
-  int ret;
+  int res;
 
   if (current_traceframe >= 0)
     {
@@ -572,22 +580,24 @@ gdb_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
                               memaddr, myaddr, len, &nbytes))
        return EIO;
       /* Data read from trace buffer, we're done.  */
-      if (nbytes == length)
-       return 0;
+      if (nbytes > 0)
+       return nbytes;
       if (!in_readonly_region (memaddr, length))
-       return EIO;
+       return -1;
       /* Otherwise we have a valid readonly case, fall through.  */
       /* (assume no half-trace half-real blocks for now) */
     }
 
-  ret = prepare_to_access_memory ();
-  if (ret == 0)
+  res = prepare_to_access_memory ();
+  if (res == 0)
     {
-      ret = read_inferior_memory (memaddr, myaddr, len);
+      res = read_inferior_memory (memaddr, myaddr, len);
       done_accessing_memory ();
-    }
 
-  return ret;
+      return res == 0 ? len : -1;
+    }
+  else
+    return -1;
 }
 
 /* Write trace frame or inferior memory.  Actually, writing to trace
@@ -623,7 +633,8 @@ handle_search_memory_1 (CORE_ADDR start_addr, CORE_ADDR search_space_len,
 {
   /* Prime the search buffer.  */
 
-  if (gdb_read_memory (start_addr, search_buf, search_buf_size) != 0)
+  if (gdb_read_memory (start_addr, search_buf, search_buf_size)
+      != search_buf_size)
     {
       warning ("Unable to access target memory at 0x%lx, halting search.",
               (long) start_addr);
@@ -675,7 +686,7 @@ handle_search_memory_1 (CORE_ADDR start_addr, CORE_ADDR search_space_len,
                        : chunk_size);
 
          if (gdb_read_memory (read_addr, search_buf + keep_len,
-                              nr_to_read) != 0)
+                              nr_to_read) != search_buf_size)
            {
              warning ("Unable to access target memory "
                       "at 0x%lx, halting search.",
@@ -2664,6 +2675,7 @@ process_serial_event (void)
   int i = 0;
   int signal;
   unsigned int len;
+  int res;
   CORE_ADDR mem_addr;
   int pid;
   unsigned char sig;
@@ -2902,10 +2914,11 @@ process_serial_event (void)
     case 'm':
       require_running (own_buf);
       decode_m_packet (&own_buf[1], &mem_addr, &len);
-      if (gdb_read_memory (mem_addr, mem_buf, len) == 0)
-       convert_int_to_ascii (mem_buf, own_buf, len);
-      else
+      res = gdb_read_memory (mem_addr, mem_buf, len);
+      if (res < 0)
        write_enn (own_buf);
+      else
+       convert_int_to_ascii (mem_buf, own_buf, res);
       break;
     case 'M':
       require_running (own_buf);
index 2da57edb9977e901970a1aeaf2c7c7ff311fc522..c5b3f5612653e4f47bd7824d081a99b86c0efc6d 100644 (file)
@@ -4909,12 +4909,17 @@ traceframe_read_mem (int tfnum, CORE_ADDR addr,
       trace_debug ("traceframe %d has %d bytes at %s",
                   tfnum, mlen, paddress (maddr));
 
-      /* Check that requested data is in bounds.  */
-      if (maddr <= addr && (addr + length) <= (maddr + mlen))
+      /* If the block includes the first part of the desired range,
+        return as much it has; GDB will re-request the remainder,
+        which might be in a different block of this trace frame.  */
+      if (maddr <= addr && addr < (maddr + mlen))
        {
-         /* Block includes the requested range, copy it out.  */
-         memcpy (buf, dataptr + (addr - maddr), length);
-         *nbytes = length;
+         ULONGEST amt = (maddr + mlen) - addr;
+         if (amt > length)
+           amt = length;
+
+         memcpy (buf, dataptr + (addr - maddr), amt);
+         *nbytes = amt;
          return 0;
        }
 
index 1fc2c7c56e046791097c833d6625641a91f56780..f59a4cede5a36e7edc7ec95e367b0f5c64c451b9 100644 (file)
@@ -1,3 +1,10 @@
+2011-02-07  Pedro Alves  <pedro@codesourcery.com>
+
+       * gdb.trace/collection.c (global_pieces): New.
+       * gdb.trace/collection.exp (gdb_collect_global_in_pieces_test):
+       New procedure.
+       (gdb_trace_collection_test): Call it.
+
 2011-02-04  Sami Wagiaalla  <swagiaal@redhat.com>
 
        * gdb.python/py-evthreads.c: New file.
index 6fb71338a402b5ef695aef0347fbee09e1a5e584..4a58170be1af6b4cbb7935af2bc681266836ce6a 100644 (file)
@@ -27,6 +27,14 @@ test_struct  globalstruct;
 test_struct *globalp;
 int          globalarr[16];
 
+struct global_pieces {
+  unsigned int a;
+  unsigned int b;
+} global_pieces =
+  {
+    0x12345678, 0x87654321
+  };
+
 /*
  * Additional globals used in arithmetic tests
  */
index 71ad38c0496877c197bd49ddc287f8a481c45460..4e0a30d4902b0f5cf11a70056abbb630b96050c4 100644 (file)
@@ -513,6 +513,50 @@ proc gdb_collect_globals_test { } {
            "collect globals: cease trace debugging"
 }
 
+# Test that when we've collected all fields of a structure
+# individually, we can print the whole structure in one go.
+proc gdb_collect_global_in_pieces_test { } {
+    global gdb_prompt
+
+    prepare_for_trace_test
+
+    # Find the comment-identified line for setting this tracepoint.
+    set testline 0
+    set msg "collect global in pieces: find tracepoint line"
+    gdb_test_multiple "list globals_test_func, +30" "$msg" {
+       -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+ Set_Tracepoint_Here .*$gdb_prompt" {
+           set testline $expect_out(1,string)
+           pass "$msg"
+       }
+    }
+
+    if {$testline == 0} {
+       return
+    }
+
+    gdb_test "trace $testline" \
+       "Tracepoint \[0-9\]+ at .*" \
+       "collect global in pieces: set tracepoint"
+    gdb_trace_setactions "collect global in pieces: define actions" \
+           "" \
+           "collect global_pieces.a, global_pieces.b" \
+           "^$"
+
+    # Begin the test.
+    run_trace_experiment "global in pieces" globals_test_func
+
+    gdb_test "print /x global_pieces.a" " = 0x12345678" \
+       "collect global in pieces: print piece a"
+    gdb_test "print /x global_pieces.b" " = 0x87654321" \
+       "collect global in pieces: print piece b"
+
+    gdb_test "print /x global_pieces" " = \{a = 0x12345678, b = 0x87654321\}" \
+       "collect global in pieces: print whole object"
+
+    gdb_test "tfind none" "#0  end .*" \
+       "collect global in pieces: cease trace debugging"
+}
+
 proc gdb_trace_collection_test {} {
     global fpreg
     global spreg
@@ -548,6 +592,7 @@ proc gdb_trace_collection_test {} {
     gdb_collect_registers_test "\$regs"
     gdb_collect_registers_test "\$$fpreg, \$$spreg, \$$pcreg"
     gdb_collect_globals_test
+    gdb_collect_global_in_pieces_test
     
     #
     # Expression tests: