about summary refs log tree commit diff
path: root/nptl/nptl-printers.py
diff options
context:
space:
mode:
authorSiddhesh Poyarekar <siddhesh@sourceware.org>2016-07-11 20:32:12 +0530
committerSiddhesh Poyarekar <siddhesh@sourceware.org>2016-07-11 20:32:12 +0530
commitc10f90dcef42092a96007fed7e77f9d470e5bb76 (patch)
treed4e260bbfec4a61d50a17f3be8fc64a0b7b01b4b /nptl/nptl-printers.py
parent26c2910ac6889dd21f128d9071418492d544a2dc (diff)
downloadglibc-c10f90dcef42092a96007fed7e77f9d470e5bb76.tar.gz
glibc-c10f90dcef42092a96007fed7e77f9d470e5bb76.tar.xz
glibc-c10f90dcef42092a96007fed7e77f9d470e5bb76.zip
Revert "Add pretty printers for the NPTL lock types"
This reverts commit 62ce266b0b261def2c6329be9814ffdcc11964d6.

The change is not mature enough because it needs the following fixes:

1. Redirect test output to a file like other tests

2. Eliminate the need to use a .gdbinit because distributions will
   break without it.  I should have caught that but I was in too much
   of a hurry to get the patch in :/

3. Feature checking during configure to determine things like minimum
   required gdb version, python-pexpect version, etc. to make sure
   that tests work correctly.
