Skip to content

Instantly share code, notes, and snippets.

@judahschvimer
Created January 14, 2019 16:14
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 judahschvimer/4aed5b4a40a78d9a704b53f21468b4d7 to your computer and use it in GitHub Desktop.
Save judahschvimer/4aed5b4a40a78d9a704b53f21468b4d7 to your computer and use it in GitHub Desktop.
StepIntoMongod
# Created by Dan Gottlieb
import gdb
class StepIntoMongod(gdb.Command):
"""sim (Step Into MongoDB)
Step into the next MongoDB source line.
There are two usages. `sim` and `sim <arg>`.
sim: Steps into the next MongoDB (or WiredTiger) source line. Consider the source line:
AutoGetCollectionOrViewForReadCommand ctx(opCtx, nss, std::move(dbSLock));
Doing a step from here will land inside the source for `std::move`:
step:
std::move<mongo::lock::DBLock&> (__t=...) at /opt/mongodbtoolchain/v2/bin/../lib/gcc/x86_64-mongodb-linux/5.4.0/../../../../include/c++/5.4.0/bits/move.h:102
Oftentimes one assumes the standard library/boost methods are doing the right thing and
instead want to jump to the next line inside MongoDB. Running with `sim` instead gives the
move constructor directly:
sim:
mongo::lock::DBLock::DBLock(mongo::lock::DBLock&&) (<snip>) at src/mongo/db/concurrency/d_concurrency.cpp:213
The second usage is running with an argument, `sim <arg>`. Oftentimes one might also want to
step into a specific MongoDB function. In the above example, one may not care about any of the
logic dealing with parameter passing and rather get directly to the constructor for
`AutoGetCollectionOrViewForReadCommand`.
sim AutoGetCollectionOrViewForReadCommand:
mongo::AutoGetCollectionOrViewForReadCommand::AutoGetCollectionOrViewForReadCommand (<snip>) at src/mongo/db/db_raii.cpp:244
`sim <arg>` matches <arg> against a substring of the function name. I.e: `sim AutoGetColl`
would be a short-hand for the same example.
Also note that a misspelled <arg> may not exist, causing the script to infinite loop, even as
other breakpoints get hit. This script has a built-in limit of stepping 20 times before
returning to the user. Take care when passing in an <arg> to not step too in a hard to hit
breakpoint.
"""
def __init__(self):
gdb.Command.__init__(self, "sim", gdb.COMMAND_RUNNING)
def invoke(self, skipTilSymbolAsFrame, from_tty):
steps = 0
while True:
output = gdb.execute("step", False, True)
steps += 1
fr = gdb.selected_frame()
if skipTilSymbolAsFrame:
if skipTilSymbolAsFrame in fr.function().name:
gdb.write(output)
break
if steps > 20:
gdb.write("Stepped 20 times without finding the target frame. Searched for: %s\n" % (skipTilSymbolAsFrame,))
return
else:
symtabAndLine = fr.find_sal().symtab
if symtabAndLine.filename.startswith('src/mongo/') or \
symtabAndLine.filename.startswith('src/third_party/wiredtiger'):
gdb.write(output)
break
output = gdb.execute("finish", False, True)
return
StepIntoMongod()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment