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]

Re: crash/regression with ia64 targets


On 12/13/2012 12:05 PM, Joel Brobecker wrote:
>> 2012-11-24  Daniel Jacobowitz  <dan@codesourcery.com>
>> > 	    Kazu Hirata  <kazu@codesourcery.com>
>> > 	    Yao Qi  <yao@codesourcery.com>
>> > 
>> > 	* objfiles.c (entry_point_address_query): Move some code ...
>> > 	(init_entry_point_info): ... here.
>> > 	* solib-svr4.c (exec_entry_point): Likewise.
>> > 	* symfile.c (generic_load): Call gdbarch_addr_bits_remove on
>> > 	the entry address.
> Unfortunately, this patch breaks GDB on ia64 (linux and hpux) :-(.
> Take any program, and try loading it in GDB:
> 
>     (gdb) file hello
>     Reading symbols from /[...]/hello...
>     zsh: 9462 segmentation fault  /[...]/gdb
> 
> What happens is that we've now added a call to
> gdbarch_convert_from_func_ptr_addr inside init_entry_point_info,
> which is called from syms_from_objfile *before* the objfile's
> section_offsets array is allocated.
> 
> On ia64, gdbarch_convert_from_func_ptr_addr resolves to
> ia64_convert_from_func_ptr_addr, which calls find_pc_section.
> This, in turns calls update_section_map, which does a sort
> on all sections, where qsort_cmp uses the obj_section_addr
> macro:
> 
> #define obj_section_addr(s)                                             \
>   (bfd_get_section_vma ((s)->objfile->obfd, s->the_bfd_section)         \
>    + obj_section_offset (s))
> 
> ... and obj_section_offset is defined as:
> 
> #define obj_section_offset(s)                                           \
>   (((s)->objfile->section_offsets)->offsets[(s)->the_bfd_section->index])
>                   ^^^^^^^^^^^^^^^^^^
> 
> Basically, to resolve whether our pointer is pointing to a descriptor
> or not, we need to find its associated section. But to find the section,
> we need the section_offsets to be defined.
> 
> So, to me, it looks like the attempt at resolving the entry point
> is performed too early. And to make things even more fun, there
> are cases where we do not allocated section_offsets at all:
> 
>   if (objfile->sf == NULL)
>     return;     /* No symbols.  */
> 
> But the other worrisome element is that most calls to
> init_entry_point_info are made from routines used as
> the "sym_init" struct sym_fns hook, and this hook is
> in fact called, in syms_from_objfile, before the section_offsets
> table is allocated.
> 
> Since syms_from_objfile is calling init_entry_point_info,
> it seems to me that the call to init_entry_point_info in
> the "sym_init" hooks are redundant, and could be removed,
> clearing one hurdle.
> 
> The other hurdle is making sure that init_entry_point_info
> is called *after* the section offsets have been allocated.
> Which means we need to make sure that we always allocate
> some, including in the case where no symbols are found.
> This must also become a documented invariant.

Seems fine to me.

I wonder why this crash wasn't visible before.  AFAICS from find_sym_fns,
the only kinds of objfiles that can be loaded without debugging symbols are
srec, ihex and tekhex (the latter can have symbols, but we don't read in those).

Ah, indeed, it was.  I can reproduce it:

...
(top-gdb) start
Temporary breakpoint 3 at 0x48f020: file ../../src/gdb/gdb.c, line 26.
Starting program: /home/pedro/gdb/mygit/build-all/gdb/gdb
Temporary breakpoint 3,
main (argc=1, argv=0x7fffffffdc38) at ../../src/gdb/gdb.c:26
26      {
(top-gdb) dump srec value dump.srec main
(top-gdb) shell cat dump.srec
S00C000064756D702E7372656362
S20548F020485A
S804000000FB
(top-gdb) file dump.srec
A program is being debugged already.
Are you sure you want to change the file? (y or n) y
Load new symbol table from "/home/pedro/gdb/mygit/build-all/gdb/dump.srec"? (y or n) y
Reading symbols from /home/pedro/gdb/mygit/build-all/gdb/dump.srec...(no debugging symbols found)...done.

Program received signal SIGSEGV, Segmentation fault.
0x00000000006c6566 in qsort_cmp (a=<optimized out>, b=<optimized out>) at ../../src/gdb/objfiles.c:1059
1059      const CORE_ADDR sect2_addr = obj_section_addr (sect2);
(top-gdb) bt
#0  0x00000000006c6566 in qsort_cmp (a=<optimized out>, b=<optimized out>) at ../../src/gdb/objfiles.c:1059
#1  0x0000003d25e37d72 in msort_with_tmp (p=0x7fffffffd5f0, b=0x35693a8, n=2) at msort.c:84
#2  0x0000003d25e37b5a in msort_with_tmp (n=2, b=0x35693a8, p=0x7fffffffd5f0) at msort.c:46
#3  msort_with_tmp (p=0x7fffffffd5f0, b=0x35693a0, n=3) at msort.c:55
#4  0x0000003d25e37b5a in msort_with_tmp (n=3, b=0x35693a0, p=0x7fffffffd5f0) at msort.c:46
#5  msort_with_tmp (p=0x7fffffffd5f0, b=0x3569390, n=5) at msort.c:55
#6  0x0000003d25e37b5a in msort_with_tmp (n=5, b=0x3569390, p=0x7fffffffd5f0) at msort.c:46
#7  msort_with_tmp (p=0x7fffffffd5f0, b=0x3569368, n=10) at msort.c:55
#8  0x0000003d25e37b5a in msort_with_tmp (n=10, b=0x3569368, p=0x7fffffffd5f0) at msort.c:46
#9  msort_with_tmp (p=0x7fffffffd5f0, b=0x3569318, n=20) at msort.c:55
#10 0x0000003d25e37b5a in msort_with_tmp (n=20, b=0x3569318, p=0x7fffffffd5f0) at msort.c:46
#11 msort_with_tmp (p=0x7fffffffd5f0, b=0x3569280, n=39) at msort.c:55
#12 0x0000003d25e37b5a in msort_with_tmp (n=39, b=0x3569280, p=0x7fffffffd5f0) at msort.c:46
#13 msort_with_tmp (p=0x7fffffffd5f0, b=0x3569150, n=77) at msort.c:55
#14 0x0000003d25e37b5a in msort_with_tmp (n=77, b=0x3569150, p=0x7fffffffd5f0) at msort.c:46
#15 msort_with_tmp (p=0x7fffffffd5f0, b=0x3568ee8, n=154) at msort.c:55
#16 0x0000003d25e37b5a in msort_with_tmp (n=154, b=0x3568ee8, p=0x7fffffffd5f0) at msort.c:46
#17 msort_with_tmp (p=0x7fffffffd5f0, b=0x3568a18, n=308) at msort.c:55
#18 0x0000003d25e37b5a in msort_with_tmp (n=308, b=0x3568a18, p=0x7fffffffd5f0) at msort.c:46
#19 msort_with_tmp (p=0x7fffffffd5f0, b=0x3568080, n=615) at msort.c:55
#20 0x0000003d25e380ac in msort_with_tmp (n=615, b=0x3568080, p=0x7fffffffd5f0) at msort.c:46
#21 __GI_qsort_r (b=b@entry=0x3568080, n=n@entry=615, s=s@entry=8, cmp=cmp@entry=0x6c6530 <qsort_cmp>, arg=arg@entry=0x0) at msort.c:298
#22 0x0000003d25e38168 in __GI_qsort (b=b@entry=0x3568080, n=n@entry=615, s=s@entry=8, cmp=cmp@entry=0x6c6530 <qsort_cmp>) at msort.c:308
#23 0x00000000006c7735 in update_section_map (pmap_size=0x1d11b30, pmap=0x1d11b28, pspace=0x1c96040) at ../../src/gdb/objfiles.c:1321
#24 find_pc_section (pc=4780064) at ../../src/gdb/objfiles.c:1366
#25 0x00000000006ca69d in lookup_minimal_symbol_by_pc_section (pc=pc@entry=4780064, section=section@entry=0x0) at ../../src/gdb/minsyms.c:708
#26 0x00000000006642a9 in find_pc_sect_symtab (pc=4780064, section=0x0) at ../../src/gdb/symtab.c:2078
#27 0x0000000000664495 in find_pc_symtab (pc=<optimized out>) at ../../src/gdb/symtab.c:2178
#28 0x0000000000758822 in select_frame (fi=0x26f8e80) at ../../src/gdb/frame.c:1448
#29 0x0000000000758979 in get_selected_frame (message=message@entry=0x0) at ../../src/gdb/frame.c:1386
#30 0x00000000007589e8 in deprecated_safe_get_selected_frame () at ../../src/gdb/frame.c:1410
#31 0x000000000074f189 in check_frame_language_change () at ../../src/gdb/top.c:376
#32 0x000000000074f35b in execute_command (p=0x1ab516d "c", p@entry=0x1ab5160 "", from_tty=1) at ../../src/gdb/top.c:504
...

We crash because bfd presents us a section:

$ objdump -h dump.srec

dump.srec:     file format srec

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .sec1         00000001  0048f020  0048f020  0000001e  2**0
                  CONTENTS, ALLOC, LOAD


and we allocate one entry for it in objfile->sections..sections_end but not
in the offsets table, and then walk over objfile->sections..sections_end:

#define ALL_OBJFILE_OSECTIONS(objfile, osect)	\
  for (osect = objfile->sections; osect < objfile->sections_end; osect++)

> 
> Attached is a prototype that seems to work on ia64-linux.
> I've only tested it against our testsuite for now, but it will
> need to be tested with the official testsuite on GNU/Linux,
> as well as on Darwin, AiX, and maybe Windows (although,
> I think the changes removing the calls to init_entry_point_info
> should be fine).
> 
> Note that there is a second call to init_entry_point_info,
> this time inside reread_symbols, but this one should be fine.
> 
> This patch also begs the question whether we might want to
> move init_entry_point_info to objfiles.c and make it static.

Not clear to me which place would be best.  I suggest do nothing,
as its easiest  :-)

>    if (objfile->sf == NULL)
> -    return;	/* No symbols.  */
> +    {
> +      int num_sections = bfd_count_sections (objfile->obfd);
> +      size_t size = SIZEOF_N_SECTION_OFFSETS (num_offsets);
> +
> +      objfile->num_sections = num_sections;
> +      objfile->section_offsets
> +        = obstack_alloc (&objfile->objfile_obstack, size);
> +      memset (objfile->section_offsets, 0, size);
> +      return;	/* No symbols.  */

I'd put this "No symbols" comment right after the '{' after the if.

-- 
Pedro Alves


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