Skip to content

Instantly share code, notes, and snippets.

@awreece
Created December 29, 2016 22:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save awreece/ed5dc3f668dc8fe5133a5945876a3f8f to your computer and use it in GitHub Desktop.
Save awreece/ed5dc3f668dc8fe5133a5945876a3f8f to your computer and use it in GitHub Desktop.
import gdb
from datetime import datetime
import sys
if sys.version_info > (3, 0):
raw_input = input
#
# The gdb constant COMPLETE_EXPRESSION was added in gdb 7.7. For earlier
# version of gdb, we use COMPLETE_SYMBOL which is close enough.
#
if gdb.VERSION < "7.7":
gdb.COMPLETE_EXPRESSION = gdb.COMPLETE_SYMBOL
def read_command_lines():
#
# The gdb commands that allow the user to specify multiple commands (e.g.
# breakpoint commands) call the C `read_command_lines` function.
# Unfortunately, the gdb python interface does not appear to provide a way
# to call this function.
#
ret = []
gdb.write('End with a line saying just "end".\n')
line = raw_input(">")
while line != "end":
ret.append(line)
line = raw_input(">")
return ret
def LockFreeSListWalk(lfsl, clazz, node_field, filter=lambda _: True, forbidden_bits = 0x1):
curr = lfsl['m_head']
while curr['m_next']['v_'] != 0:
gdb.execute("set $_ = ('%s' *)%s" % (clazz, str(curr['m_next']['v_'] & ~0x7)))
gdb.execute("set $__ = *$_")
val = gdb.parse_and_eval("$_")
if curr['m_next']['v_'] & forbidden_bits == 0:
if filter(val):
yield val
curr = val[node_field]
def LockFreeHashTableWalk(lfht, clazz, node_field, filter=lambda _: True, forbidden_bits = 0x1):
for bi in range(int(lfht['m_bucketCount'])):
for v in LockFreeSListWalk(lfht['m_hashBuckets'][bi], clazz,
node_field, filter, forbidden_bits):
yield v
class LockFreeHashTableWalkCommand(gdb.Command):
"""Print all entries in a LockFreeHashTable.
If an optional filter is used, $_ and $__ can be used in the filter
expression to reference the instance.
Usage:
lfht-walk <type> <node> [if <filter>]
Example:
(gdb) lfht-walk m_hashTable VersionedCachedTableEntry m_node
"""
def __init__(self):
super(LockFreeHashTableWalkCommand, self).__init__(
"lfht-walk", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION)
def invoke(self, argument, from_tty):
args = gdb.string_to_argv(argument)
if (len(args) < 3 or (len(args) > 3 and args[3] != "if")):
raise gdb.GdbError("Usage: <val> <class> <node> [if <filter>]")
val, clazz, node = args[:3]
val = gdb.parse_and_eval(val)
_filter = lambda _: True
if len(args) > 3:
_filter = lambda _: bool(gdb.parse_and_eval(" ".join(args[4:])))
for v in LockFreeHashTableWalk(val, clazz, node, _filter):
gdb.write("(('%s'*)%s\n" % (clazz, v))
self.dont_repeat()
LockFreeHashTableWalkCommand()
class LockFreeHashTableWalkCommandsCommand(gdb.Command):
"""Execute the given commands on all values in a LockFreeHashTable.
The commands can reference the values via $_ and $__.
If an optional filter is used, $_ and $__ can be used in the filter
expression to reference the values.
Usage:
lfht-walk-commands <val> <type> <node> [if <filter>]
Example:
(gdb) lfht-walk-commands m_hashTable VersionedCachedTableEntry m_node
Type commands to execute for each (matched) instance.
End with a line saying just "end".
>print $_->m_cte->m_key.tableName
>end
"""
def __init__(self):
super(LockFreeHashTableWalkCommandsCommand, self).__init__(
"lfht-walk-commands", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION)
def invoke(self, argument, from_tty):
args = gdb.string_to_argv(argument)
if (len(args) < 3 or (len(args) > 3 and args[3] != "if")):
raise gdb.GdbError("Usage: <val> <class> <node> [if <filter>]")
val, clazz, node = args[:3]
val = gdb.parse_and_eval(val)
_filter = lambda _: True
if len(args) > 3:
_filter = lambda _: bool(gdb.parse_and_eval(" ".join(args[4:])))
gdb.write("Type commands to execute for each (matched) value.\n")
commands = read_command_lines()
for _ in LockFreeHashTableWalk(val, clazz, node, _filter):
for command in commands:
gdb.execute(command)
self.dont_repeat()
LockFreeHashTableWalkCommandsCommand()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment