[gnu.gdb.bug] bug in gdb 3.3 on iPSC/2

nagel@ics.uci.edu (Mark Nagel) (10/24/89)

The following is a script of a session with a freshly built gdb 3.3
on an Intel iPSC/2 Hypercube (config = i386-sysv3.2):

------------------------------------------------------------------------------
GDB 3.3, Copyright (C) 1989 Free Software Foundation, Inc.
There is ABSOLUTELY NO WARRANTY for GDB; type "info warranty" for
details.
GDB is free software and you are welcome to distribute copies of it
 under certain conditions; type "info copying" to see the conditions.
Reading symbol data from /usr/src/usr/gnu/gdb-3.3/gdb...unexpected
type 11 at sy
mnum 19549
unexpected type 11 at symnum 19550
done.
Setting up the environment for debugging gdb.
Breakpoint 1 at 0x26837: file utils.c, line 276.
Breakpoint 2 at 0x1603: file main.c, line 1059.
Type "help" for a list of commands.
(top-gdb) b main
Breakpoint 3 at 0x3d0: file main.c, line 237.
(top-gdb) run
Starting program: /usr/src/usr/gnu/gdb-3.3/gdb

Bpt 3, main (Error reading memory address 0x2543acdd: I/O error (5).
------------------------------------------------------------------------------

The memory read error appears to be happening in read_inferior_memory,
but it isn't clear why.  I have no idea what is wrong with the
symbol table.  If anyone out there has encountered these problems
and knows of a fix, please let me know.  Thanks in advance...

--
Mark Nagel
UC Irvine Department of ICS   +----------------------------------------+
ARPA: nagel@ics.uci.edu       | Charisma doesn't have jelly in the     |
UUCP: ucbvax!ucivax!nagel     | middle.  -- Jim Ignatowski             |

pat@wang.UUCP (Pat Knight) (10/27/89)

In message <1989Oct23.173711.11319@paris.ics.uci.edu> Mark Nagel writes:

>The following is a script of a session with a freshly built gdb 3.3
>on an Intel iPSC/2 Hypercube (config = i386-sysv3.2):
>
>------------------------------------------------------------------------------
>GDB 3.3, Copyright (C) 1989 Free Software Foundation, Inc.
>There is ABSOLUTELY NO WARRANTY for GDB; type "info warranty" for
>details.
>GDB is free software and you are welcome to distribute copies of it
> under certain conditions; type "info copying" to see the conditions.
>Reading symbol data from /usr/src/usr/gnu/gdb-3.3/gdb...unexpected
>type 11 at sy
>mnum 19549
>unexpected type 11 at symnum 19550
>done.
>Setting up the environment for debugging gdb.
>Breakpoint 1 at 0x26837: file utils.c, line 276.
>Breakpoint 2 at 0x1603: file main.c, line 1059.
>Type "help" for a list of commands.
>(top-gdb) b main
>Breakpoint 3 at 0x3d0: file main.c, line 237.
>(top-gdb) run
>Starting program: /usr/src/usr/gnu/gdb-3.3/gdb
>
>Bpt 3, main (Error reading memory address 0x2543acdd: I/O error (5).
>------------------------------------------------------------------------------
>
>The memory read error appears to be happening in read_inferior_memory,
>but it isn't clear why.  I have no idea what is wrong with the
>symbol table.  If anyone out there has encountered these problems
>and knows of a fix, please let me know.  Thanks in advance...

I've got the same error in version 3.2 configured for i386sysv.  The "good"
news is that we don't appear to be alone. From source inspection, I think
lots of other configurations should have the same problem, but I don't use
those machines so what do I know.

I've tracked down the error to an interaction between the first_object_file_end
variable declared in the file blockframe.c and the FRAME_CHAIN and
FRAME_CHAIN_VALID macros (declared in m-i386.h, linked to param.h by
config.gdb).  These macros don't return a frame pointer (gdb's internal
record of the invocation frames on the debugged process' stack) if the pc of
the function whose frame is required is less than first_object_file_end.  The
intent of this is clear, in that it stops backtrace showing the system
dependent start up functions (ie _start from /lib/crt1.o).  However, the
print_frame_info function looks at the caller's frame information to determine
the number of arguments passed to the current function.  So, you break in
main and gdb tries to print something like "main(argc=2,argv=0x7ffffe80)"
(I'm just giving an example - I know it doesn't really print that).  It calls
FRAME_NUM_ARGS to obtain the number of arguments passed to main.  In the
m-i386.h (386 configured for System V) case, this calls get_prev_frame_info
which calls FRAME_CHAIN and FRAME_CHAIN_VALID.  These find that main's caller
has a pc less than first_object_file_end, return 0, get_prev_frame_info
returns a NULL reference, FRAME_NUM_ARGS dereferences it and gets a random
value for the memory address of _start's stackframe, and we get Mark's error
message.

I've kludged a temporary fix to take out the test against first_object_file_end
and my gdb works fine now.  However, I would like the gdb internals gurus to
say what the "ideal" fix is. All I've done is move the memory address error
to the report of _start which now appears in a stack backtrace.  I could hack
things so that if the pc of the current frame is > first_object_file_end then
look at the caller's frame unconditionally, and if the pc of the current frame
is less than first_object_file_end don't print any info at all.

I'm going to try this and might post fixes if it works, but I'd rather the
gdb developers do something cleaner than I have the knowledge about gdb to do.

Cheers,
	Pat
PS  In the meantime, 386 people can get the "unsafe" fix by modifying the
FRAME_CHAIN and FRAME_CHAIN_VALID macros in m-i386.h to remove the test
against first_object_file_end, link the new m-i386.h to param.h and rebuild.
At least you'll see main.

kingdon@ai.mit.edu (Jim Kingdon) (10/27/89)

    [GDB cannot find number of arguments for main on i386 because
    FRAME_CHAIN_VALID doesn't allow get_prev_frame_info to go into
    start.]

I fixed this in the working GDB (i.e. the fix will be in the next
release) by just not having FRAME_NUM_ARGS return the number of
arguments (i.e. return -1) when get_prev_frame_info returns 0.  This
is pretty much harmless because main is not a varadic function, so if
you have debugging symbols GDB will know how many arguments it has
from the debugging symbols.  If someone wants to see all 3 arguments
to main, no matter how it is declared in the source, it would require
something like a really_get_prev_frame_info in addition to
get_prev_frame_info.

The check for start is necessary, because at least on some machines
there is no way to tell where the bottom of the stack is, so we have
to stop looking when we get to start.

nagel@ics.uci.edu (Mark Nagel) (10/29/89)

kingdon@ai.mit.edu (Jim Kingdon) writes:


>    [GDB cannot find number of arguments for main on i386 because
>    FRAME_CHAIN_VALID doesn't allow get_prev_frame_info to go into
>    start.]

>I fixed this in the working GDB (i.e. the fix will be in the next
>release) by just not having FRAME_NUM_ARGS return the number of
>arguments (i.e. return -1) when get_prev_frame_info returns 0.  This
>is pretty much harmless because main is not a varadic function, so if
>you have debugging symbols GDB will know how many arguments it has
>from the debugging symbols.  If someone wants to see all 3 arguments
>to main, no matter how it is declared in the source, it would require
>something like a really_get_prev_frame_info in addition to
>get_prev_frame_info.

I applied this fix to FRAME_NUM_ARGS and gdb works fine now (except
for that unknown symbol type, but that's minor).  Thanks a lot for
the help!
--
Mark Nagel
UC Irvine Department of ICS   +----------------------------------------+
ARPA: nagel@ics.uci.edu       | radiation: smog with an attitude       |
UUCP: ucbvax!ucivax!nagel     +----------------------------------------+