summaryrefslogtreecommitdiff
path: root/buildscripts/gdb/mongo_printers.py
diff options
context:
space:
mode:
Diffstat (limited to 'buildscripts/gdb/mongo_printers.py')
-rw-r--r--buildscripts/gdb/mongo_printers.py123
1 files changed, 76 insertions, 47 deletions
diff --git a/buildscripts/gdb/mongo_printers.py b/buildscripts/gdb/mongo_printers.py
index 6c6d39e5ec7..6d1a5272d58 100644
--- a/buildscripts/gdb/mongo_printers.py
+++ b/buildscripts/gdb/mongo_printers.py
@@ -1,24 +1,24 @@
-"""GDB Pretty-printers for MongoDB
-"""
+"""GDB Pretty-printers for MongoDB."""
from __future__ import print_function
-import gdb.printing
import struct
import sys
+import gdb.printing
+
try:
import bson
import bson.json_util
import collections
from bson.codec_options import CodecOptions
-except ImportError as e:
+except ImportError as err:
print("Warning: Could not load bson library for Python '" + str(sys.version) + "'.")
print("Check with the pip command if pymongo 3.x is installed.")
bson = None
def get_unique_ptr(obj):
- """Read the value of a libstdc++ std::unique_ptr"""
+ """Read the value of a libstdc++ std::unique_ptr."""
return obj["_M_t"]['_M_head_impl']
@@ -30,13 +30,14 @@ def get_unique_ptr(obj):
class StatusPrinter(object):
- """Pretty-printer for mongo::Status"""
- OK = 0 # ErrorCodes::OK
+ """Pretty-printer for mongo::Status."""
def __init__(self, val):
+ """Initialize StatusPrinter."""
self.val = val
def to_string(self):
+ """Return status for printing."""
if not self.val['_error']:
return 'Status::OK()'
@@ -49,13 +50,15 @@ class StatusPrinter(object):
return 'Status(%s, %s)' % (code, reason)
-class StatusWithPrinter:
- """Pretty-printer for mongo::StatusWith<>"""
+class StatusWithPrinter(object):
+ """Pretty-printer for mongo::StatusWith<>."""
def __init__(self, val):
+ """Initialize StatusWithPrinter."""
self.val = val
def to_string(self):
+ """Return status for printing."""
if not self.val['_status']['_error']:
return 'StatusWith(OK, %s)' % (self.val['_t'])
@@ -69,27 +72,31 @@ class StatusWithPrinter:
return 'StatusWith(%s, %s)' % (code, reason)
-class StringDataPrinter:
- """Pretty-printer for mongo::StringData"""
+class StringDataPrinter(object):
+ """Pretty-printer for mongo::StringData."""
def __init__(self, val):
+ """Initialize StringDataPrinter."""
self.val = val
- def display_hint(self):
+ @staticmethod
+ def display_hint():
+ """Display hint."""
return 'string'
def to_string(self):
+ """Return data for printing."""
size = self.val["_size"]
if size == -1:
return self.val['_data'].lazy_string()
- else:
- return self.val['_data'].lazy_string(length=size)
+ return self.val['_data'].lazy_string(length=size)
-class BSONObjPrinter:
- """Pretty-printer for mongo::BSONObj"""
+class BSONObjPrinter(object):
+ """Pretty-printer for mongo::BSONObj."""
def __init__(self, val):
+ """Initialize BSONObjPrinter."""
self.val = val
self.ptr = self.val['_objdata'].cast(gdb.lookup_type('void').pointer())
# Handle the endianness of the BSON object size, which is represented as a 32-bit integer
@@ -101,10 +108,13 @@ class BSONObjPrinter:
else:
self.size = struct.unpack('<I', inferior.read_memory(self.ptr, 4))[0]
- def display_hint(self):
+ @staticmethod
+ def display_hint():
+ """Display hint."""
return 'map'
def children(self):
+ """Children."""
# Do not decode a BSONObj with an invalid size.
if not bson or self.size < 5 or self.size > 17 * 1024 * 1024:
return
@@ -114,11 +124,12 @@ class BSONObjPrinter:
options = CodecOptions(document_class=collections.OrderedDict)
bsondoc = bson.BSON.decode(buf, codec_options=options)
- for k, v in bsondoc.items():
- yield 'key', k
- yield 'value', bson.json_util.dumps(v)
+ for key, val in bsondoc.items():
+ yield 'key', key
+ yield 'value', bson.json_util.dumps(val)
def to_string(self):
+ """Return BSONObj for printing."""
# The value has been optimized out.
if self.size == -1:
return "BSONObj @ %s" % (self.ptr)
@@ -132,29 +143,33 @@ class BSONObjPrinter:
if size == 5:
return "%s empty BSONObj @ %s" % (ownership, self.ptr)
- else:
- return "%s BSONObj %s bytes @ %s" % (ownership, size, self.ptr)
+ return "%s BSONObj %s bytes @ %s" % (ownership, size, self.ptr)
-class UnorderedFastKeyTablePrinter:
- """Pretty-printer for mongo::UnorderedFastKeyTable<>"""
+class UnorderedFastKeyTablePrinter(object):
+ """Pretty-printer for mongo::UnorderedFastKeyTable<>."""
def __init__(self, val):
+ """Initialize UnorderedFastKeyTablePrinter."""
self.val = val
# Get the value_type by doing a type lookup
- valueTypeName = val.type.strip_typedefs().name + "::value_type"
- valueType = gdb.lookup_type(valueTypeName).target()
- self.valueTypePtr = valueType.pointer()
+ value_type_name = val.type.strip_typedefs().name + "::value_type"
+ value_type = gdb.lookup_type(value_type_name).target()
+ self.value_type_ptr = value_type.pointer()
- def display_hint(self):
+ @staticmethod
+ def display_hint():
+ """Display hint."""
return 'map'
def to_string(self):
+ """Return UnorderedFastKeyTablePrinter for printing."""
return "UnorderedFastKeyTablePrinter<%s> with %s elems " % (
self.val.type.template_argument(0), self.val["_size"])
def children(self):
+ """Children."""
cap = self.val["_area"]["_hashMask"] + 1
it = get_unique_ptr(self.val["_area"]["_entries"])
end = it + cap
@@ -168,16 +183,17 @@ class UnorderedFastKeyTablePrinter:
if not elt['_used']:
continue
- value = elt['_data']["__data"].cast(self.valueTypePtr).dereference()
+ value = elt['_data']["__data"].cast(self.value_type_ptr).dereference()
yield ('key', value['first'])
yield ('value', value['second'])
-class DecorablePrinter:
- """Pretty-printer for mongo::Decorable<>"""
+class DecorablePrinter(object):
+ """Pretty-printer for mongo::Decorable<>."""
def __init__(self, val):
+ """Initialize DecorablePrinter."""
self.val = val
decl_vector = val["_decorations"]["_registry"]["_decorationInfo"]
@@ -187,14 +203,18 @@ class DecorablePrinter:
decinfo_t = gdb.lookup_type('mongo::DecorationRegistry::DecorationInfo')
self.count = int((int(finish) - int(self.start)) / decinfo_t.sizeof)
- def display_hint(self):
+ @staticmethod
+ def display_hint():
+ """Display hint."""
return 'map'
def to_string(self):
+ """Return Decorable for printing."""
return "Decorable<%s> with %s elems " % (self.val.type.template_argument(0), self.count)
def children(self):
- decorationData = get_unique_ptr(self.val["_decorations"]["_decorationData"])
+ """Children."""
+ decoration_data = get_unique_ptr(self.val["_decorations"]["_decorationData"])
for index in range(self.count):
descriptor = self.start[index]
@@ -215,19 +235,20 @@ class DecorablePrinter:
# Cast the raw char[] into the actual object that is stored there.
type_t = gdb.lookup_type(type_name)
- obj = decorationData[dindex].cast(type_t)
+ obj = decoration_data[dindex].cast(type_t)
yield ('key', "%d:%s:%s" % (index, obj.address, type_name))
yield ('value', obj)
def find_match_brackets(search, opening='<', closing='>'):
- """Returns the index of the closing bracket that matches the first opening bracket.
- Returns -1 if no last matching bracket is found, i.e. not a template.
+ """Return the index of the closing bracket that matches the first opening bracket.
+
+ Return -1 if no last matching bracket is found, i.e. not a template.
- Example:
- 'Foo<T>::iterator<U>''
- returns 5
+ Example:
+ 'Foo<T>::iterator<U>''
+ returns 5
"""
index = search.find(opening)
if index == -1:
@@ -237,11 +258,11 @@ def find_match_brackets(search, opening='<', closing='>'):
count = 1
str_len = len(search)
for index in range(start, str_len):
- c = search[index]
+ char = search[index]
- if c == opening:
+ if char == opening:
count += 1
- elif c == closing:
+ elif char == closing:
count -= 1
if count == 0:
@@ -251,9 +272,10 @@ def find_match_brackets(search, opening='<', closing='>'):
class MongoSubPrettyPrinter(gdb.printing.SubPrettyPrinter):
- """Sub pretty printer managed by the pretty-printer collection"""
+ """Sub pretty printer managed by the pretty-printer collection."""
def __init__(self, name, prefix, is_template, printer):
+ """Initialize MongoSubPrettyPrinter."""
super(MongoSubPrettyPrinter, self).__init__(name)
self.prefix = prefix
self.printer = printer
@@ -262,16 +284,20 @@ class MongoSubPrettyPrinter(gdb.printing.SubPrettyPrinter):
class MongoPrettyPrinterCollection(gdb.printing.PrettyPrinter):
"""MongoDB-specific printer printer collection that ignores subtypes.
+
It will match 'HashTable<T> but not 'HashTable<T>::iterator' when asked for 'HashTable'.
"""
def __init__(self):
+ """Initialize MongoPrettyPrinterCollection."""
super(MongoPrettyPrinterCollection, self).__init__("mongo", [])
def add(self, name, prefix, is_template, printer):
+ """Add a subprinter."""
self.subprinters.append(MongoSubPrettyPrinter(name, prefix, is_template, printer))
def __call__(self, val):
+ """Return matched printer type."""
# Get the type name.
lookup_tag = gdb.types.get_basic_type(val.type).tag
@@ -286,15 +312,18 @@ class MongoPrettyPrinterCollection(gdb.printing.PrettyPrinter):
# We do not want HashTable<T>::iterator as an example, just HashTable<T>
if index == -1 or index + 1 == len(lookup_tag):
for printer in self.subprinters:
- if printer.enabled and (
- (printer.is_template and lookup_tag.find(printer.prefix) == 0) or
- (not printer.is_template and lookup_tag == printer.prefix)):
- return printer.printer(val)
+ if not printer.enabled:
+ continue
+ if ((not printer.is_template or lookup_tag.find(printer.prefix) != 0)
+ and (printer.is_template or lookup_tag != printer.prefix)):
+ continue
+ return printer.printer(val)
return None
def build_pretty_printer():
+ """Build a pretty printer."""
pp = MongoPrettyPrinterCollection()
pp.add('BSONObj', 'mongo::BSONObj', False, BSONObjPrinter)
pp.add('Decorable', 'mongo::Decorable', True, DecorablePrinter)