From: Pedro Alves Date: Mon, 7 Feb 2011 12:14:14 +0000 (+0000) Subject: gdb/server/ X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=764880b7edb584d2e037474a40fd06f17e6c5fd5;p=binutils-gdb.git gdb/server/ * 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. --- diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 79ed9096e41..a93ca7904bb 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,11 @@ +2011-02-07 Pedro Alves + + * 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 * regcache.c (init_register_cache): Initialize diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index a170d85283e..9e197392902 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -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); diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c index 2da57edb997..c5b3f561265 100644 --- a/gdb/gdbserver/tracepoint.c +++ b/gdb/gdbserver/tracepoint.c @@ -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; } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 1fc2c7c56e0..f59a4cede5a 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2011-02-07 Pedro Alves + + * 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 * gdb.python/py-evthreads.c: New file. diff --git a/gdb/testsuite/gdb.trace/collection.c b/gdb/testsuite/gdb.trace/collection.c index 6fb71338a40..4a58170be1a 100644 --- a/gdb/testsuite/gdb.trace/collection.c +++ b/gdb/testsuite/gdb.trace/collection.c @@ -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 */ diff --git a/gdb/testsuite/gdb.trace/collection.exp b/gdb/testsuite/gdb.trace/collection.exp index 71ad38c0496..4e0a30d4902 100644 --- a/gdb/testsuite/gdb.trace/collection.exp +++ b/gdb/testsuite/gdb.trace/collection.exp @@ -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: