From 066eb309594c6d034956929eff4e9cfc0475c94f Mon Sep 17 00:00:00 2001 From: Vicent Marti Date: Fri, 25 Mar 2016 17:12:11 +0100 Subject: [PATCH] table: Implement a StackWalker for StackTrace tables The StackWalker iterator lets us call `stack_trace.walk(id)` to iterate through the addresses in any given stack. The constructor of this iterator takes an optional `resolver` to convert the addresses in the iterator into symbols (or to format them according to the users' needs). --- src/python/bcc/table.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/python/bcc/table.py b/src/python/bcc/table.py index c33cb39..70ef973 100644 --- a/src/python/bcc/table.py +++ b/src/python/bcc/table.py @@ -412,9 +412,37 @@ class PerCpuArray(ArrayBase): raise Exception("Unsupported") class StackTrace(TableBase): + MAX_DEPTH = 127 + def __init__(self, *args, **kwargs): super(StackTrace, self).__init__(*args, **kwargs) + class StackWalker(object): + def __init__(self, stack, resolve=None): + self.stack = stack + self.n = -1 + self.resolve = resolve + + def __iter__(self): + return self + + def __next__(self): + return self.next() + + def next(self): + self.n += 1 + if self.n == StackTrace.MAX_DEPTH: + raise StopIteration() + + addr = self.stack.ip[self.n] + if addr == 0 : + raise StopIteration() + + return self.resolve(addr) if self.resolve else addr + + def walk(self, stack_id, resolve=None): + return StackTrace.StackWalker(self[self.Key(stack_id)], resolve) + def __len__(self): i = 0 for k in self: i += 1 -- 2.7.4