segfault on opening a register window

Atsushi Nemoto <[email protected]>
Newsgroups gmane.comp.debugging.insight
Message-ID <[email protected]>
The insight crashes with segfault when opening a register window after
connecting to a remote ARM target.  I confirmed the problem with 7.0.1,
7.1 and current CVS.

The crash happened here:

Program received signal SIGSEGV, Segmentation fault.
get_register (regnum=0, arg={integer = 0, ptr = 0x0})
    at ../../insight/src/gdb/gdbtk/generic/gdbtk-register.c:341
341	      if ((TYPE_CODE (reg_vtype) == TYPE_CODE_UNION)

(gdb) p reg_vtype
$1 = (struct type *) 0x66

The reg_vtype pointer had a wrong value.  I realized that contents of
regtype[] array are corrupted.  This is because current gdbarch was
changed but regformat or regtype array was not reconstructed.

1. start insight.
2. setup_architecture_data() was called.
3. connecting to a remote target, then gdbarch (also numregs) changed.
4. gdb_regformat() was called and write to outside of allocated
   regformat, regtype array.

The problem is setup_architecture_data() is not called when gdbarch
was changed.  If I opened the register window _before_ connecting to
a remote target, setup_architecture_data() is called via
gdb_reg_arch_changed.  But it seems gdb_reg_arch_changed is called
only if the register windows was opened.

Here is a quick workaround.  Is there good way to call
setup_architecture_data() automatically if current arch was changed?
Or other good fix?


--- gdb/gdbtk/generic/gdbtk-register.c.org	2010-09-07 23:06:48.000000000 +0900
+++ gdb/gdbtk/generic/gdbtk-register.c	2010-09-07 23:06:59.000000000 +0900
@@ -65,6 +65,7 @@ static void get_register_types (int regn
 static char *old_regs = NULL;
 static int *regformat = (int *)NULL;
 static struct type **regtype = (struct type **)NULL;
+static struct gdbarch *cur_gdbarch = NULL;
 
 int
 Gdbtk_Register_Init (Tcl_Interp *interp)
@@ -149,6 +150,10 @@ gdb_register_info (ClientData clientData
       return TCL_ERROR;
     }
   
+  /* Check gdbarch change to avoid corruption of regformat/regtype array */
+  if (cur_gdbarch != get_current_arch ())
+    setup_architecture_data ();
+
   /* Skip the option */
   objc -= 2;
   objv += 2;
@@ -469,6 +474,7 @@ setup_architecture_data ()
 {
   int numregs;
 
+  cur_gdbarch = get_current_arch ();
   xfree (old_regs);
   xfree (regformat);
   xfree (regtype);

---
Atsushi Nemoto
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.