brian@vdbsan.UUCP (Brian Bainter) (09/14/90)
Can anyone tell me what the hell a "Broken stack frame" message from the debugger is telling me. I have a program that keeps aborting at odd times and when I bring the thing in to the debugger, all I get is a broken stack frame message and no idea where or what aborted the program. If anyone has any insights to this problem, I would be most greatful to hear from you. Thanks in advance, Brian Bainter gatech!kd4nc!vdbsan!brian
kirkenda@eecs.cs.pdx.edu (Steve Kirkendall) (09/17/90)
In article <114@vdbsan.UUCP> brian@vdbsan.UUCP (Brian Bainter) writes: >Can anyone tell me what the hell a "Broken stack frame" message from the >debugger is telling me. I have a program that keeps aborting at odd times >and when I bring the thing in to the debugger, all I get is a broken stack >frame message and no idea where or what aborted the program. A "stack frame" is the mechanism that is used to allocate space for local variables on the stack. The CPU has a register called a "frame pointer" that points to the base address of the local variables. This is the "bp" register in 80x86 chips, and usually the A6 register in 680x0 chips. A subroutine call pushes the arguments, the return address, and the frame pointer onto the stack. It then loads the frame pointer with the value of the stack pointer, and decrements the stack pointer to allocate space for local variables. A stack frame is "broken" when either the return address or the old frame pointer fields have been clobbered. The easiest way to clobber those fields is to declare a local array, and then write past the end of the array. /* This function will have a broken stack frame if it ever * * encounters a line that is more than 79 characters long. */ scum() { char buf[80]; gets(buf); } The debugger can't display a stack trace because it needs a healthy set of frame pointers to follow. You might try running `adb' and giving it the "?" command. This *may* tell you which function it was trying to return from. ------------------------------------------------------------------------------- Steve Kirkendall kirkenda@cs.pdx.edu uunet!tektronix!psueea!eecs!kirkenda ------------------------------------------------------------------------------- Steve Kirkendall kirkenda@cs.pdx.edu uunet!tektronix!psueea!eecs!kirkenda
josef@nixpbe.UUCP (Moellers) (09/18/90)
In <114@vdbsan.UUCP> brian@vdbsan.UUCP (Brian Bainter) writes: >Can anyone tell me what the hell a "Broken stack frame" message from the >debugger is telling me. I have a program that keeps aborting at odd times >and when I bring the thing in to the debugger, all I get is a broken stack >frame message and no idea where or what aborted the program. Stack frames usually are linked together, so that when the current function returns, the machine can find the previous frame. This is done through what is called the "Frame Pointer", a machine register that points at a fixed place in the current stack frame. The following is a list of processors and the registers they use as Frame Pointers: 80386: BP, 68K: a6, 32K: FP; VAX: FP, PDP-11: r5 Mostly, the (old) Frame Pointer is saved on the stack and the new frame pointer is set up to point to the old Frame Pointer (the following is pseudo-code, any resemblance with actual code is ...): func: push FP move SP,FP sub #nnn,SP (This code assumes that the Stack Pointer points to the last used entry). The format of a stack frame usually is: | arguments | +-----------+ | old PC | +-----------+ FP----->| old FP | +------------+ | locals | +-----------+ | | So much for the introduction. When a debugger is started, it tries to follow the Frame-Pointer-links from Stack-Frame to Stack-Frame in order to find the calling sequence and probably the arguments to the functions/procedures/subroutines. It starts with the current FP, and the current PC, then locates the "old PC" which identifies the calling function and via "old FP" that function's stack frame. this goes on until the debugger finds some (predefined!) value in "old FP" (usually 0), which identifies the top stack frame (in C this is often "main"'s stack frame). If, however, the debugger finds an "old FP" which is e.g. less than the current one (assuming a stack growth downward from high core), or odd (in the case of a 68000, 68010, PDP-11), then it will report "Broken Stack Frame". What usually has happened is, that a function has written to a local variable which is too small: e.g. a character array which is too short (Hello, ARPANET worm!!!). This may be the reason for Your program's misbehaviour. What I have done once in a case like this is to start with "main", whose stack frame often is at a predefined address just below the "argc, argv, envp" trio. Then using the information on how many local variables "main" allocates find main's callee's stack frame. In that frame I can find the return address (old PC) which gives me the name of the function called (unless it is an indirect call, e.g. (*funcp)(a,b,c)), and that function's Frame pointer which must match "main"'s stack frame, and so on. This is tedious and requires some knowledege of compiler internals, but in my case it was the last resort. Hope this helps, -- | Josef Moellers | c/o Nixdorf Computer AG | | USA: mollers.pad@nixdorf.com | Abt. PXD-S14 | | !USA: mollers.pad@nixdorf.de | Heinz-Nixdorf-Ring | | Phone: (+49) 5251 104662 | D-4790 Paderborn |