aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Arnez <arnez@linux.vnet.ibm.com>2014-12-12 14:14:20 +0100
committerAndreas Krebbel <krebbel@linux.vnet.ibm.com>2014-12-12 14:15:07 +0100
commit098dbe61246fd65ea5e3825d77afb31d52c43153 (patch)
tree23faf81574756f48e5d03eb92d7e3b7b52bf1744
parent28eef6727d3cd4461091a752c19c418d1bf3bcb7 (diff)
downloadgdb-098dbe61246fd65ea5e3825d77afb31d52c43153.zip
gdb-098dbe61246fd65ea5e3825d77afb31d52c43153.tar.gz
gdb-098dbe61246fd65ea5e3825d77afb31d52c43153.tar.bz2
gdbserver: Prevent stale/random values in register cache
When fetch_inferior_registers does not update all registers, this patch assures that no stale register values remain in the register cache. On Linux platforms using the regsets interface, when one of the ptrace calls used for fetching the register values returns an error, this patch also avoids copying the random data returned from ptrace into the register cache. All unfetched registers are marked "unavailable" instead. gdb/gdbserver/ChangeLog: * linux-low.c (regsets_fetch_inferior_registers): Do not invoke the regset's store function when ptrace returned an error. * regcache.c (get_thread_regcache): Invalidate register cache before fetching inferior's registers.
-rw-r--r--gdb/gdbserver/ChangeLog7
-rw-r--r--gdb/gdbserver/linux-low.c11
-rw-r--r--gdb/gdbserver/regcache.c3
3 files changed, 16 insertions, 5 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 7471dae..54caa55 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,5 +1,12 @@
2014-12-12 Andreas Arnez <arnez@linux.vnet.ibm.com>
+ * linux-low.c (regsets_fetch_inferior_registers): Do not invoke
+ the regset's store function when ptrace returned an error.
+ * regcache.c (get_thread_regcache): Invalidate register cache
+ before fetching inferior's registers.
+
+2014-12-12 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
* linux-low.c (regsets_fetch_inferior_registers): Rephrase
while-loop as for-loop.
(regsets_store_inferior_registers): Likewise.
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 164b0f6..c1b53ff 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -4255,8 +4255,6 @@ regsets_fetch_inferior_registers (struct regsets_info *regsets_info,
/* If we get EIO on a regset, do not try it again for
this process mode. */
disable_regset (regsets_info, regset);
- free (buf);
- continue;
}
else
{
@@ -4266,9 +4264,12 @@ regsets_fetch_inferior_registers (struct regsets_info *regsets_info,
perror (s);
}
}
- else if (regset->type == GENERAL_REGS)
- saw_general_regs = 1;
- regset->store_function (regcache, buf);
+ else
+ {
+ if (regset->type == GENERAL_REGS)
+ saw_general_regs = 1;
+ regset->store_function (regcache, buf);
+ }
free (buf);
}
if (saw_general_regs)
diff --git a/gdb/gdbserver/regcache.c b/gdb/gdbserver/regcache.c
index 718ae8c..8c874f0 100644
--- a/gdb/gdbserver/regcache.c
+++ b/gdb/gdbserver/regcache.c
@@ -52,6 +52,9 @@ get_thread_regcache (struct thread_info *thread, int fetch)
struct thread_info *saved_thread = current_thread;
current_thread = thread;
+ /* Invalidate all registers, to prevent stale left-overs. */
+ memset (regcache->register_status, REG_UNAVAILABLE,
+ regcache->tdesc->num_registers);
fetch_inferior_registers (regcache, -1);
current_thread = saved_thread;
regcache->registers_valid = 1;