LinuxDump.BTstack
- Module for working with stacks¶
This module contains Python code built on pykdump.API
that can help with
loading and analyzing stacks. Currently, it is implemented by running the crash
bt
comand and parsing its results. However, this could be replaced with a
more efficient method in the future.
Below are presented some common actions you can perform with this module:
Load the current stack:
stack = LinuxDump.BTstack.exec_bt('bt', MEMOIZE=False)[0]
Load the stack of a given PID:
stack = LinuxDump.BTstack.exec_bt('bt PID')[0]
Group and report every stack on the system:
allstacks = LinuxDump.BTstack.exec_bt('foreach bt')
tt = LinuxDump.Tasks.TaskTable()
LinuxDump.BTstack.bt_merge_stacks(allstacks, tt=tt)
List PIDs which may be executing a function:
finder = LinuxDump.BTstack.fastSubroutineStacks()
maybe_doing_read = finder.find_pids_byfuncname('sys_read')
Types¶
- class LinuxDump.BTstack.BTStack¶
The
BTStack
represents a single backtrace stack. This class should not be constructed manually. Instead, it should be created via theexec_bt()
function.- frames: list[BTFrame]¶
A list of stack frames (as
BTFrame
) within this stack. The list is ordered most recent first.
- hasfunc(self, func, reverse=False)¶
Tells whether this stack contains the given function, and where.
Returns false when the stack does not contain the function. When the stack does contain the function, returns a 2-tuple giving information about its location. The first element of the tuple is the frame index, and the second element is the matched portion of the function name (as
func
is treated as a regexp). Whenreverse
is True, find the last stack frame rather than the first.Note
Note that when using
reverse=True
, the frame index returned from this function is also reversed. That is, the last frame of the stack would have index 0.- Parameters:
- Returns:
False when not found. When found, returns a tuple of (frame index, matched function name).
- Return type:
- getSimpleSignature(self)¶
Return a string "signature" which identifies which functions are called in this stack. The signature does not include offsets, which identify /exactly/ where a function was called.
- Returns:
A string like:
function_one/function_two/function_three
- Return type:
- getFullSignature(self)¶
Return a string "signature" which identifies not just the functions that are called in this stack, but also offsets, indices, and any data in the stack frame.
- Returns:
A long string containing the
repr()
of every frame- Return type:
- class LinuxDump.BTstack.BTFrame¶
This class represents a single frame on the stack. Each attribute of this class is populated by the
bt
output. When fields are not present, a default value of-1
(for integers) or''
(for strings) is stored.This class is not typically created by a user; instead it is returned by
exec_bt()
or another function of this module.- level: int¶
At what index into the stack is this frame? The most recent stack frame has a level of 0.
Note
This index is reported by crash. (e.g.
#0 [addr] ...
). For some frames (such as exception frames), there is no index, and this remains at its default value of -1. Frames occurring after this in the backtrace will be offset. If you wish to have a reliable value, use the index in theBTStack.frames
list.
- frame: int¶
The address of the return address within the stack, which is nearly (but not exactly) the frame pointer.
- via: str¶
Some stack frames include entries like
error code (via page_fault) at ...
. This attribute contains the text of this field, or a default of the empty string if it does not exist.
- offset: int¶
The offset of the return address within the function being executed. For example, the return address of a function might be represented as
sys_mprotect+0x16b
. In this return address,sys_mprotect
is the function, and0x16b
is the offset from that function. The actual address could be computed viasym2addr(frame.func) + frame.addr
.
- data: list[str]¶
The data field is a list (potentially empty) of any lines of text which occur in the backtrace text following the stack frame line. Each line is a string within the list, and the strings do not contain trailing newlines.
One sort of data that may occur in this field is a register dump from a system call or exception. Another sort of data may be the stack contents, if this frame came from a
bt -f
command.
- simplerepr(self)¶
Return a simple string representation of this frame, showing only its index and the function name.
- Return type:
- class LinuxDump.BTstack.fastSubroutineStacks¶
This object can be used to search for stacks that are executing a certain function. On creation, this class needs to load a lot of data for the search, but once created, the returned object can be used multiple times to identify tasks that may be executing a current function:
finder = fastSubroutineStacks() maybe_doing_read = finder.find_pids_byfuncname('sys_read') maybe_selecting = finder.find_pids_byfuncname('sys_select')
- find_pids_byfuncname(self, funcnames):
Use this instance's indexed task data to search for stacks that may be executing functions.
- Parameters:
funcnames (str or regexp) -- Either a string or a compiled regular expression. If it is a string, then it may be specified like:
function_one|function_two
. That is, multiple functions may be listed, separated by a pipe character. If the argument is a regular expression, then we search for stacks executing a function which matches that regexp.- Returns:
A set of pids. This set simply contains pids that appear to be executing this function (because
bt -t
reported that symbol on the stack). There may be false positives! UseverifyFastSet()
to remove any false positives by actually parsing the stacks for each PID.- Return type:
Functions¶
- LinuxDump.BTstack.exec_bt(crashcmd=None, text=None, bg=False, MEMOIZE=True)¶
Create (potentially multiple)
BTStack
instances by running a command or parsing text.This function either executes the crash command
crashcmd
and parses the resulting stack descriptions, or it directly parses the text given intext
. Eithercrashcmd
ortext
must be specified.Using this function to retrieve the current task's backtrace:
stack = exec_bt('bt', MEMOIZE=False)[0]
Using this function to retrieve backtraces from every CPU:
stack_list = exec_bt('bt -a')
- Parameters:
crashcmd (str) -- A crash command to execute that will return a backtrace, e.g.
bt PID
orbt -a
.text (str) -- Text which contains a backtrace already.
bg (bool) -- Whether we should use
exec_crash_command_bg()
to executecrashcmd
in the background. This is mainly useful if the command execution will take a long time and may need to be timed out. Commands which containforeach
or-a
are automatically run in the background.MEMOIZE (bool) -- Should the result of this function be cached? This should be set to False when using
text
to parse an existing string, since parsing is fast and need not waste cache space. This should also be set to False when executing a command whose output may change, such asbt
(as the output would change if the current PID is updated withset
).
- LinuxDump.BTstack.bt_mergestacks(btlist, precise=False, count=1, reverse=False, tt=None, verbose=0)¶
Group stacks based on their signature and display counts for each one.
Given a list of
BTStack
's, identify and group which ones involve the same function calls, and print a report for all grouped stacks.Example: group and analyze all stacks of a vmcore:
from LinuxDump.BTstack import exec_bt, bt_mergestacks from LinuxDump.Tasks import TaskTable allstacks = exec_bt('foreach bt') tt = TaskTable() bt_merge_stacks(allstacks, tt=tt)
This code could produce sample output such as:
------- 56 stacks like that: ---------- #0 __schedule #1 schedule #2 do_nanosleep #3 hrtimer_nanosleep #4 sys_nanosleep #5 system_call_fastpath youngest=0s(pid=1234), oldest=81036s(pid=5678) ........................ command_1 2 times command_2 1 times command_3 1 times command_4 52 times
- Parameters:
precise (bool) -- When True, use
BTStack.getFullSignature()
to compare stacks. The default (False) is to useBTStack.getSimpleSignature()
.count (int) -- Only report groups that have at least this many members.
reverse (bool) -- When True, report groups in descending order (by member count). The default (False) is to report in ascending order.
tt (LinuxDump.Tasks.TaskTable) -- An optional
LinuxDump.Tasks.TaskTable
object that may be used to provide additional information about groups (youngest and oldest in the sample output above).verbose (int) -- Specify verbose=1 (or True) in order to output a list of PIDs for each group.
- LinuxDump.BTstack.verifyFastSet(dset, func)¶
Remove false positives from a set of PIDs that may be executing a function.
Given a set of PIDs (e.g., returned from
fastSubroutineStacks.find_pids_byfuncname()
), load each stack and verify that the PID is actually executingfunc
. If not, remove that pid fromdset
.- Parameters:
func (str or regexp) -- A string (or regexp) to test whether it is contained by a stack. This parameter is interpreted by
BTStack.hasfunc()
; see the documentation of that method for further details.