Created
January 14, 2019 16:14
-
-
Save judahschvimer/4aed5b4a40a78d9a704b53f21468b4d7 to your computer and use it in GitHub Desktop.
StepIntoMongod
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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