Bug 24751 - doc: Can 'm' return partial read?
Summary: doc: Can 'm' return partial read?
Status: NEW
Alias: None
Product: gdb
Classification: Unclassified
Component: server (show other bugs)
Version: HEAD
: P2 minor
Target Milestone: ---
Assignee: Pedro Alves
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-07-01 12:21 UTC by Jan Kratochvil
Modified: 2024-03-15 11:58 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jan Kratochvil 2019-07-01 12:21:26 UTC
GDB documentation
  https://sourceware.org/gdb/current/onlinedocs/gdb/Packets.html#Packets
says for the 'm' packet:
  "The reply may contain fewer addressable memory units than requested if the server was able to read only part of the region of memory."
GNU gdbserver gdb_read_memory() does return only full length or error, contrary what the documentation says:
  res = read_inferior_memory (memaddr, myaddr, len);
  return res == 0 ? len : -1;
So is documentation right or gdbserver right?
Then there is "may" which permits interpretation both ways but I do not find that kind of documentation useful.
Comment 1 Baris Aktemur 2024-03-14 12:32:10 UTC
The `gdb_read_memory` function's comment reads

```
/* 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.  */
```

The code that's about the traceframe is

```
      if (traceframe_read_mem (cs.current_traceframe,
                               memaddr, myaddr, len, &nbytes))
        return -1;
      /* Data read from trace buffer, we're done.  */
      if (nbytes > 0)
        return nbytes;
```

I checked the code of `traceframe_read_mem`.  It may indeed return a partial result, indicated in `nbytes` above.

Based on these, the function comment and the documentation seem mostly accurate to me.  If the documentation is updated as follows, would it be better?

"The reply may contain fewer addressable memory units than requested if the server read from a traceframe and was able to read only part of the region of memory."
Comment 2 Pavel Labath 2024-03-15 11:58:06 UTC
I think the existing documentation is pretty clear -- if that is indeed what it's trying to say. Our confusion was coming from the fact that this does not match existing gdbserver behavior (note that there is no mapping for 0x555555561000 in this example):

(gdb) maintenance packet m555555560ff0,10
sending: m555555560ff0,10
received: "00000000000000000000000000000000"
(gdb) maintenance packet m555555560ff0,11
sending: m555555560ff0,11
received: "E01"

The gdbserver is not necessarily wrong here (the documentations says it "may" return fewer bytes), but:
- gdbserver is kind of the reference implementation for the protocol, and iirc we filed this bug when we were looking at whether lldb's implementation is compatible with that
- This behavior does not seem particularly useful, because it makes it hard for the client to read everything up to the end of addressable memory (upon getting an error, it would have to do a binary search or something to make sure it really got everything).

So if the "specification" really does allow the server to return partial data, then I think the question becomes: "Why doesn't gdbserver do that"?