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.
This commit is contained in:
Andreas Arnez 2014-12-12 14:14:20 +01:00 committed by Andreas Krebbel
parent 28eef6727d
commit 098dbe6124
3 changed files with 16 additions and 5 deletions

View File

@ -1,3 +1,10 @@
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

View File

@ -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)

View File

@ -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;