diff options
author | Daniel Gottlieb <daniel.gottlieb@mongodb.com> | 2018-07-19 14:34:19 -0400 |
---|---|---|
committer | Daniel Gottlieb <daniel.gottlieb@mongodb.com> | 2018-07-19 14:34:19 -0400 |
commit | 71750f6060da2a48686c7835a65e95179d856e4f (patch) | |
tree | a165a9e77a0dfdc405c03ac1c79930a7ad891799 /buildscripts/gdb | |
parent | 6ea23db0a643fbd64e3f653108900915fc04f9e0 (diff) | |
download | mongo-71750f6060da2a48686c7835a65e95179d856e4f.tar.gz |
SERVER-36167: Add flags pretty printing for WT session/txn/cursor.
Diffstat (limited to 'buildscripts/gdb')
-rw-r--r-- | buildscripts/gdb/mongo_printers.py | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/buildscripts/gdb/mongo_printers.py b/buildscripts/gdb/mongo_printers.py index 20e340044e5..6876b69aa6c 100644 --- a/buildscripts/gdb/mongo_printers.py +++ b/buildscripts/gdb/mongo_printers.py @@ -1,6 +1,7 @@ """GDB Pretty-printers for MongoDB.""" from __future__ import print_function +import re import struct import sys @@ -243,6 +244,133 @@ class DecorablePrinter(object): yield ('value', obj) +def _get_flags(flag_val, flags): + """ + Return a list of flag name strings. + + `flags` is a list of `(flag_name, flag_value)` pairs. The list must be in sorted in order of the + highest `flag_value` first and the lowest last. + """ + if not flags: + return "Flags not parsed from source." + + ret = [] + for name, hex_val in flags: + dec_val = int(hex_val, 16) + if flag_val < dec_val: + continue + + ret.append(name) + flag_val -= dec_val + + return ret + + +class WtCursorPrinter(object): + """ + Pretty-printer for WT_CURSOR objects. + + Complement the `flags: int` field with the macro names used in the source code. + """ + + try: + with open("./src/third_party/wiredtiger/src/include/wiredtiger.in") as wiredtiger_header: + file_contents = wiredtiger_header.read() + cursor_flags_re = re.compile(r"#define\s+WT_CURSTD_(\w+)\s+0x(\d+)u") + cursor_flags = cursor_flags_re.findall(file_contents)[::-1] + except IOError: + cursor_flags = [] + + def __init__(self, val): + """Initializer.""" + self.val = val + + # pylint: disable=R0201 + def to_string(self): + """to_string.""" + return None + + def children(self): + """children.""" + for field in self.val.type.fields(): + field_val = self.val[field.name] + if field.name == "flags": + yield ("flags", "{} ({})".format(field_val, + str(_get_flags(field_val, self.cursor_flags)))) + else: + yield (field.name, field_val) + + +class WtSessionImplPrinter(object): + """ + Pretty-printer for WT_SESSION_IMPL objects. + + Complement the `flags: int` field with the macro names used in the source code. + """ + + try: + with open("./src/third_party/wiredtiger/src/include/session.h") as session_header: + file_contents = session_header.read() + session_flags_re = re.compile(r"#define\s+WT_SESSION_(\w+)\s+0x(\d+)u") + session_flags = session_flags_re.findall(file_contents)[::-1] + except IOError: + session_flags = [] + + def __init__(self, val): + """Initializer.""" + self.val = val + + # pylint: disable=R0201 + def to_string(self): + """to_string.""" + return None + + def children(self): + """children.""" + for field in self.val.type.fields(): + field_val = self.val[field.name] + if field.name == "flags": + yield ("flags", "{} ({})".format(field_val, + str(_get_flags(field_val, self.session_flags)))) + else: + yield (field.name, field_val) + + +class WtTxnPrinter(object): + """ + Pretty-printer for WT_TXN objects. + + Complement the `flags: int` field with the macro names used in the source code. + """ + + try: + with open("./src/third_party/wiredtiger/src/include/txn.h") as txn_header: + file_contents = txn_header.read() + txn_flags_re = re.compile(r"#define\s+WT_TXN_(\w+)\s+0x(\d+)u") + txn_flags = txn_flags_re.findall(file_contents)[::-1] + except IOError: + txn_flags = [] + + def __init__(self, val): + """Initializer.""" + self.val = val + + # pylint: disable=R0201 + def to_string(self): + """to_string.""" + return None + + def children(self): + """children.""" + for field in self.val.type.fields(): + field_val = self.val[field.name] + if field.name == "flags": + yield ("flags", "{} ({})".format(field_val, + str(_get_flags(field_val, self.txn_flags)))) + else: + yield (field.name, field_val) + + def find_match_brackets(search, opening='<', closing='>'): """Return the index of the closing bracket that matches the first opening bracket. @@ -334,6 +462,9 @@ def build_pretty_printer(): pp.add('StringData', 'mongo::StringData', False, StringDataPrinter) pp.add('UnorderedFastKeyTable', 'mongo::UnorderedFastKeyTable', True, UnorderedFastKeyTablePrinter) + pp.add('__wt_cursor', '__wt_cursor', False, WtCursorPrinter) + pp.add('__wt_session_impl', '__wt_session_impl', False, WtSessionImplPrinter) + pp.add('__wt_txn', '__wt_txn', False, WtTxnPrinter) return pp |