diff options
| -rw-r--r-- | gdb/NEWS | 5 | ||||
| -rw-r--r-- | gdb/doc/gdb.texinfo | 15 | ||||
| -rw-r--r-- | gdb/testsuite/gdb.server/fileio-packets.exp | 6 | ||||
| -rw-r--r-- | gdb/testsuite/gdb.server/fileio-packets.py | 41 | ||||
| -rw-r--r-- | gdbserver/hostio.cc | 2 |
5 files changed, 61 insertions, 8 deletions
@@ -195,6 +195,11 @@ qXfer:threads:read should print as the target ID of the thread, for example in the "info threads" command or when switching to the thread. +vFile:stat + Previously, gdbserver incorrectly implemented this packet using + lstat rather than stat. This has now been corrected. The + documentation has also been clarified. + * MI changes ** The =library-unloaded event now includes the 'ranges' field, which diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index a564307..6139bc3 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -46730,12 +46730,16 @@ If an error occurs the return value is -1. The format of the returned binary attachment is as described in @ref{struct stat}. @item vFile:stat: @var{filename} -Get information about the file @var{filename} on the target. -On success the information is returned as a binary attachment -and the return value is the size of this attachment in bytes. -If an error occurs the return value is -1. The format of the +Get information about the file @var{filename} on the target as if from +a @samp{stat} call. On success the information is returned as a binary +attachment and the return value is the size of this attachment in +bytes. If an error occurs the return value is -1. The format of the returned binary attachment is as described in @ref{struct stat}. +If @var{filename} is a symbolic link, then the information returned is +about the file the link refers to, this is inline with the @samp{stat} +library call. + @item vFile:lstat: @var{filename} Get information about the file @var{filename} on the target as if from an @samp{lstat} call. On success the information is returned as a @@ -46743,7 +46747,8 @@ binary attachment and the return value is the size of this attachment in bytes. If an error occurs the return value is -1. The format of the returned binary attachment is as described in @ref{struct stat}. -If @var{filename} is a symbolic link, then this packet returns +This packet is identical to @samp{vFile:stat}, except if +@var{filename} is a symbolic link, then this packet returns information about the link itself, not the file that the link refers to, this is inline with the @samp{lstat} library call. diff --git a/gdb/testsuite/gdb.server/fileio-packets.exp b/gdb/testsuite/gdb.server/fileio-packets.exp index d243e93..9435efd 100644 --- a/gdb/testsuite/gdb.server/fileio-packets.exp +++ b/gdb/testsuite/gdb.server/fileio-packets.exp @@ -58,3 +58,9 @@ gdb_test "python check_lstat(\"$test_file_1\")" "PASS" \ gdb_test "python check_lstat(\"$test_file_2\")" "PASS" \ "check remote lstat works on a symbolic link" + +gdb_test "python check_stat(\"$test_file_1\")" "PASS" \ + "check remote stat works on a normal file" + +gdb_test "python check_stat(\"$test_file_2\")" "PASS" \ + "check remote stat works on a symbolic link" diff --git a/gdb/testsuite/gdb.server/fileio-packets.py b/gdb/testsuite/gdb.server/fileio-packets.py index 53fb49e..293ae7e 100644 --- a/gdb/testsuite/gdb.server/fileio-packets.py +++ b/gdb/testsuite/gdb.server/fileio-packets.py @@ -114,6 +114,20 @@ def remote_lstat(filename): return stat +# Perform a stat of remote file FILENAME, and create a dictionary of +# the results, the keys are the fields of the stat structure. +def remote_stat(filename): + conn = gdb.selected_inferior().connection + if not isinstance(conn, gdb.RemoteTargetConnection): + raise gdb.GdbError("connection is the wrong type") + + filename_hex = hex_encode(filename) + reply = conn.send_packet("vFile:stat:%s" % filename_hex) + + stat = decode_stat_reply(reply) + return stat + + # Convert a stat_result object to a dictionary that should match the # dictionary built from the remote protocol reply. def stat_result_to_dict(res): @@ -154,6 +168,13 @@ def local_lstat(filename): return stat_result_to_dict(res) +# Perform an lstat of local file FILENAME, and create a dictionary of +# the results, the keys are the fields of the stat structure. +def local_stat(filename): + res = os.stat(filename) + return stat_result_to_dict(res) + + # Perform a remote lstat using GDB, and a local lstat using os.lstat. # Compare the results to check they are the same. # @@ -163,8 +184,24 @@ def check_lstat(filename): s1 = remote_lstat(filename) s2 = local_lstat(filename) - print(f"s1 = {s1}") - print(f"s2 = {s2}") + print(f"remote = {s1}") + print(f"local = {s2}") + + assert s1 == s2 + print("PASS") + + +# Perform a remote stat using GDB, and a local stat using os.stat. +# Compare the results to check they are the same. +# +# For this test to work correctly, gdbserver, and GDB (where this +# Python script is running), must see the same filesystem. +def check_stat(filename): + s1 = remote_stat(filename) + s2 = local_stat(filename) + + print(f"remote = {s1}") + print(f"local = {s2}") assert s1 == s2 print("PASS") diff --git a/gdbserver/hostio.cc b/gdbserver/hostio.cc index 05f2c4e..8b4d74d 100644 --- a/gdbserver/hostio.cc +++ b/gdbserver/hostio.cc @@ -504,7 +504,7 @@ handle_stat (char *own_buf, int *new_packet_len) return; } - if (lstat (filename, &st) == -1) + if (stat (filename, &st) == -1) { hostio_error (own_buf); return; |