Diffstat (limited to 'nptl/nptl-printers.py')
-rw-r--r--nptl/nptl-printers.py593
1 files changed, 0 insertions, 593 deletions
diff --git a/nptl/nptl-printers.py b/nptl/nptl-printers.py
deleted file mode 100644
index f64216fb57..0000000000
--- a/nptl/nptl-printers.py
+++ /dev/null
@@ -1,593 +0,0 @@
-# Pretty printers for the NPTL lock types.
-#
-# Copyright (C) 2016 Free Software Foundation, Inc.
-# This file is part of the GNU C Library.
-#
-# 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/>.
-
-"""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.
-"""
-
-from __future__ import print_function
-
-import gdb
-from nptl_lock_constants import *
-
-MUTEX_TYPES = {
-    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.read_values()
-
-    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 self.values
-
-    def read_values(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.read_type()
-        self.read_status()
-        self.read_attributes()
-        self.read_misc_info()
-
-    def read_type(self):
-        """Read the mutex's type."""
-
-        mutex_type = self.kind & PTHREAD_MUTEX_KIND_MASK
-
-        # mutex_type must be casted to int because it's a gdb.Value
-        self.values.append(MUTEX_TYPES[int(mutex_type)])
-
-    def read_status(self):
-        """Read the mutex's status.
-
-        For architectures which support lock elision, this method reads
-        whether the mutex appears as locked in memory (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.read_status_robust()
-        else:
-            self.read_status_no_robust()
-
-    def read_status_robust(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, possibly with 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 read_status_no_robust(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).
-        """
-
-        lock_value = self.lock
-
-        if self.kind & PTHREAD_MUTEX_PRIO_PROTECT_NP:
-            lock_value &= ~(PTHREAD_MUTEX_PRIO_CEILING_MASK)
-
-        if lock_value == 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, possibly with no waiters'))
-
-            self.values.append(('Owner ID', owner))
-
-    def read_attributes(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:
-                prio_ceiling = ((self.lock & PTHREAD_MUTEX_PRIO_CEILING_MASK)
-                                >> PTHREAD_MUTEX_PRIO_CEILING_SHIFT)
-
-                self.values.append(('Protocol', 'Priority protect'))
-                self.values.append(('Priority ceiling', prio_ceiling))
-            else:
-                # PTHREAD_PRIO_NONE
-                self.values.append(('Protocol', 'None'))
-
-    def read_misc_info(self):
-        """Read miscellaneous info on the mutex.
-
-        For now this reads the number of times a recursive mutex was locked
-        by the same thread.
-        """
-
-        mutex_type = self.kind & PTHREAD_MUTEX_KIND_MASK
-
-        if mutex_type == PTHREAD_MUTEX_RECURSIVE and self.count > 1:
-            self.values.append(('Times locked recursively', self.count))
-
-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.
-        """
-
-        mutexattr_struct = gdb.lookup_type('struct pthread_mutexattr')
-        self.mutexattr = mutexattr.cast(mutexattr_struct)['mutexkind']
-        self.values = []
-        self.read_values()
-
-    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 self.values
-
-    def read_values(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.
-        """
-
-        mutexattr_type = (self.mutexattr
-                          & ~PTHREAD_MUTEXATTR_FLAG_BITS
-                          & ~PTHREAD_MUTEX_NO_ELISION_NP)
-
-        # mutexattr_type must be casted to int because it's a gdb.Value
-        self.values.append(MUTEX_TYPES[int(mutexattr_type)])
-
-        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'))
-
-CLOCK_IDS = {
-    CLOCK_REALTIME: 'CLOCK_REALTIME',
-    CLOCK_MONOTONIC: 'CLOCK_MONOTONIC',
-    CLOCK_PROCESS_CPUTIME_ID: 'CLOCK_PROCESS_CPUTIME_ID',
-    CLOCK_THREAD_CPUTIME_ID: 'CLOCK_THREAD_CPUTIME_ID',
-    CLOCK_MONOTONIC_RAW: 'CLOCK_MONOTONIC_RAW',
-    CLOCK_REALTIME_COARSE: 'CLOCK_REALTIME_COARSE',
-    CLOCK_MONOTONIC_COARSE: 'CLOCK_MONOTONIC_COARSE'
-}
-
-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.total_seq = data['__total_seq']
-        self.mutex = data['__mutex']
-        self.nwaiters = data['__nwaiters']
-        self.values = []
-        self.read_values()
-
-    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 self.values
-
-    def read_values(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.read_status()
-        self.read_attributes()
-        self.read_mutex_info()
-
-    def read_status(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.total_seq == PTHREAD_COND_DESTROYED:
-            self.values.append(('Status', 'Destroyed'))
-
-        self.values.append(('Threads waiting for this condvar',
-                            self.nwaiters >> COND_NWAITERS_SHIFT))
-
-    def read_attributes(self):
-        """Read the condvar's attributes."""
-
-        clock_id = self.nwaiters & ((1 << COND_NWAITERS_SHIFT) - 1)
-
-        # clock_id must be casted to int because it's a gdb.Value
-        self.values.append(('Clock ID', CLOCK_IDS[int(clock_id)]))
-
-        shared = (self.mutex == PTHREAD_COND_SHARED)
-
-        if shared:
-            self.values.append(('Shared', 'Yes'))
-        else:
-            self.values.append(('Shared', 'No'))
-
-    def read_mutex_info(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:
-            mutex_type = gdb.lookup_type('pthread_mutex_t')
-            mutex = self.mutex.cast(mutex_type.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.
-        """
-
-        condattr_struct = gdb.lookup_type('struct pthread_condattr')
-        self.condattr = condattr.cast(condattr_struct)['value']
-        self.values = []
-        self.read_values()
-
-    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 self.values
-
-    def read_values(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.
-        """
-
-        clock_id = self.condattr & ((1 << COND_NWAITERS_SHIFT) - 1)
-
-        # clock_id must be casted to int because it's a gdb.Value
-        self.values.append(('Clock ID', CLOCK_IDS[int(clock_id)]))
-
-        if self.condattr & 1:
-            self.values.append(('Shared', 'Yes'))
-        else:
-            self.values.append(('Shared', 'No'))
-
-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.queued_readers = data['__nr_readers_queued']
-        self.queued_writers = data['__nr_writers_queued']
-        self.writer_id = data['__writer']
-        self.shared = data['__shared']
-        self.prefers_writers = data['__flags']
-        self.values = []
-        self.read_values()
-
-    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 self.values
-
-    def read_values(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.read_status()
-        self.read_attributes()
-
-    def read_status(self):
-        """Read the status of the rwlock."""
-
-        # Right now pthread_rwlock_destroy doesn't do anything, so there's no
-        # way to check if an rwlock is destroyed.
-
-        if self.writer_id:
-            self.values.append(('Status', 'Locked (Write)'))
-            self.values.append(('Writer ID', self.writer_id))
-        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.queued_readers))
-        self.values.append(('Queued writers', self.queued_writers))
-
-    def read_attributes(self):
-        """Read the attributes of the rwlock."""
-
-        if self.shared:
-            self.values.append(('Shared', 'Yes'))
-        else:
-            self.values.append(('Shared', 'No'))
-
-        if self.prefers_writers:
-            self.values.append(('Prefers', 'Writers'))
-        else:
-            self.values.append(('Prefers', 'Readers'))
-
-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.
-        """
-
-        rwlockattr_struct = gdb.lookup_type('struct pthread_rwlockattr')
-        self.rwlockattr = rwlockattr.cast(rwlockattr_struct)
-        self.values = []
-        self.read_values()
-
-    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 self.values
-
-    def read_values(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.
-        """
-
-        rwlock_type = 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 (rwlock_type == PTHREAD_RWLOCK_PREFER_READER_NP or
-            rwlock_type == PTHREAD_RWLOCK_PREFER_WRITER_NP):
-            # This is a known bug.  Using PTHREAD_RWLOCK_PREFER_WRITER_NP will
-            # still make the rwlock prefer readers.
-            self.values.append(('Prefers', 'Readers'))
-        elif rwlock_type == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP:
-            self.values.append(('Prefers', 'Writers'))
-
-def register(objfile):
-    """Register the pretty printers within the given objfile."""
-
-    printer = gdb.printing.RegexpCollectionPrettyPrinter('glibc pthread locks')
-
-    printer.add_printer('pthread_mutex_t', r'^pthread_mutex_t$',
-                        MutexPrinter)
-    printer.add_printer('pthread_mutexattr_t', r'^pthread_mutexattr_t$',
-                        MutexAttributesPrinter)
-    printer.add_printer('pthread_cond_t', r'^pthread_cond_t$',
-                        ConditionVariablePrinter)
-    printer.add_printer('pthread_condattr_t', r'^pthread_condattr_t$',
-                        ConditionVariableAttributesPrinter)
-    printer.add_printer('pthread_rwlock_t', r'^pthread_rwlock_t$',
-                        RWLockPrinter)
-    printer.add_printer('pthread_rwlockattr_t', r'^pthread_rwlockattr_t$',
-                        RWLockAttributesPrinter)
-
-    gdb.printing.register_pretty_printer(objfile, printer)
-
-register(gdb.current_objfile())