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: info frame ADDR internal error


On Sunday 25 January 2009 19:44:32, Pedro Alves wrote:
> :-(
> 
> Was going to commit the patch, but then I tried it on x86 (I was on x86-64 before) ...

I actually went ahead, and committed the patch.  It fixes some bogosity,
and uncovers the next problem.  This should help everyone else who
wants to look at the issue.

> 
>  (top-gdb) bt
>  #0  main (argc=1, argv=0xffffd524) at ../../src/gdb/gdb.c:28
> 
>  (top-gdb) info frame 1
>  Stack frame at 0x1:
>   eip = 0x0; saved eip 0xf7f26f59
> 
>  Breakpoint 1, internal_error (file=0x8314a4f "../../src/gdb/valops.c", line=662,
>      string=0x8314a19 "%s: Assertion `%s' failed.") at ../../src/gdb/utils.c:972
>  972       va_start (ap, string);
> 
>  (top-gdb) bt
>  #0  internal_error (file=0x8314a4f "../../src/gdb/valops.c", line=662, string=0x8314a19 "%s: Assertion `%s' failed.")
>      at ../../src/gdb/utils.c:972
>  #1  0x08116c44 in value_fetch_lazy (val=0x883f960) at ../../src/gdb/valops.c:662
>  #2  0x0810b766 in value_contents_all (value=0x883f960) at ../../src/gdb/value.c:375
>  #3  0x081efd43 in frame_register_unwind (frame=0x8421250, regnum=5, optimizedp=0xffc759f4, lvalp=0xffc759e8,
>      addrp=0xffc759f0, realnump=0xffc759ec, bufferp=0xffc75a40 "...") at ../../src/gdb/frame.c:603
>  #4  0x081eff19 in frame_unwind_register (frame=0x8421250, regnum=5, buf="...") at ../../src/gdb/frame.c:639
>  #5  0x081eff3d in get_frame_register (frame=0x84212e4, regnum=5, buf="...") at ../../src/gdb/frame.c:647
>  #6  0x0809c2b7 in i386_frame_cache (this_frame=0x84212e4, this_cache=0x84212e8) at ../../src/gdb/i386-tdep.c:1306
>  #7  0x0809c47e in i386_frame_this_id (this_frame=0x84212e4, this_cache=0x84212e8, this_id=0x8421304)
>      at ../../src/gdb/i386-tdep.c:1369
>  #8  0x081ef2cb in get_frame_id (fi=0x84212e4) at ../../src/gdb/frame.c:261
>  #9  0x081f194d in get_frame_base (fi=0x84212e4) at ../../src/gdb/frame.c:1666
>  #10 0x0814cd44 in frame_info (addr_exp=0x83f5133 "1", from_tty=1) at ../../src/gdb/stack.c:995
>  #11 0x080d51b7 in do_cfunc (c=0x84187c0, args=0x83f5133 "1", from_tty=1) at ../../src/gdb/cli/cli-decode.c:67
> 
> Here's the offender:
> 
>  int
>  value_fetch_lazy (struct value *val)
>  {
>    gdb_assert (value_lazy (val));
>    allocate_value_contents (val);
>    if (VALUE_LVAL (val) == lval_memory)
>      {
>        CORE_ADDR addr = VALUE_ADDRESS (val) + value_offset (val);
>        int length = TYPE_LENGTH (check_typedef (value_enclosing_type (val)));
>  
>        if (length)
>  	read_memory (addr, value_contents_all_raw (val), length);
>      }
>    else if (VALUE_LVAL (val) == lval_register)
>      {
>        struct frame_info *frame;
>        int regnum;
>        struct type *type = check_typedef (value_type (val));
>        struct value *new_val = val, *mark = value_mark ();
>  
>        /* Offsets are not supported here; lazy register values must
>  	 refer to the entire register.  */
>        gdb_assert (value_offset (val) == 0);
>  
>        while (VALUE_LVAL (new_val) == lval_register && value_lazy (new_val))
>  	{
>  	  frame = frame_find_by_id (VALUE_FRAME_ID (new_val));
>                   ^^^^^^^^^^^^^^^^
>  	  regnum = VALUE_REGNUM (new_val);
>  
>  	  gdb_assert (frame != NULL);
>           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 
>  (top-gdb) p VALUE_FRAME_ID (new_val)
>  $1 = {stack_addr = 1, code_addr = 0, special_addr = 0, stack_addr_p = 1, code_addr_p = 1, special_addr_p = 0}
> 
> The new frame that create_new_frame created, isn't linked in the
> regular ( current_frame->... ) frame chain, it lives in its own chain,
> so this frame_find_by_id call isn't going to find it, unless you
> get lucky.
> 
> This reinforces the bad things I was saying about create_new_frame.
> 
> Any suggestions on how this could be fixed?
> 
> Before we go farther, is this a valid use case at all?  Could
> we rip this piece of parse_frame_specification_1 out instead?  It's been
> broken for years now --- I can reproduce the original internal error
> on gdb-6.0:
> 
>  >./gdb ./gdb
>  GNU gdb 6.0
>  Copyright 2003 Free Software Foundation, Inc.
>  ...
>  (top-gdb) b main
>  Breakpoint 3 at 0x8077aa4: file ../../gdb-6.0/gdb/gdb.c, line 30.
>  (top-gdb) r
>  Starting program: /home/pedro/gdb/ancient/build-6.0/gdb/gdb
>  Breakpoint 3, main (argc=1, argv=0xffd15254) at ../../gdb-6.0/gdb/gdb.c:30
>  30        memset (&args, 0, sizeof args);
>  (top-gdb) info frame 1
>  Stack frame at 0x1:
>   eip = 0x0; saved eip
>  ../../gdb-6.0/gdb/dwarf2-frame.c:518: internal-error: dwarf2_frame_cache: Assertion `fde != NULL' failed.
> 
> Note that "info frame ADDR" and "frame ADDR" do look for a frame in
> the regular chain that matches ADDR, before resorting to hacking up
> a new one with create_new_frame.
> 



-- 
Pedro Alves


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