This page was produced by an automated import process, and may have formatting errors; feel free to fix.

Analyzing Stacks—Frame Sniffers

When a program stops, GDB needs to construct the chain of struct frame_info representing the state of the stack using appropriate sniffers.

Each architecture requires appropriate sniffers, but they do not form entries in struct gdbarch, since more than one sniffer may be required and a sniffer may be suitable for more than one struct gdbarch. Instead sniffers are associated with architectures using the following functions.

These functions all take a reference to struct gdbarch, so they are associated with a specific architecture. They are usually called in the gdbarch initialization function, after the gdbarch struct has been set up. Unless a default has been set, the most recently appended sniffer will be tried first.

The main frame unwinding sniffer (as set by frame_unwind_append_sniffer) returns a structure specifying a set of sniffing functions:

struct frame_unwind
{
   enum frame_type            type;
   frame_this_id_ftype       *this_id;
   frame_prev_register_ftype *prev_register;
   const struct frame_data   *unwind_data;
   frame_sniffer_ftype       *sniffer;
   frame_prev_pc_ftype       *prev_pc;
   frame_dealloc_cache_ftype *dealloc_cache;
};

The type field indicates the type of frame this sniffer can handle: normal, dummy (see Functions Creating Dummy Frames), signal handler or sentinel. Signal handlers sometimes have their own simplified stack structure for efficiency, so may need their own handlers.

The unwind_data field holds additional information which may be relevant to particular types of frame. For example it may hold additional information for signal handler frames.

The remaining fields define functions that yield different types of information when given a pointer to the NEXT stack frame. Not all functions need be provided. If an entry is NULL, the next sniffer will be tried instead.

In general it is only the this_id and prev_register fields that need be defined for custom sniffers.

The frame base sniffer is much simpler. It is a struct frame_base, which refers to the corresponding frame_unwind struct and whose fields refer to functions yielding various addresses within the frame.

struct frame_base
{
   const struct frame_unwind *unwind;
   frame_this_base_ftype     *this_base;
   frame_this_locals_ftype   *this_locals;
   frame_this_args_ftype     *this_args;
};

All the functions referred to take a pointer to the NEXT frame as argument. The function referred to by this_base returns the base address of THIS frame, the function referred to by this_locals returns the base address of local variables in THIS frame and the function referred to by this_args returns the base address of the function arguments in this frame.

As described above, the base address of a frame is the address immediately before the start of the NEXT frame. For a falling stack, this is the lowest address in the frame and for a rising stack it is the highest address in the frame. For most architectures the same address is also the base address for local variables and arguments, in which case the same function can be used for all three entries [DOCF6 6].

Footnotes

[FOOT6 (6)]

It is worth noting that if it cannot be determined in any other way (for example by there being a register with the name "fp"), then the result of the this_base function will be used as the value of the frame pointer variable $fp in GDB. This is very often not correct (for example with the OpenRISC 1000, this value is the stack pointer, $sp). In this case a register (raw or pseudo) with the name "fp" should be defined. It will be used in preference as the value of $fp.

None: Internals Analyzing-Stacks_002d_002d_002dFrame-Sniffers (last edited 2013-08-20 23:40:19 by StanShebs)

All content (C) 2008 Free Software Foundation. For terms of use, redistribution, and modification, please see the WikiLicense page.