diff options
Diffstat (limited to 'gdb/doc/python.texi')
-rw-r--r-- | gdb/doc/python.texi | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index d725eb0..098d718 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -144,6 +144,7 @@ optional arguments while skipping others. Example: * Frame Filter API:: Filtering Frames. * Frame Decorator API:: Decorating Frames. * Writing a Frame Filter:: Writing a Frame Filter. +* Unwinding Frames in Python:: Writing frame unwinder. * Xmethods In Python:: Adding and replacing methods of C++ classes. * Xmethod API:: Xmethod types. * Writing an Xmethod:: Writing an xmethod. @@ -2178,6 +2179,148 @@ printed hierarchically. Another approach would be to combine the marker in the inlined frame, and also show the hierarchical relationship. +@node Unwinding Frames in Python +@subsubsection Unwinding Frames in Python +@cindex unwinding frames in Python + +In @value{GDBN} terminology ``unwinding'' is the process of finding +the previous frame (that is, caller's) from the current one. An +unwinder has three methods. The first one checks if it can handle +given frame (``sniff'' it). For the frames it can sniff an unwinder +provides two additional methods: it can return frame's ID, and it can +fetch registers from the previous frame. A running @value{GDBN} +mantains a list of the unwinders and calls each unwinder's sniffer in +turn until it finds the one that recognizes the current frame. There +is an API to register an unwinder. + +The unwinders that come with @value{GDBN} handle standard frames. +However, mixed language applications (for example, an application +running Java Virtual Machine) sometimes use frame layouts that cannot +be handled by the @value{GDBN} unwinders. You can write Python code +that can handle such custom frames. + +You implement a frame unwinder in Python as a class with which has two +attributes, @code{name} and @code{enabled}, with obvious meanings, and +a single method @code{__call__}, which examines a given frame and +returns an object (an instance of @code{gdb.UnwindInfo class)} +describing it. If an unwinder does not recognize a frame, it should +return @code{None}. The code in @value{GDBN} that enables writing +unwinders in Python uses this object to return frame's ID and previous +frame registers when @value{GDBN} core asks for them. + +@subheading Unwinder Input + +An object passed to an unwinder (a @code{gdb.PendingFrame} instance) +provides a method to read frame's registers: + +@defun PendingFrame.read_register (reg) +This method returns the contents of the register @var{regn} in the +frame as a @code{gdb.Value} object. @var{reg} can be either a +register number or a register name; the values are platform-specific. +They are usually found in the corresponding +@file{@var{platform}-tdep.h} file in the @value{GDBN} source tree. +@end defun + +It also provides a factory method to create a @code{gdb.UnwindInfo} +instance to be returned to @value{GDBN}: + +@defun PendingFrame.create_unwind_info (frame_id) +Returns a new @code{gdb.UnwindInfo} instance identified by given +@var{frame_id}. The argument is used to build @value{GDBN}'s frame ID +using one of functions provided by @value{GDBN}. @var{frame_id}'s attributes +determine which function will be used, as follows: + +@table @code +@item sp, pc, special +@code{frame_id_build_special (@var{frame_id}.sp, @var{frame_id}.pc, @var{frame_id}.special)} + +@item sp, pc +@code{frame_id_build (@var{frame_id}.sp, @var{frame_id}.pc)} + +This is the most common case. + +@item sp +@code{frame_id_build_wild (@var{frame_id}.sp)} +@end table +The attribute values should be @code{gdb.Value} + +@end defun + +@subheading Unwinder Output: UnwindInfo + +Use @code{PendingFrame.create_unwind_info} method described above to +create a @code{gdb.UnwindInfo} instance. Use the following method to +specify caller registers that have been saved in this frame: + +@defun gdb.UnwindInfo.add_saved_register (reg, value) +@var{reg} identifies the register. It can be a number or a name, just +as for the @code{PendingFrame.read_register} method above. +@var{value} is a register value (a @code{gdb.Value} object). +@end defun + +@subheading Unwinder Skeleton Code + +@value{GDBN} comes with the module containing the base @code{Unwinder} +class. Derive your unwinder class from it and structure the code as +follows: + +@smallexample +from gdb.unwinders import Unwinder + +class FrameId(object): + def __init__(self, sp, pc): + self.sp = sp + self.pc = pc + + +class MyUnwinder(Unwinder): + def __init__(....): + supe(MyUnwinder, self).__init___(<expects unwinder name argument>) + + def __call__(pending_frame): + if not <we recognize frame>: + return None + # Create UnwindInfo. Usually the frame is identified by the stack + # pointer and the program counter. + sp = pending_frame.read_register(<SP number>) + pc = pending_frame.read_register(<PC number>) + unwind_info = pending_frame.create_unwind_info(FrameId(sp, pc)) + + # Find the values of the registers in the caller's frame and + # save them in the result: + unwind_info.add_saved_register(<register>, <value>) + .... + + # Return the result: + return unwind_info + +@end smallexample + +@subheading Registering a Unwinder + +An object file, a program space, and the @value{GDBN} proper can have +unwinders registered with it. + +The @code{gdb.unwinders} module provides the function to register a +unwinder: + +@defun gdb.unwinder.register_unwinder (locus, unwinder, replace=False) +@var{locus} is specifies an object file or a program space to which +@var{unwinder} is added. Passing @code{None} or @code{gdb} adds +@var{unwinder} to the @value{GDBN}'s global unwinder list. The newly +added @var{unwinder} will be called before any other unwinder from the +same locus. Two unwinders in the same locus cannot have the same +name. An attempt to add a unwinder with already existing name raises +an exception unless @var{replace} is @code{True}, in which case the +old unwinder is deleted. +@end defun + +@subheading Unwinder Precedence + +@value{GDBN} first calls the unwinders from all the object files in no +particular order, then the unwinders from the current program space, +and finally the unwinders from @value{GDBN}. + @node Xmethods In Python @subsubsection Xmethods In Python @cindex xmethods in Python |