diff --git a/nptl/printers.py b/nptl/printers.py
new file mode 100644
index 0000000..fdab6e8
--- /dev/null
+++ b/nptl/printers.py
@@ -0,0 +1,744 @@
+# Copyright (C) 2015 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+# Contributed by Martin Galvan <martin.galvan@tallertechnologies.com>
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+"""Pretty printers for the NTPL lock types.
+
+This file contains the gdb pretty printers for the following types:
+
+    * pthread_mutex_t
+    * pthread_mutexattr_t
+    * pthread_cond_t
+    * pthread_condattr_t
+    * pthread_rwlock_t
+    * pthread_rwlockattr_t
+
+You can check which printers are registered and enabled by issuing the
+'info pretty-printer' gdb command. Printers should trigger automatically when
+trying to print a variable of one of the types mentioned above.
+"""
+
+import sys
+import re
+import ctypes
+import gdb
+
+class _IteratorP3(object):
+    """A simple Iterator class."""
+
+    def __init__(self, values):
+        self.values = values
+        self.length = len(self.values)
+        self.count = 0
+
+    def __iter__(self):
+        return self
+
+    def __next__(self):
+        count = self.count
+        self.count += 1
+
+        if count == self.length:
+            raise StopIteration
+        else:
+            return self.values[count]
+
+class _IteratorP2(_IteratorP3):
+    """Hack for Python 2 compatibilty."""
+
+    def next(self):
+        self.__next__()
+
+# Hack for Python 2 compatibilty
+if sys.version_info[0] > 2:
+    Iterator = _IteratorP3
+else:
+    Iterator = _IteratorP2
+
+################################################################################
+
+# These variables correspond to the macros defined in nptl/pthread.h and
+# nptl/pthreadP.h. Unfortunately, as those values are hardcoded in the glibc
+# code, updating the macros will require updating these variables as well.
+
+# Mutex types
+PTHREAD_MUTEX_KIND_MASK = 0x3
+PTHREAD_MUTEX_NORMAL = 0
+PTHREAD_MUTEX_RECURSIVE = 1
+PTHREAD_MUTEX_ERRORCHECK = 2
+PTHREAD_MUTEX_ADAPTIVE_NP = 3
+
+# Mutex status
+PTHREAD_MUTEX_DESTROYED = -1
+PTHREAD_MUTEX_UNLOCKED = 0
+PTHREAD_MUTEX_LOCKED_NO_WAITERS = 1
+
+# INT_MAX for 2's complement CPUs
+PTHREAD_MUTEX_INCONSISTENT = gdb.parse_and_eval('~0u >> 1')
+PTHREAD_MUTEX_NOTRECOVERABLE = PTHREAD_MUTEX_INCONSISTENT - 1
+
+# For robust mutexes
+FUTEX_OWNER_DIED = 0x40000000
+
+# For robust and PI mutexes
+FUTEX_WAITERS = 0x80000000
+FUTEX_TID_MASK = 0x3FFFFFFF
+
+# Mutex attributes
+PTHREAD_MUTEX_ROBUST_NORMAL_NP = 0x10
+PTHREAD_MUTEX_PRIO_INHERIT_NP = 0x20
+PTHREAD_MUTEX_PRIO_PROTECT_NP = 0x40
+PTHREAD_MUTEX_PSHARED_BIT = 0x80
+PTHREAD_MUTEX_PRIO_CEILING_SHIFT = 19
+PTHREAD_MUTEX_PRIO_CEILING_MASK = 0x7FF80000
+
+mutexTypesDict = {
+    PTHREAD_MUTEX_NORMAL: ('Type', 'Normal'),
+    PTHREAD_MUTEX_RECURSIVE: ('Type', 'Recursive'),
+    PTHREAD_MUTEX_ERRORCHECK: ('Type', 'Error check'),
+    PTHREAD_MUTEX_ADAPTIVE_NP: ('Type', 'Adaptive')
+}
+
+class MutexPrinter(object):
+    """Pretty printer for pthread_mutex_t."""
+
+    def __init__(self, mutex):
+        """Initialize the printer's internal data structures.
+
+        Args:
+            mutex: A gdb.value representing a pthread_mutex_t.
+        """
+
+        data = mutex['__data']
+        self.lock = data['__lock']
+        self.count = data['__count']
+        self.owner = data['__owner']
+        self.kind = data['__kind']
+        self.values = []
+        self.readValues()
+
+    def to_string(self):
+        """gdb API function.
+
+        This is called from gdb when we try to print a pthread_mutex_t.
+        """
+
+        return 'pthread_mutex_t'
+
+    def children(self):
+        """gdb API function.
+
+        This is called from gdb when we try to print a pthread_mutex_t.
+        """
+
+        return Iterator(self.values)
+
+    def readValues(self):
+        """Read the mutex's info and store it in self.values.
+
+        The data contained in self.values will be returned by the Iterator
+        created in self.children.
+        """
+
+        self.readType()
+        self.readStatus()
+        self.readAttributes()
+        self.readMiscInfo()
+
+    def readType(self):
+        """Read the mutex's type."""
+
+        mutexType = self.kind & PTHREAD_MUTEX_KIND_MASK
+
+        # mutexType must be casted to int because it's a gdb.Value
+        self.values.append(mutexTypesDict[int(mutexType)])
+
+    def readStatus(self):
+        """Read the mutex's status.
+
+        For architectures which support lock elision, this method reads
+        whether the mutex is actually locked (i.e. it may show it as unlocked
+        even after calling pthread_mutex_lock).
+        """
+
+        if self.kind == PTHREAD_MUTEX_DESTROYED:
+            self.values.append(('Status', 'Destroyed'))
+        elif self.kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP:
+            self.readStatusRobust()
+        else:
+            self.readStatusNonRobust()
+
+    def readStatusRobust(self):
+        """Read the status of a robust mutex.
+
+        In glibc robust mutexes are implemented in a very different way than
+        non-robust ones. This method reads their locking status,
+        whether it may have waiters, their registered owner (if any),
+        whether the owner is alive or not, and the status of the state
+        they're protecting.
+        """
+
+        if self.lock == PTHREAD_MUTEX_UNLOCKED:
+            self.values.append(('Status', 'Unlocked'))
+        else:
+            if self.lock & FUTEX_WAITERS:
+                self.values.append(('Status', 'Locked, possibly with waiters'))
+            else:
+                self.values.append(('Status', 'Locked, no waiters'))
+
+            if self.lock & FUTEX_OWNER_DIED:
+                self.values.append(('Owner ID', '%d (dead)' % self.owner))
+            else:
+                self.values.append(('Owner ID', self.lock & FUTEX_TID_MASK))
+
+        if self.owner == PTHREAD_MUTEX_INCONSISTENT:
+            self.values.append(('State protected by this mutex',
+                                'Inconsistent'))
+        elif self.owner == PTHREAD_MUTEX_NOTRECOVERABLE:
+            self.values.append(('State protected by this mutex',
+                                'Not recoverable'))
+
+    def readStatusNonRobust(self):
+        """Read the status of a non-robust mutex.
+
+        Read info on whether the mutex is locked, if it may have waiters
+        and its owner (if any).
+        """
+
+        if self.lock == PTHREAD_MUTEX_UNLOCKED:
+            self.values.append(('Status', 'Unlocked'))
+        else:
+            if self.kind & PTHREAD_MUTEX_PRIO_INHERIT_NP:
+                waiters = self.lock & FUTEX_WAITERS
+                owner = self.lock & FUTEX_TID_MASK
+            else:
+                # Mutex protocol is PP or none
+                waiters = (self.lock != PTHREAD_MUTEX_LOCKED_NO_WAITERS)
+                owner = self.owner
+
+            if waiters:
+                self.values.append(('Status', 'Locked, possibly with waiters'))
+            else:
+                self.values.append(('Status', 'Locked, no waiters'))
+
+            self.values.append(('Owner ID', owner))
+
+    def readAttributes(self):
+        """Read the mutex's attributes."""
+
+        if self.kind != PTHREAD_MUTEX_DESTROYED:
+            if self.kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP:
+                self.values.append(('Robust', 'Yes'))
+            else:
+                self.values.append(('Robust', 'No'))
+
+            # In glibc, robust mutexes always have their pshared flag set to
+            # 'shared' regardless of what the pshared flag of their
+            # mutexattr was. Therefore a robust mutex will act as shared even if
+            # it was initialized with a 'private' mutexattr.
+            if self.kind & PTHREAD_MUTEX_PSHARED_BIT:
+                self.values.append(('Shared', 'Yes'))
+            else:
+                self.values.append(('Shared', 'No'))
+
+            if self.kind & PTHREAD_MUTEX_PRIO_INHERIT_NP:
+                self.values.append(('Protocol', 'Priority inherit'))
+            elif self.kind & PTHREAD_MUTEX_PRIO_PROTECT_NP:
+                prioCeiling = ((self.lock & PTHREAD_MUTEX_PRIO_CEILING_MASK) >>
+                               PTHREAD_MUTEX_PRIO_CEILING_SHIFT)
+
+                self.values.append(('Protocol', 'Priority protect'))
+                self.values.append(('Priority ceiling', prioCeiling))
+            else:
+                # PTHREAD_PRIO_NONE
+                self.values.append(('Protocol', 'None'))
+
+    def readMiscInfo(self):
+        """Read miscellaneous info on the mutex.
+
+        For now this reads the number of times a row a recursive mutex
+        was locked by the same thread.
+        """
+
+        mutexType = self.kind & PTHREAD_MUTEX_KIND_MASK
+
+        if mutexType == PTHREAD_MUTEX_RECURSIVE and self.count > 1:
+            self.values.append(('Times locked recursively', self.count))
+
+################################################################################
+
+# Mutex attribute flags
+PTHREAD_MUTEXATTR_PROTOCOL_SHIFT = 28
+PTHREAD_MUTEXATTR_PROTOCOL_MASK = 0x30000000
+PTHREAD_MUTEXATTR_PRIO_CEILING_MASK = 0x00FFF000
+PTHREAD_MUTEXATTR_FLAG_ROBUST = 0x40000000
+PTHREAD_MUTEXATTR_FLAG_PSHARED = 0x80000000
+
+PTHREAD_MUTEXATTR_FLAG_BITS = (PTHREAD_MUTEXATTR_FLAG_ROBUST |
+                               PTHREAD_MUTEXATTR_FLAG_PSHARED |
+                               PTHREAD_MUTEXATTR_PROTOCOL_MASK |
+                               PTHREAD_MUTEXATTR_PRIO_CEILING_MASK)
+
+PTHREAD_MUTEX_NO_ELISION_NP = 0x200
+
+# Priority protocols
+PTHREAD_PRIO_NONE = 0
+PTHREAD_PRIO_INHERIT = 1
+PTHREAD_PRIO_PROTECT = 2
+
+class MutexAttributesPrinter(object):
+    """Pretty printer for pthread_mutexattr_t.
+
+    In the NPTL this is a type that's always casted to struct pthread_mutexattr,
+    which has a single 'mutexkind' field containing the actual attributes.
+    """
+
+    def __init__(self, mutexattr):
+        """Initialize the printer's internal data structures.
+
+        Args:
+            mutexattr: A gdb.value representing a pthread_mutexattr_t.
+        """
+
+        mutexattrStruct = gdb.lookup_type('struct pthread_mutexattr')
+        self.mutexattr = mutexattr.cast(mutexattrStruct)['mutexkind']
+        self.values = []
+        self.readValues()
+
+    def to_string(self):
+        """gdb API function.
+
+        This is called from gdb when we try to print a pthread_mutexattr_t.
+        """
+
+        return 'pthread_mutexattr_t'
+
+    def children(self):
+        """gdb API function.
+
+        This is called from gdb when we try to print a pthread_mutexattr_t.
+        """
+
+        return Iterator(self.values)
+
+    def readValues(self):
+        """Read the mutexattr's info and store it in self.values.
+
+        The data contained in self.values will be returned by the Iterator
+        created in self.children.
+        """
+
+        mutexattrType = (self.mutexattr &
+                         ~PTHREAD_MUTEXATTR_FLAG_BITS &
+                         ~PTHREAD_MUTEX_NO_ELISION_NP)
+
+        # mutexattrType must be casted to int because it's a gdb.Value
+        self.values.append(mutexTypesDict[int(mutexattrType)])
+
+        if self.mutexattr & PTHREAD_MUTEXATTR_FLAG_ROBUST:
+            self.values.append(('Robust', 'Yes'))
+        else:
+            self.values.append(('Robust', 'No'))
+
+        if self.mutexattr & PTHREAD_MUTEXATTR_FLAG_PSHARED:
+            self.values.append(('Shared', 'Yes'))
+        else:
+            self.values.append(('Shared', 'No'))
+
+        protocol = ((self.mutexattr & PTHREAD_MUTEXATTR_PROTOCOL_MASK) >>
+                    PTHREAD_MUTEXATTR_PROTOCOL_SHIFT)
+
+        if protocol == PTHREAD_PRIO_NONE:
+            self.values.append(('Protocol', 'None'))
+        elif protocol == PTHREAD_PRIO_INHERIT:
+            self.values.append(('Protocol', 'Priority inherit'))
+        elif protocol == PTHREAD_PRIO_PROTECT:
+            self.values.append(('Protocol', 'Priority protect'))
+
+################################################################################
+
+# Value of __mutex for shared condvars.
+PTHREAD_COND_SHARED = ~ctypes.c_long(0).value
+
+# Value of __total_seq for destroyed condvars.
+PTHREAD_COND_DESTROYED = ctypes.c_ulonglong(-1).value
+
+# __nwaiters encodes the number of threads waiting on a condvar
+# and the clock ID.
+# __nwaiters >> COND_NWAITERS_SHIFT gives us the number of waiters.
+COND_NWAITERS_SHIFT = 1
+
+class ConditionVariablePrinter(object):
+    """Pretty printer for pthread_cond_t."""
+
+    def __init__(self, cond):
+        """Initialize the printer's internal data structures.
+
+        Args:
+            cond: A gdb.value representing a pthread_cond_t.
+        """
+
+        data = cond['__data']
+        self.totalSeq = data['__total_seq']
+        self.mutex = data['__mutex']
+        self.nwaiters = data['__nwaiters']
+        self.values = []
+        self.readValues()
+
+    def to_string(self):
+        """gdb API function.
+
+        This is called from gdb when we try to print a pthread_cond_t.
+        """
+
+        return 'pthread_cond_t'
+
+    def children(self):
+        """gdb API function.
+
+        This is called from gdb when we try to print a pthread_cond_t.
+        """
+
+        return Iterator(self.values)
+
+    def readValues(self):
+        """Read the condvar's info and store it in self.values.
+
+        The data contained in self.values will be returned by the Iterator
+        created in self.children.
+        """
+
+        self.readStatus()
+        self.readAttributes()
+        self.readMutexInfo()
+
+    def readStatus(self):
+        """Read the status of the condvar.
+
+        This method reads whether the condvar is destroyed and how many threads
+        are waiting for it.
+        """
+
+        if self.totalSeq == PTHREAD_COND_DESTROYED:
+            self.values.append(('Status', 'Destroyed'))
+
+        self.values.append(('Threads waiting for this condvar',
+                           self.nwaiters >> COND_NWAITERS_SHIFT))
+
+    def readAttributes(self):
+        """Read the condvar's attributes."""
+
+        clockID = self.nwaiters & ((1 << COND_NWAITERS_SHIFT) - 1)
+        shared = (self.mutex == PTHREAD_COND_SHARED)
+
+        if shared:
+            self.values.append(('Shared', 'Yes'))
+        else:
+            self.values.append(('Shared', 'No'))
+
+        self.values.append(('Clock ID', clockID))
+
+    def readMutexInfo(self):
+        """Read the data of the mutex this condvar is bound to.
+
+        A pthread_cond_t's __data.__mutex member is a void * which
+        must be casted to pthread_mutex_t *. For shared condvars, this
+        member isn't recorded and has a value of ~0l instead.
+        """
+
+        if self.mutex and self.mutex != PTHREAD_COND_SHARED:
+            mutexType = gdb.lookup_type('pthread_mutex_t')
+            mutex = self.mutex.cast(mutexType.pointer()).dereference()
+
+            self.values.append(('Mutex', mutex))
+
+################################################################################
+
+class ConditionVariableAttributesPrinter(object):
+    """Pretty printer for pthread_condattr_t.
+
+    In the NPTL this is a type that's
+    always casted to struct pthread_condattr, which has a single 'value' field
+    containing the actual attributes.
+    """
+
+    def __init__(self, condattr):
+        """Initialize the printer's internal data structures.
+
+        Args:
+            condattr: A gdb.value representing a pthread_condattr_t.
+        """
+
+        condattrStruct = gdb.lookup_type('struct pthread_condattr')
+        self.condattr = condattr.cast(condattrStruct)['value']
+        self.values = []
+        self.readValues()
+
+    def to_string(self):
+        """gdb API function.
+
+        This is called from gdb when we try to print a pthread_condattr_t.
+        """
+
+        return 'pthread_condattr_t'
+
+    def children(self):
+        """gdb API function.
+
+        This is called from gdb when we try to print a pthread_condattr_t.
+        """
+
+        return Iterator(self.values)
+
+    def readValues(self):
+        """Read the condattr's info and store it in self.values.
+
+        The data contained in self.values will be returned by the Iterator
+        created in self.children.
+        """
+
+        clockID = self.condattr & ((1 << COND_NWAITERS_SHIFT) - 1)
+
+        if self.condattr & 1:
+            self.values.append(('Shared', 'Yes'))
+        else:
+            self.values.append(('Shared', 'No'))
+
+        self.values.append(('Clock ID', clockID))
+
+################################################################################
+
+class RWLockPrinter(object):
+    """Pretty printer for pthread_rwlock_t."""
+
+    def __init__(self, rwlock):
+        """Initialize the printer's internal data structures.
+
+        Args:
+            rwlock: A gdb.value representing a pthread_rwlock_t.
+        """
+
+        data = rwlock['__data']
+        self.readers = data['__nr_readers']
+        self.queuedReaders = data['__nr_readers_queued']
+        self.queuedWriters = data['__nr_writers_queued']
+        self.writerID = data['__writer']
+        self.shared = data['__shared']
+        self.prefersWriters = data['__flags']
+        self.values = []
+        self.readValues()
+
+    def to_string(self):
+        """gdb API function.
+
+        This is called from gdb when we try to print a pthread_rwlock_t.
+        """
+
+        return 'pthread_rwlock_t'
+
+    def children(self):
+        """gdb API function.
+
+        This is called from gdb when we try to print a pthread_rwlock_t.
+        """
+
+        return Iterator(self.values)
+
+    def readValues(self):
+        """Read the rwlock's info and store it in self.values.
+
+        The data contained in self.values will be returned by the Iterator
+        created in self.children.
+        """
+
+        self.readStatus()
+        self.readAttributes()
+
+    def readStatus(self):
+        """Read the status of the rwlock."""
+
+        if self.writerID:
+            self.values.append(('Status', 'Locked (Write)'))
+            self.values.append(('Writer ID', self.writerID))
+        elif self.readers:
+            self.values.append(('Status', 'Locked (Read)'))
+            self.values.append(('Readers', self.readers))
+        else:
+            self.values.append(('Status', 'Unlocked'))
+
+        self.values.append(('Queued readers', self.queuedReaders))
+        self.values.append(('Queued writers', self.queuedWriters))
+
+    def readAttributes(self):
+        """Read the attributes of the rwlock."""
+
+        if self.shared:
+            self.values.append(('Shared', 'Yes'))
+        else:
+            self.values.append(('Shared', 'No'))
+
+        if self.prefersWriters:
+            self.values.append(('Prefers', 'Writers'))
+        else:
+            self.values.append(('Prefers', 'Readers'))
+
+################################################################################
+
+# Rwlock attributes
+PTHREAD_RWLOCK_PREFER_READER_NP = 0
+PTHREAD_RWLOCK_PREFER_WRITER_NP = 1
+PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP = 2
+
+# 'Shared' attribute values
+PTHREAD_PROCESS_PRIVATE = 0
+PTHREAD_PROCESS_SHARED = 1
+
+class RWLockAttributesPrinter(object):
+    """Pretty printer for pthread_rwlockattr_t.
+
+    In the NPTL this is a type that's always casted to
+    struct pthread_rwlockattr, which has two fields ('lockkind' and 'pshared')
+    containing the actual attributes.
+    """
+
+    def __init__(self, rwlockattr):
+        """Initialize the printer's internal data structures.
+
+        Args:
+            rwlockattr: A gdb.value representing a pthread_rwlockattr_t.
+        """
+
+        rwlockattrStruct = gdb.lookup_type('struct pthread_rwlockattr')
+        self.rwlockattr = rwlockattr.cast(rwlockattrStruct)
+        self.values = []
+        self.readValues()
+
+    def to_string(self):
+        """gdb API function.
+
+        This is called from gdb when we try to print a pthread_rwlockattr_t."""
+
+        return 'pthread_rwlockattr_t'
+
+    def children(self):
+        """gdb API function.
+
+        This is called from gdb when we try to print a pthread_rwlockattr_t."""
+
+        return Iterator(self.values)
+
+    def readValues(self):
+        """Read the rwlockattr's info and store it in self.values.
+
+        The data contained in self.values will be returned by the Iterator
+        created in self.children.
+        """
+
+        rwlockType = self.rwlockattr['lockkind']
+        shared = self.rwlockattr['pshared']
+
+        if shared == PTHREAD_PROCESS_SHARED:
+            self.values.append(('Shared', 'Yes'))
+        else:
+            # PTHREAD_PROCESS_PRIVATE
+            self.values.append(('Shared', 'No'))
+
+        if rwlockType == PTHREAD_RWLOCK_PREFER_READER_NP:
+            self.values.append(('Prefers', 'Readers'))
+        elif (rwlockType == PTHREAD_RWLOCK_PREFER_WRITER_NP or
+              rwlockType == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP):
+            self.values.append(('Prefers', 'Writers'))
+
+################################################################################
+
+class Printer(object):
+    """Printer class which conforms to the gdb pretty printing interface."""
+
+    def __init__(self, name):
+        self.name = name
+        self.enabled = True
+        self.subprinters = []
+
+    class Subprinter(object):
+        """A regex-based printer.
+
+        Individual pretty-printers are registered as subprinters of a single
+        Printer instance.
+        """
+
+        def __init__(self, name, regex, callable):
+            """
+            Initialize a pretty-printer.
+
+            Args:
+                name: The name of the printer.
+                regex: A regular expression. When gdb tries to print a variable
+                    whose type matches the regex it'll trigger this printer.
+                callable: A function or callable object that gdb will call
+                    when trying to print some value. It should return a
+                    pretty-printer.
+            """
+            self.name = name
+            self.regex = re.compile(regex)
+            self.callable = callable
+            self.enabled = True
+
+    def addSubprinter(self, name, regex, callable):
+        """Register a regex-based subprinter."""
+
+        self.subprinters.append(self.Subprinter(name, regex, callable))
+
+    def __call__(self, value):
+        """gdb API function.
+
+        This is called when trying to print an inferior value
+        from gdb. If a registered printer's regex matches the value's type,
+        gdb will use the printer to print the value.
+        """
+
+        typeName = value.type.name
+
+        if typeName:
+            for subprinter in self.subprinters:
+                if subprinter.enabled and subprinter.regex.match(typeName):
+                    return subprinter.callable(value)
+
+        # Return None if we have no type name or if we can't find a subprinter
+        # for the given type.
+        return None
+
+################################################################################
+
+def register(objfile):
+    """Register the pretty printers within the given objfile."""
+
+    printer = Printer('Glibc pthread locks')
+
+    printer.addSubprinter('pthread_mutex_t', '^pthread_mutex_t$', MutexPrinter)
+    printer.addSubprinter('pthread_mutexattr_t', '^pthread_mutexattr_t$',
+                          MutexAttributesPrinter)
+    printer.addSubprinter('pthread_cond_t', '^pthread_cond_t$',
+                          ConditionVariablePrinter)
+    printer.addSubprinter('pthread_condattr_t', '^pthread_condattr_t$',
+                          ConditionVariableAttributesPrinter)
+    printer.addSubprinter('pthread_rwlock_t', '^pthread_rwlock_t$', RWLockPrinter)
+    printer.addSubprinter('pthread_rwlockattr_t', '^pthread_rwlockattr_t$',
+                          RWLockAttributesPrinter)
+
+    gdb.printing.register_pretty_printer(objfile, printer)
+
+register(gdb.current_objfile())
