Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 16 Jun 2006 02:46:47 +0400
From:      Yar Tikhiy <yar@comp.chem.msu.su>
To:        freebsd-hackers@freebsd.org
Subject:   Re: Stack frame problem in gdb
Message-ID:  <20060615224646.GA79952@comp.chem.msu.su>
In-Reply-To: <20060516071240.GA6338@comp.chem.msu.su>
References:  <20060516071240.GA6338@comp.chem.msu.su>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, May 16, 2006 at 11:12:40AM +0400, Yar Tikhiy wrote:
> 
> Has our stock GDB lost the ability to set the current stack frame
> by its address?  In 4.11-STABLE, the old recipe from the Developer's
> Handbook still works:
> 
> 	frame <frame_addr> <instruction_ptr>
> 
> Alas, it no longer works in RELENG_6 or CURRENT (tested on i386 and
> amd64.)  A sample typescript is attached.  It boils down to the
> following: The "frame" command accepts one argument at most in the
> new GDB, which is taken for the address of a frame if it's sufficiently
> large.  Refusing now to read the instruction pointer value from the
> command line, GDB sets it to 0 -- a smart guess, damn it.  Finally,
> GDB crashes on the bogus frame it made up.

It seems to be a genuine GDB 6 i386 bug reported as early as in
2002: <http://sourceware.org/ml/gdb/2002-11/msg00263.html>.  It
exists in Linux, too, as tested in Debian with GDB 6.3.

Moreover, GDB 6 fails to assign correct addresses to stack frames.
This might be related to the former issue, as testing on alpha
showed (see below.)

Does anybody know GDB folks who can help in fixing the issues?

Example:

%%% GDB 6 i386 %%%
(gdb) i f 2
Stack frame at 0xbfbfeca8:
 eip = 0x80484ac in b (test.c:13); saved eip 0x80484b8
 called by frame at 0xbfbfecb0, caller of frame at 0xbfbfeca0
 source language c.
 Arglist at 0xbfbfeca0, args:
 Locals at 0xbfbfeca0, Previous frame's sp is 0xbfbfeca8
 Saved registers:
  ebp at 0xbfbfeca0, eip at 0xbfbfeca4
(gdb) i f 3
Stack frame at 0xbfbfecb0:
 eip = 0x80484b8 in c (test.c:18); saved eip 0x80484dd
 called by frame at 0xbfbfecd0, caller of frame at 0xbfbfeca8
 source language c.
 Arglist at 0xbfbfeca8, args:
 Locals at 0xbfbfeca8, Previous frame's sp is 0xbfbfecb0
 Saved registers:
  ebp at 0xbfbfeca8, eip at 0xbfbfecac

### The frame addresses were off by one frame.  It was a coincidence,
### as the following tests on alpha will show.  The addresses are just
### bogus.

%%% GDB 6 alpha %%%
(gdb) i f 2
Stack frame at 0x11ffeb80:
 pc = 0x12000087c in b (test.c:13); saved pc 0x1200008ac
 called by frame at 0x11ffeb90, caller of frame at 0x11ffeb70
 source language c.
 Arglist at 0x11ffeb80, args:
 Locals at 0x11ffeb80, Previous frame's sp is 0x11ffeb80
 Saved registers:
  fp at 0x11ffeb78, ra at 0x11ffeb70, pc at 0x11ffeb70
(gdb) i f 3
Stack frame at 0x11ffeb90:
 pc = 0x1200008ac in c (test.c:18); saved pc 0x1200008dc
 called by frame at 0x11ffeba0, caller of frame at 0x11ffeb80
 source language c.
 Arglist at 0x11ffeb90, args:
 Locals at 0x11ffeb90, Previous frame's sp is 0x11ffeb90
 Saved registers:
  fp at 0x11ffeb88, ra at 0x11ffeb80, pc at 0x11ffeb80

### The frame addresses were just bogus.
### Let's look at frame 2 by its address:

(gdb) i f 0x11ffeb80 0x12000087c
Stack frame at 0x11ffeb80:
 pc = 0x12000087c in b (test.c:14); saved pc 0x12000084c
 called by frame at 0x11ffeb70
 source language c.
 Arglist at 0x11ffeb60, args:
 Locals at 0x11ffeb60, Previous frame's sp is 0x11ffeb60
 Saved registers:
  fp at 0x11ffeb58, ra at 0x11ffeb50, pc at 0x11ffeb50

### It's not frame 2!  Which frame is it?..

(gdb) i f 0
Stack frame at 0x11ffeb60:
 pc = 0x120000810 in x (test.c:3); saved pc 0x12000084c
 called by frame at 0x11ffeb70
 source language c.
 Arglist at 0x11ffeb60, args:
 Locals at 0x11ffeb60, Previous frame's sp is 0x11ffeb60
 Saved registers:
  fp at 0x11ffeb58, ra at 0x11ffeb50, pc at 0x11ffeb50

### Oops, GDB showed us frame 0 when we tried to look at
### the frame @ 0x11ffeb80!

%%% GDB 4 i386 %%%
(gdb) i f 2
Stack frame at 0xbfbff6f0:
 eip = 0x804849f in b (test.c:13); saved eip 0x80484b7
 called by frame at 0xbfbff700, caller of frame at 0xbfbff6e0
 source language c.
 Arglist at 0xbfbff6f0, args:
 Locals at 0xbfbff6f0, Previous frame's sp is 0x0
 Saved registers:
  ebp at 0xbfbff6f0, eip at 0xbfbff6f4
(gdb) i f 3
Stack frame at 0xbfbff700:
 eip = 0x80484b7 in c (test.c:18); saved eip 0x80484cf
 called by frame at 0xbfbff710, caller of frame at 0xbfbff6f0
 source language c.
 Arglist at 0xbfbff700, args:
 Locals at 0xbfbff700, Previous frame's sp is 0x0
 Saved registers:
  ebp at 0xbfbff700, eip at 0xbfbff704

### The good old GDB 4 was working OK...

-- 
Yar

P.S. The program used for the tests was as follows:
x()
{
        return 1;
}

a()
{
        return x();
}

b()
{
        return a();
}

c()
{
        return b();
}

main()
{
        return c();
}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20060615224646.GA79952>