summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Gottlieb <daniel.gottlieb@mongodb.com>2021-06-01 16:07:57 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-06-01 20:28:20 +0000
commit87e10cc39920a7aff6283820686de312d4527df8 (patch)
treebd45b224419a3ed347b672dc8344e290be48720b
parent0ec70f6ac70716d9296a014d52e4cc99bf4e5695 (diff)
downloadmongo-87e10cc39920a7aff6283820686de312d4527df8.tar.gz
SERVER-57326: Add bson data gdb pretty printer function.
-rw-r--r--buildscripts/gdb/mongo.py37
-rw-r--r--buildscripts/gdb/mongo_printers.py35
2 files changed, 72 insertions, 0 deletions
diff --git a/buildscripts/gdb/mongo.py b/buildscripts/gdb/mongo.py
index 08a26df539b..caea23d7a02 100644
--- a/buildscripts/gdb/mongo.py
+++ b/buildscripts/gdb/mongo.py
@@ -24,6 +24,13 @@ except Exception as e:
print("Failed to load the libstdc++ pretty printers: " + str(e))
# pylint: enable=invalid-name,wildcard-import
+try:
+ import bson
+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
+
if sys.version_info[0] < 3:
raise gdb.GdbError(
"MongoDB gdb extensions only support Python 3. Your GDB was compiled against Python 2")
@@ -748,6 +755,36 @@ class MongoDBJavaScriptStack(gdb.Command):
MongoDBJavaScriptStack()
+class MongoDBPPrintBsonAtPointer(gdb.Command):
+ """Interprets a pointer into raw memory as the start of a bson object. Pretty print the results."""
+
+ def __init__(self):
+ """Init."""
+ RegisterMongoCommand.register(self, "mongodb-pprint-bson", gdb.COMMAND_STATUS)
+
+ def invoke(self, args, _from_tty): # pylint: disable=no-self-use
+ """Invoke."""
+ args = args.split(' ')
+ if len(args) == 0 or (len(args) == 1 and len(args[0]) == 0):
+ print("Usage: mongodb-pprint-bson <ptr> <optional length>")
+ return
+
+ ptr = eval(args[0]) # pylint: disable=eval-used
+ size = 20 * 1024
+ if len(args) >= 2:
+ size = int(args[1])
+ print("Pretty printing bson object at %s (%d bytes)" % (ptr, size))
+
+ memory = gdb.selected_inferior().read_memory(ptr, size).tobytes()
+ bsonobj = next(bson.decode_iter(memory))
+
+ from pprint import pprint
+ pprint(bsonobj)
+
+
+MongoDBPPrintBsonAtPointer()
+
+
class MongoDBHelp(gdb.Command):
"""Dump list of mongodb commands."""
diff --git a/buildscripts/gdb/mongo_printers.py b/buildscripts/gdb/mongo_printers.py
index 6adf0f3b3b0..c8a5790d305 100644
--- a/buildscripts/gdb/mongo_printers.py
+++ b/buildscripts/gdb/mongo_printers.py
@@ -566,6 +566,40 @@ class MongoPrettyPrinterCollection(gdb.printing.PrettyPrinter):
return None
+class WtUpdateToBsonPrinter(object):
+ """Pretty printer for WT_UPDATE. Interpreting the `data` field as bson."""
+
+ def __init__(self, val):
+ """Initializer."""
+ self.val = val
+ self.size = self.val['size']
+ self.ptr = self.val['data']
+
+ @staticmethod
+ def display_hint():
+ """DisplayHint."""
+ return 'map'
+
+ # pylint: disable=R0201
+ def to_string(self):
+ """ToString."""
+ elems = []
+ for idx in range(len(self.val.type.fields())):
+ fld = self.val.type.fields()[idx]
+ val = self.val[fld.name]
+ elems.append(str((fld.name, str(val))))
+ return "WT_UPDATE: \n %s" % ('\n '.join(elems))
+
+ def children(self):
+ """children."""
+ memory = gdb.selected_inferior().read_memory(self.ptr, self.size).tobytes()
+ bsonobj = next(bson.decode_iter(memory)) # pylint: disable=stop-iteration-return
+
+ for key, value in list(bsonobj.items()):
+ yield 'key', key
+ yield 'value', bson.json_util.dumps(value)
+
+
def build_pretty_printer():
"""Build a pretty printer."""
pp = MongoPrettyPrinterCollection()
@@ -582,6 +616,7 @@ def build_pretty_printer():
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)
+ pp.add('__wt_update', '__wt_update', False, WtUpdateToBsonPrinter)
return pp