* "info mutex"
@ 2010-07-13 17:57 Tom Tromey
0 siblings, 0 replies; only message in thread
From: Tom Tromey @ 2010-07-13 17:57 UTC (permalink / raw)
To: Project Archer
I saw a request for something like this from a user, and so I took a
stab at implementing it yesterday.
This adds a new "info mutex" command that shows the current threads
grouped by mutex. In particular it tries to show what threads are
blocking on a mutex, and what thread owns that mutex.
As is, it only works for pthread mutexes, and you need the glibc
debuginfo installed. Also the output is not as pretty as "info thread":
(gdb) info mutex
Threads not waiting for a lock:
Thread 18453
Mutex 0x8049874:
Owned by thread 18453
* Thread 18456
A couple Python API notes arising from this work:
* It would be nice to have a way to print a thread the way the GDB core
does it. Say, some extended to_string method on gdb.Thread.
* Probably ThreadHolder should be in our library.
* For things like the mutex specifics, it would be nice if libraries
could add their own information when the library-related .py code is
loaded. Maybe we need some generic mechanism for this, since I think
we already also want this for frame filters.
I don't think this code is fully baked enough to check in, but I wanted
to post it in case other people are interested.
Tom
import gdb
class ThreadHolder:
"""A class that can be used with the 'with' statement to save and
restore the current thread while operating on some other thread."""
def __init__(self, thread):
self.thread = thread
def __enter__(self):
self.save = gdb.selected_thread()
self.thread.switch()
def __exit__ (self, exc_type, exc_value, traceback):
try:
self.save.switch()
except:
pass
return None
def print_thread (thr, owner):
"A helper function to nicely print a gdb.Thread."
if thr == selected_thread:
print "* ",
else:
print " ",
if owner:
print "Owned by thread",
else:
print "Thread",
(pid, lwp, tid) = thr.ptid
print "%d " % lwp
# FIXME - function, file name, etc
class InfoMutex(gdb.Command):
def __init__ (self):
gdb.Command.__init__ (self, "info mutex", gdb.COMMAND_NONE)
def invoke (self, arg, from_tty):
# Map a mutex ID to the LWP owning the mutex.
owner = {}
# Map an LWP id to a thread object.
threads = {}
# Map a mutex ID to a list of thread objects that are waiting
# for the lock.
mutexes = {}
for inf in gdb.inferiors():
for thr in inf.threads():
id = thr.ptid[1]
threads[id] = thr
with ThreadHolder (thr):
frame = gdb.selected_frame()
lock_name = None
for n in range(5):
if frame is None:
break
fn_sym = frame.function()
if fn_sym is not None and (fn_sym.name == '__pthread_mutex_lock' or fn_sym.name == '__pthread_mutex_lock_full' or fn_sym.name == 'pthread_mutex_timedlock'):
m = frame.read_var ('mutex')
lock_name = long (m)
if lock_name not in owner:
owner[lock_name] = long (m['__data']['__owner'])
break
frame = frame.older()
if lock_name not in mutexes:
mutexes[lock_name] = []
mutexes[lock_name] += [thr]
selected_thread = gdb.selected_thread()
for id in mutexes.keys():
if id is None:
print "Threads not waiting for a lock:"
else:
print "Mutex 0x%x:" % id
print_thread (threads[owner[id]], True)
for thr in mutexes[id]:
print_thread (thr, False)
print
InfoMutex()
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2010-07-13 17:57 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-07-13 17:57 "info mutex" Tom Tromey
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).