[patch+7.4] reread.exp 7.3->7.4 regression

Jan Kratochvil
2011-12-18T11:54:24Z

Hi Joel,

this patch should be tested on ARM, I do not yet have some ARM testing
environment (I probably could build one).

There is now crash regression 7.3->7.4, seen on ia64 but it apparently applies
to all archs:

Program terminated with signal 11, Segmentation fault.
#0 in freehook () from /lib/libc.so.6.1
(gdb) bt
#0 in freehook () from /lib/libc.so.6.1
#1 in free () from /lib/libc.so.6.1
#2 in xfree (ptr=0x9393939300000000) at ./common/common-utils.c:109
#3 in VEC_arm_exidx_entry_s_free (vec_=0x6000000000cb01e0) at arm-tdep.c:2143
#4 in arm_exidx_data_free (objfile=0x6000000000ca4650, arg=0x6000000000cb00b0) at arm-tdep.c:2157
#5 in clear_objfile_data (objfile=0x6000000000ca4650) at objfiles.c:1463
#6 in reread_symbols () at symfile.c:2489
#7 in run_command_1 (args=0x0, from_tty=1, tbreak_at_main=0) at infcmd.c:528
#8 in run_command (args=0x0, from_tty=1) at infcmd.c:622

(gdb) file /root/jkratoch/redhat/gdb74/gdb/testsuite/gdb.base/reread
Reading symbols from /root/jkratoch/redhat/gdb74/gdb/testsuite/gdb.base/reread...done.
arm_exidx_new_objfile objfile=0x6000000000ca4650 section_count=36
[...]
`/root/jkratoch/redhat/gdb74/gdb/testsuite/gdb.base/reread' has changed; re-reading symbols.
arm_exidx_data_free objfile=0x6000000000ca4650 section_count=37
FAIL: gdb.base/reread.exp: run to foo() second time (timeout)

This is because objfile->OBFD can change underneath registered objfile data.

There are multiple such problems because objfile is not destroyed + recreated
on objfile reload, there was a patch for it but it has never been checked in:
[patch] Fix a reread_symbols regression by mmap
http://sourceware.org/ml/gdb-patches/2009-06/msg00606.html
http://sourceware.org/ml/gdb-patches/2009-08/msg00207.html
http://sourceware.org/ml/gdb-patches/2011-12/msg00596.html

As I believe the patch above is not suitable for the 7.4 branch offering at
least this very ugly patch which breaks ARM functionality on rereads but it at
least does not break ARM-unrelated arches.

Thanks,
Jan

gdb/
2011-12-18 Jan Kratochvil <jan.kratochvil@redhat.com>

* arm-tdep.c (struct arm_per_objfile): Add field section_count.
(arm_find_mapping_symbol): Sanity check INDEX against SECTION_COUNT.
(struct arm_exidx_data): Add field section_count.
(arm_exidx_data_free): Use SECTION_COUNT from struct arm_exidx_data.
(arm_exidx_new_objfile): Initialize arm_exidx_data->section_count.
Use it.
(arm_find_exidx_entry): Sanity check INDEX against SECTION_COUNT.
(arm_objfile_data_free): Use SECTION_COUNT from struct arm_per_objfile.
(arm_record_special_symbol): Initialize arm_per_objfile->section_count.
Use it. Sanity check INDEX against SECTION_COUNT.

--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -90,6 +90,10 @@ DEF_VEC_O(arm_mapping_symbol_s);
struct arm_per_objfile
{
VEC(arm_mapping_symbol_s) **section_maps;
+
+ /* A copy from OBFD. OBFD can change underneath by reread_symbols. It is
+ wrong then to use arm_per_objfile but at least do not crash. */
+ unsigned int section_count;
};

/* The list of available "set arm ..." and "show arm ..." commands. */
@@ -330,7 +334,7 @@ arm_find_mapping_symbol (CORE_ADDR memaddr, CORE_ADDR *start)
unsigned int idx;

data = objfile_data (sec->objfile, arm_objfile_data_key);
- if (data != NULL)
+ if (data != NULL && sec->the_bfd_section->index < data->section_count)
{
map = data->section_maps[sec->the_bfd_section->index];
if (!VEC_empty (arm_mapping_symbol_s, map))
@@ -2145,6 +2149,10 @@ DEF_VEC_O(arm_exidx_entry_s);
struct arm_exidx_data
{
VEC(arm_exidx_entry_s) **section_maps;
+
+ /* A copy from OBFD. OBFD can change underneath by reread_symbols. It is
+ wrong then to use arm_per_objfile but at least do not crash. */
+ unsigned int section_count;
};

static void
@@ -2153,7 +2161,7 @@ arm_exidx_data_free (struct objfile *objfile, void *arg)
struct arm_exidx_data *data = arg;
unsigned int i;

- for (i = 0; i < objfile->obfd->section_count; i++)
+ for (i = 0; i < data->section_count; i++)
VEC_free (arm_exidx_entry_s, data->section_maps[i]);
}

@@ -2250,8 +2258,9 @@ arm_exidx_new_objfile (struct objfile *objfile)
/* Allocate exception table data structure. */
data = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct arm_exidx_data);
set_objfile_data (objfile, arm_exidx_data_key, data);
+ data->section_count = objfile->obfd->section_count;
data->section_maps = OBSTACK_CALLOC (&objfile->objfile_obstack,
- objfile->obfd->section_count,
+ data->section_count,
VEC(arm_exidx_entry_s) *);

/* Fill in exception table. */
@@ -2425,7 +2434,7 @@ arm_find_exidx_entry (CORE_ADDR memaddr, CORE_ADDR *start)
unsigned int idx;

data = objfile_data (sec->objfile, arm_exidx_data_key);
- if (data != NULL)
+ if (data != NULL && sec->the_bfd_section->index < data->section_count)
{
map = data->section_maps[sec->the_bfd_section->index];
if (!VEC_empty (arm_exidx_entry_s, map))
@@ -9398,7 +9407,7 @@ arm_objfile_data_free (struct objfile *objfile, void *arg)
struct arm_per_objfile *data = arg;
unsigned int i;

- for (i = 0; i < objfile->obfd->section_count; i++)
+ for (i = 0; i < data->section_count; i++)
VEC_free (arm_mapping_symbol_s, data->section_maps[i]);
}

@@ -9421,10 +9430,13 @@ arm_record_special_symbol (struct gdbarch *gdbarch, struct objfile *objfile,
data = OBSTACK_ZALLOC (&objfile->objfile_obstack,
struct arm_per_objfile);
set_objfile_data (objfile, arm_objfile_data_key, data);
+ data->section_count = objfile->obfd->section_count;
data->section_maps = OBSTACK_CALLOC (&objfile->objfile_obstack,
- objfile->obfd->section_count,
+ data->section_count,
VEC(arm_mapping_symbol_s) *);
}
+ else if (bfd_get_section (sym)->index >= data->section_count)
+ return;
map_p = &data->section_maps[bfd_get_section (sym)->index];

new_map_sym.value = sym->value;