This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

SIGSEGV on gdb 6.7*


Hi list,

I have been playing with gdb-6.7 and it appears there is a bug whereby reading registers can cause a SIGSEGV in gdb. The simplest way I've found to cause the problem is to try to read a register after calling the flushregs maintenance command:

$ cat hello.c
#include <stdio.h>

int
main (void)
{
printf ("hello, world\n");
return 0;
}
$ gcc -g hello.c
$ ./gdb a.out
GNU gdb 6.7.1
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
(gdb) start
Breakpoint 1 at 0x8048385: file hello.c, line 6.
Starting program: /mnt/duron/tests/a.out
main () at hello.c:6
6 printf ("Hello world\n");
(gdb) flushregs
Register cache flushed.
(gdb) print $pc
Segmentation fault (core dumped)
$



I realise that flushregs is not exactly a "supported" feature, but since the implementation of that command is simply:


static void
reg_flush_command (char *command, int from_tty)
{
  /* Force-flush the register cache.  */
  registers_changed ();
  if (from_tty)
    printf_filtered (_("Register cache flushed.\n"));
}

one wonders if there aren't other ways this issue can be triggered.

I have had a look around the code, and it's one of those "how could it ever have worked?" occasions (which of course typically means I've missed something important). The implementation of registers_changed() is (essentially):

void
registers_changed (void)
{
  int i;

  regcache_xfree (current_regcache);
  current_regcache = NULL;

yet there appear to be pointers to the regcache squirrelled away in various other places, notably the prologue_cache member of the frame_info structure.

I'm sure I'm missing something here -- how come freeing current_regcache is safe with pointers to the register cache out-living it?

I have found that the following simple patch appears to fix (or at least work round) the SEGV triggered by flushregs:

Index: regcache.c
===================================================================
RCS file: /cvs/src/src/gdb/regcache.c,v
retrieving revision 1.163
diff -u -r1.163 regcache.c
--- regcache.c  1 Jan 2008 22:53:12 -0000       1.163
+++ regcache.c  3 Feb 2008 21:35:19 -0000
@@ -885,6 +885,7 @@
 {
   /* Force-flush the register cache.  */
   registers_changed ();
+  get_current_regcache ();
   if (from_tty)
     printf_filtered (_("Register cache flushed.\n"));
 }

However, I am insufficiently familiar with the gdb internals to know which, if any, of the other call-sites to register_changed() should be similarly updated. Perhaps it would be safer simply to call get_current_regcache() from the end of registers_changed():

Index: regcache.c
===================================================================
RCS file: /cvs/src/src/gdb/regcache.c,v
retrieving revision 1.163
diff -u -r1.163 regcache.c
--- regcache.c  1 Jan 2008 22:53:12 -0000       1.163
+++ regcache.c  3 Feb 2008 21:49:37 -0000
@@ -472,6 +472,9 @@
   regcache_xfree (current_regcache);
   current_regcache = NULL;

+  /* Update the cache with the new registers. */
+  get_current_regcache ();
+
   /* Force cleanup of any alloca areas if using C alloca instead of
      a builtin alloca.  This particular call is used to clean up
      areas allocated by low level target code which may build up


I guess this might result in some "unnecessary" fetches of the register state, but that has to be favourable to a SEGV :)


Cheers,

Greg


-- Greg Law, Undo Software http://undo-software.com/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]