gdbserver: Prevent stale/random values in register cache
authorAndreas Arnez <arnez@linux.vnet.ibm.com>
Fri, 12 Dec 2014 13:14:20 +0000 (14:14 +0100)
committerAndreas Krebbel <krebbel@linux.vnet.ibm.com>
Fri, 12 Dec 2014 13:15:07 +0000 (14:15 +0100)
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.

gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-low.c
gdb/gdbserver/regcache.c

index 7471dae583d39e0a457aaea74ad63cc83fdf2693..54caa55ef12d4d8b0cf8d482f4d247942181f2a6 100644 (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
index 164b0f662400b3ae2ff2cb4a6d08e8245b7c53d2..c1b53ff42d1e7c1347b47139bb5921d47e9e6a58 100644 (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)
index 718ae8c3c9b921e1b384e7fb871d901c8b3caebb..8c874f0c2a4fd5416a94f3b842c448d0a3a0454b 100644 (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;