diff options
author | Daniel Gottlieb <daniel.gottlieb@mongodb.com> | 2021-06-01 16:07:57 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-06-01 20:28:20 +0000 |
commit | 87e10cc39920a7aff6283820686de312d4527df8 (patch) | |
tree | bd45b224419a3ed347b672dc8344e290be48720b /buildscripts/gdb | |
parent | 0ec70f6ac70716d9296a014d52e4cc99bf4e5695 (diff) | |
download | mongo-87e10cc39920a7aff6283820686de312d4527df8.tar.gz |
SERVER-57326: Add bson data gdb pretty printer function.
Diffstat (limited to 'buildscripts/gdb')
-rw-r--r-- | buildscripts/gdb/mongo.py | 37 | ||||
-rw-r--r-- | buildscripts/gdb/mongo_printers.py | 35 |
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 |