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: [RFC] [PATCH] Provide the ability to write the frame unwinder in Python


Greets Alexander,

One thing I found in your docs:

> +@subheading Returning Previous Frame
> +
> +If sniffer's @code{__call__} method recognizes the frame, it should
> +return a (@var{registers}, @var{frame_id_register_numbers}) tuple.
> +
> +@var{registers} describe the registers that can be unwound (i.e., the
> +registers from the previous frame that have been saved in the current
> +frame described by @var{sniffer_info}). It is a tuple where each
> +element is a (@var{regnum}, @var{regdata}) 2-tuple.  @var{regnum} is
> +a register number, and @var{regdata} is register contents (a
> +@code{gdb.Value} object).
> +
> +@var{frame_id_register_numbers} is a tuple specifying the registers
> +used to construct frame ID of the returned frame.  It is a (@var{sp}),
> +(@var{sp}, @var{pc}) or (@var{sp}, @var{pc}, @var{special}) tuple,
> +where @var{sp}, @var{pc}, @var{special} are register numbers. The
> +referenced registers should be present in @var{registers} tuple. The
> +frame ID is constructed by calling
> +@code{frame_id_build_wild}(@var{value}(@var{sp})),
> +@code{frame_id_build}(@var{value}(@var{sp}), @var{value}(@var{pc})),
> +or @code{frame_id_build}(@var{value}(@var{sp}), @var{value}(@var{pc}),
> +@var{value}(@var{special})) respectively.

The frame_id that the unwinder computes is for THIS, not for PREVIOUS,
so the interface is incorrect if it works as documented.

Here is a section of the docs that I wrote for the Guile side.

   Before getting into the API, we should discuss how unwinders work in
   @value{GDBN}.

   As an example, consider a stack in which we have already computed
   frame 0 and we want to compute frame 1.  We say that frame 0 is the
   ``inner'' frame, and frame 1 will be the ``outer'' frame.

   Unwinding starts with a model of the state of all registers in an
   inner, already unwound frame.  In our case, we start with frame 0.
   @value{GDBN} then constructs a ephemeral frame object for the outer
   frame that is being built (frame 1) and links it to the inner frame
   (frame 0).  @value{GDBN} then goes through its list of registered
   unwinders, searching for one that knows how to unwind the frame.  When
   it finds one, @value{GDBN} will ask the unwinder to compute a frame
   identifier for the outer frame.  Once the unwinder has done so, the
   frame is marked as ``valid'' and can be accessed using the normal
   frame API.

   A frame identifier (frame ID) consists of code and data pointers
   associated with a frame which will remain valid as long as the frame
   is still alive.  Usually a frame ID is a pair of the code and stack
   pointers as they were when control entered the function associated
   with the frame, though as described below there are other ways to
   build a frame ID@.  However as you can see, computing the frame ID
   requires some input from the unwinder to determine the start code
   address (PC) and the frame pointer (FP), especially on platforms that
   don't dedicate a register to the FP.

   (Given this description, you might wonder how the frame ID for the
   innermost frame (frame 0) is unwound, given that unwinding requires an
   inner frame.  The answer is that internally, @value{GDBN} always has a
   ``sentinel'' frame that is inner to the innermost frame, and which has
   a pre-computed unwinder that just returns the registers as they are,
   without unwinding.)

   The Guile frame unwinder API loosely follows this protocol as
   described above.  Guile will build a special ``ephemeral frame
   object'' corresponding the frame being unwound (in our example,
   frame 1).  It allows the user to read registers from that ephemeral
   frame, which in reality are unwound from the already-existing frame
   0.  If the unwinder decides that it can handle the frame in question,
   it then sets the frame ID on the ephemeral frame.  It also records the
   values of any registers saved in the frame, for use when unwinding
   its outer frame (frame 2).

Regards,

Andy


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