summaryrefslogtreecommitdiff
path: root/buildscripts/gdb
diff options
context:
space:
mode:
authorJames Wahlin <james@mongodb.com>2018-04-10 16:24:24 -0400
committerJames Wahlin <james@mongodb.com>2018-04-18 13:03:56 -0400
commitadcbe28e5c66d0e6fc108073cf15f3fc4e078b4d (patch)
tree9cce85c77581cbfe2262296a54d4a35dd1559c79 /buildscripts/gdb
parent133bf4b4c4517fe52cfda3d3fdbad960eb0f64a6 (diff)
downloadmongo-adcbe28e5c66d0e6fc108073cf15f3fc4e078b4d.tar.gz
SERVER-34334 Update Locker _threadId when stashing/unstashing
Diffstat (limited to 'buildscripts/gdb')
-rw-r--r--buildscripts/gdb/mongo_lock.py35
1 files changed, 34 insertions, 1 deletions
diff --git a/buildscripts/gdb/mongo_lock.py b/buildscripts/gdb/mongo_lock.py
index 78d2778e07b..ecd1cf743aa 100644
--- a/buildscripts/gdb/mongo_lock.py
+++ b/buildscripts/gdb/mongo_lock.py
@@ -15,6 +15,35 @@ if sys.version_info[0] >= 3:
long = int # pylint: disable=redefined-builtin,invalid-name
+class NonExecutingThread(object):
+ """NonExecutingThread class.
+
+ Idle multi-statement transactions can hold locks that are not associated with an active
+ thread. In order to generate meaningful digraphs that include these locks, we create an
+ object that implements the "Thread" class interface but populates with LockerId rather than
+ thread::id. This allows us to uniquely identify each idle transaction.
+ """
+
+ def __init__(self, locker_id):
+ """Initialize Thread."""
+ self.locker_id = locker_id
+
+ def __eq__(self, other):
+ if isinstance(other, NonExecutingThread):
+ return self.locker_id == other.locker_id
+ return NotImplemented
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __str__(self):
+ return "Idle Transaction (LockerId {})".format(self.locker_id)
+
+ def key(self):
+ """Return NonExecutingThread key."""
+ return "LockerId {}".format(self.locker_id)
+
+
class Thread(object):
"""Thread class."""
@@ -291,7 +320,11 @@ def find_lock_manager_holders(graph, thread_dict, show): # pylint: disable=too-
locker_ptr = locker_ptr.cast(locker_ptr_type)
locker = locker_ptr.dereference()
lock_holder_id = int(locker["_threadId"]["_M_thread"])
- lock_holder = find_thread(thread_dict, lock_holder_id)
+ if lock_holder_id == 0:
+ locker_id = int(locker["_id"])
+ lock_holder = NonExecutingThread(locker_id)
+ else:
+ lock_holder = find_thread(thread_dict, lock_holder_id)
if show:
print("MongoDB Lock at {} ({}) held by {} waited on by {}".format(
lock_head, lock_request["mode"], lock_holder, lock_waiter))