Blame nptl/nptl-printers.py

Packit Service 82fcde
# Pretty printers for the NPTL lock types.
Packit Service 82fcde
#
Packit Service 82fcde
# Copyright (C) 2016-2018 Free Software Foundation, Inc.
Packit Service 82fcde
# This file is part of the GNU C Library.
Packit Service 82fcde
#
Packit Service 82fcde
# The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
# modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
# License as published by the Free Software Foundation; either
Packit Service 82fcde
# version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
#
Packit Service 82fcde
# The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
# Lesser General Public License for more details.
Packit Service 82fcde
#
Packit Service 82fcde
# You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
# License along with the GNU C Library; if not, see
Packit Service 82fcde
# <http://www.gnu.org/licenses/>.
Packit Service 82fcde
Packit Service 82fcde
"""This file contains the gdb pretty printers for the following types:
Packit Service 82fcde
Packit Service 82fcde
    * pthread_mutex_t
Packit Service 82fcde
    * pthread_mutexattr_t
Packit Service 82fcde
    * pthread_cond_t
Packit Service 82fcde
    * pthread_condattr_t
Packit Service 82fcde
    * pthread_rwlock_t
Packit Service 82fcde
    * pthread_rwlockattr_t
Packit Service 82fcde
Packit Service 82fcde
You can check which printers are registered and enabled by issuing the
Packit Service 82fcde
'info pretty-printer' gdb command.  Printers should trigger automatically when
Packit Service 82fcde
trying to print a variable of one of the types mentioned above.
Packit Service 82fcde
"""
Packit Service 82fcde
Packit Service 82fcde
from __future__ import print_function
Packit Service 82fcde
Packit Service 82fcde
import gdb
Packit Service 82fcde
import gdb.printing
Packit Service 82fcde
from nptl_lock_constants import *
Packit Service 82fcde
Packit Service 82fcde
MUTEX_TYPES = {
Packit Service 82fcde
    PTHREAD_MUTEX_NORMAL: ('Type', 'Normal'),
Packit Service 82fcde
    PTHREAD_MUTEX_RECURSIVE: ('Type', 'Recursive'),
Packit Service 82fcde
    PTHREAD_MUTEX_ERRORCHECK: ('Type', 'Error check'),
Packit Service 82fcde
    PTHREAD_MUTEX_ADAPTIVE_NP: ('Type', 'Adaptive')
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
class MutexPrinter(object):
Packit Service 82fcde
    """Pretty printer for pthread_mutex_t."""
Packit Service 82fcde
Packit Service 82fcde
    def __init__(self, mutex):
Packit Service 82fcde
        """Initialize the printer's internal data structures.
Packit Service 82fcde
Packit Service 82fcde
        Args:
Packit Service 82fcde
            mutex: A gdb.value representing a pthread_mutex_t.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        data = mutex['__data']
Packit Service 82fcde
        self.lock = data['__lock']
Packit Service 82fcde
        self.count = data['__count']
Packit Service 82fcde
        self.owner = data['__owner']
Packit Service 82fcde
        self.kind = data['__kind']
Packit Service 82fcde
        self.values = []
Packit Service 82fcde
        self.read_values()
Packit Service 82fcde
Packit Service 82fcde
    def to_string(self):
Packit Service 82fcde
        """gdb API function.
Packit Service 82fcde
Packit Service 82fcde
        This is called from gdb when we try to print a pthread_mutex_t.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        return 'pthread_mutex_t'
Packit Service 82fcde
Packit Service 82fcde
    def children(self):
Packit Service 82fcde
        """gdb API function.
Packit Service 82fcde
Packit Service 82fcde
        This is called from gdb when we try to print a pthread_mutex_t.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        return self.values
Packit Service 82fcde
Packit Service 82fcde
    def read_values(self):
Packit Service 82fcde
        """Read the mutex's info and store it in self.values.
Packit Service 82fcde
Packit Service 82fcde
        The data contained in self.values will be returned by the Iterator
Packit Service 82fcde
        created in self.children.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        self.read_type()
Packit Service 82fcde
        self.read_status()
Packit Service 82fcde
        self.read_attributes()
Packit Service 82fcde
        self.read_misc_info()
Packit Service 82fcde
Packit Service 82fcde
    def read_type(self):
Packit Service 82fcde
        """Read the mutex's type."""
Packit Service 82fcde
Packit Service 82fcde
        mutex_type = self.kind & PTHREAD_MUTEX_KIND_MASK
Packit Service 82fcde
Packit Service 82fcde
        # mutex_type must be casted to int because it's a gdb.Value
Packit Service 82fcde
        self.values.append(MUTEX_TYPES[int(mutex_type)])
Packit Service 82fcde
Packit Service 82fcde
    def read_status(self):
Packit Service 82fcde
        """Read the mutex's status.
Packit Service 82fcde
Packit Service 82fcde
        Architectures that support lock elision might not record the mutex owner
Packit Service 82fcde
        ID in the __owner field.  In that case, the owner will be reported as
Packit Service 82fcde
        "Unknown".
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        if self.kind == PTHREAD_MUTEX_DESTROYED:
Packit Service 82fcde
            self.values.append(('Status', 'Destroyed'))
Packit Service 82fcde
        elif self.kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP:
Packit Service 82fcde
            self.read_status_robust()
Packit Service 82fcde
        else:
Packit Service 82fcde
            self.read_status_no_robust()
Packit Service 82fcde
Packit Service 82fcde
    def read_status_robust(self):
Packit Service 82fcde
        """Read the status of a robust mutex.
Packit Service 82fcde
Packit Service 82fcde
        In glibc robust mutexes are implemented in a very different way than
Packit Service 82fcde
        non-robust ones.  This method reads their locking status,
Packit Service 82fcde
        whether it may have waiters, their registered owner (if any),
Packit Service 82fcde
        whether the owner is alive or not, and the status of the state
Packit Service 82fcde
        they're protecting.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        if self.lock == PTHREAD_MUTEX_UNLOCKED:
Packit Service 82fcde
            self.values.append(('Status', 'Not acquired'))
Packit Service 82fcde
        else:
Packit Service 82fcde
            if self.lock & FUTEX_WAITERS:
Packit Service 82fcde
                self.values.append(('Status',
Packit Service 82fcde
                                    'Acquired, possibly with waiters'))
Packit Service 82fcde
            else:
Packit Service 82fcde
                self.values.append(('Status',
Packit Service 82fcde
                                    'Acquired, possibly with no waiters'))
Packit Service 82fcde
Packit Service 82fcde
            if self.lock & FUTEX_OWNER_DIED:
Packit Service 82fcde
                self.values.append(('Owner ID', '%d (dead)' % self.owner))
Packit Service 82fcde
            else:
Packit Service 82fcde
                self.values.append(('Owner ID', self.lock & FUTEX_TID_MASK))
Packit Service 82fcde
Packit Service 82fcde
        if self.owner == PTHREAD_MUTEX_INCONSISTENT:
Packit Service 82fcde
            self.values.append(('State protected by this mutex',
Packit Service 82fcde
                                'Inconsistent'))
Packit Service 82fcde
        elif self.owner == PTHREAD_MUTEX_NOTRECOVERABLE:
Packit Service 82fcde
            self.values.append(('State protected by this mutex',
Packit Service 82fcde
                                'Not recoverable'))
Packit Service 82fcde
Packit Service 82fcde
    def read_status_no_robust(self):
Packit Service 82fcde
        """Read the status of a non-robust mutex.
Packit Service 82fcde
Packit Service 82fcde
        Read info on whether the mutex is acquired, if it may have waiters
Packit Service 82fcde
        and its owner (if any).
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        lock_value = self.lock
Packit Service 82fcde
Packit Service 82fcde
        if self.kind & PTHREAD_MUTEX_PRIO_PROTECT_NP:
Packit Service 82fcde
            lock_value &= ~(PTHREAD_MUTEX_PRIO_CEILING_MASK)
Packit Service 82fcde
Packit Service 82fcde
        if lock_value == PTHREAD_MUTEX_UNLOCKED:
Packit Service 82fcde
            self.values.append(('Status', 'Not acquired'))
Packit Service 82fcde
        else:
Packit Service 82fcde
            if self.kind & PTHREAD_MUTEX_PRIO_INHERIT_NP:
Packit Service 82fcde
                waiters = self.lock & FUTEX_WAITERS
Packit Service 82fcde
                owner = self.lock & FUTEX_TID_MASK
Packit Service 82fcde
            else:
Packit Service 82fcde
                # Mutex protocol is PP or none
Packit Service 82fcde
                waiters = (self.lock != PTHREAD_MUTEX_LOCKED_NO_WAITERS)
Packit Service 82fcde
                owner = self.owner
Packit Service 82fcde
Packit Service 82fcde
            if waiters:
Packit Service 82fcde
                self.values.append(('Status',
Packit Service 82fcde
                                    'Acquired, possibly with waiters'))
Packit Service 82fcde
            else:
Packit Service 82fcde
                self.values.append(('Status',
Packit Service 82fcde
                                    'Acquired, possibly with no waiters'))
Packit Service 82fcde
Packit Service 82fcde
            if self.owner != 0:
Packit Service 82fcde
                self.values.append(('Owner ID', owner))
Packit Service 82fcde
            else:
Packit Service 82fcde
                # Owner isn't recorded, probably because lock elision
Packit Service 82fcde
                # is enabled.
Packit Service 82fcde
                self.values.append(('Owner ID', 'Unknown'))
Packit Service 82fcde
Packit Service 82fcde
    def read_attributes(self):
Packit Service 82fcde
        """Read the mutex's attributes."""
Packit Service 82fcde
Packit Service 82fcde
        if self.kind != PTHREAD_MUTEX_DESTROYED:
Packit Service 82fcde
            if self.kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP:
Packit Service 82fcde
                self.values.append(('Robust', 'Yes'))
Packit Service 82fcde
            else:
Packit Service 82fcde
                self.values.append(('Robust', 'No'))
Packit Service 82fcde
Packit Service 82fcde
            # In glibc, robust mutexes always have their pshared flag set to
Packit Service 82fcde
            # 'shared' regardless of what the pshared flag of their
Packit Service 82fcde
            # mutexattr was.  Therefore a robust mutex will act as shared
Packit Service 82fcde
            # even if it was initialized with a 'private' mutexattr.
Packit Service 82fcde
            if self.kind & PTHREAD_MUTEX_PSHARED_BIT:
Packit Service 82fcde
                self.values.append(('Shared', 'Yes'))
Packit Service 82fcde
            else:
Packit Service 82fcde
                self.values.append(('Shared', 'No'))
Packit Service 82fcde
Packit Service 82fcde
            if self.kind & PTHREAD_MUTEX_PRIO_INHERIT_NP:
Packit Service 82fcde
                self.values.append(('Protocol', 'Priority inherit'))
Packit Service 82fcde
            elif self.kind & PTHREAD_MUTEX_PRIO_PROTECT_NP:
Packit Service 82fcde
                prio_ceiling = ((self.lock & PTHREAD_MUTEX_PRIO_CEILING_MASK)
Packit Service 82fcde
                                >> PTHREAD_MUTEX_PRIO_CEILING_SHIFT)
Packit Service 82fcde
Packit Service 82fcde
                self.values.append(('Protocol', 'Priority protect'))
Packit Service 82fcde
                self.values.append(('Priority ceiling', prio_ceiling))
Packit Service 82fcde
            else:
Packit Service 82fcde
                # PTHREAD_PRIO_NONE
Packit Service 82fcde
                self.values.append(('Protocol', 'None'))
Packit Service 82fcde
Packit Service 82fcde
    def read_misc_info(self):
Packit Service 82fcde
        """Read miscellaneous info on the mutex.
Packit Service 82fcde
Packit Service 82fcde
        For now this reads the number of times a recursive mutex was acquired
Packit Service 82fcde
        by the same thread.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        mutex_type = self.kind & PTHREAD_MUTEX_KIND_MASK
Packit Service 82fcde
Packit Service 82fcde
        if mutex_type == PTHREAD_MUTEX_RECURSIVE and self.count > 1:
Packit Service 82fcde
            self.values.append(('Times acquired by the owner', self.count))
Packit Service 82fcde
Packit Service 82fcde
class MutexAttributesPrinter(object):
Packit Service 82fcde
    """Pretty printer for pthread_mutexattr_t.
Packit Service 82fcde
Packit Service 82fcde
    In the NPTL this is a type that's always casted to struct pthread_mutexattr
Packit Service 82fcde
    which has a single 'mutexkind' field containing the actual attributes.
Packit Service 82fcde
    """
Packit Service 82fcde
Packit Service 82fcde
    def __init__(self, mutexattr):
Packit Service 82fcde
        """Initialize the printer's internal data structures.
Packit Service 82fcde
Packit Service 82fcde
        Args:
Packit Service 82fcde
            mutexattr: A gdb.value representing a pthread_mutexattr_t.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        self.values = []
Packit Service 82fcde
Packit Service 82fcde
        try:
Packit Service 82fcde
            mutexattr_struct = gdb.lookup_type('struct pthread_mutexattr')
Packit Service 82fcde
            self.mutexattr = mutexattr.cast(mutexattr_struct)['mutexkind']
Packit Service 82fcde
            self.read_values()
Packit Service 82fcde
        except gdb.error:
Packit Service 82fcde
            # libpthread doesn't have debug symbols, thus we can't find the
Packit Service 82fcde
            # real struct type.  Just print the union members.
Packit Service 82fcde
            self.values.append(('__size', mutexattr['__size']))
Packit Service 82fcde
            self.values.append(('__align', mutexattr['__align']))
Packit Service 82fcde
Packit Service 82fcde
    def to_string(self):
Packit Service 82fcde
        """gdb API function.
Packit Service 82fcde
Packit Service 82fcde
        This is called from gdb when we try to print a pthread_mutexattr_t.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        return 'pthread_mutexattr_t'
Packit Service 82fcde
Packit Service 82fcde
    def children(self):
Packit Service 82fcde
        """gdb API function.
Packit Service 82fcde
Packit Service 82fcde
        This is called from gdb when we try to print a pthread_mutexattr_t.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        return self.values
Packit Service 82fcde
Packit Service 82fcde
    def read_values(self):
Packit Service 82fcde
        """Read the mutexattr's info and store it in self.values.
Packit Service 82fcde
Packit Service 82fcde
        The data contained in self.values will be returned by the Iterator
Packit Service 82fcde
        created in self.children.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        mutexattr_type = (self.mutexattr
Packit Service 82fcde
                          & ~PTHREAD_MUTEXATTR_FLAG_BITS
Packit Service 82fcde
                          & ~PTHREAD_MUTEX_NO_ELISION_NP)
Packit Service 82fcde
Packit Service 82fcde
        # mutexattr_type must be casted to int because it's a gdb.Value
Packit Service 82fcde
        self.values.append(MUTEX_TYPES[int(mutexattr_type)])
Packit Service 82fcde
Packit Service 82fcde
        if self.mutexattr & PTHREAD_MUTEXATTR_FLAG_ROBUST:
Packit Service 82fcde
            self.values.append(('Robust', 'Yes'))
Packit Service 82fcde
        else:
Packit Service 82fcde
            self.values.append(('Robust', 'No'))
Packit Service 82fcde
Packit Service 82fcde
        if self.mutexattr & PTHREAD_MUTEXATTR_FLAG_PSHARED:
Packit Service 82fcde
            self.values.append(('Shared', 'Yes'))
Packit Service 82fcde
        else:
Packit Service 82fcde
            self.values.append(('Shared', 'No'))
Packit Service 82fcde
Packit Service 82fcde
        protocol = ((self.mutexattr & PTHREAD_MUTEXATTR_PROTOCOL_MASK) >>
Packit Service 82fcde
                    PTHREAD_MUTEXATTR_PROTOCOL_SHIFT)
Packit Service 82fcde
Packit Service 82fcde
        if protocol == PTHREAD_PRIO_NONE:
Packit Service 82fcde
            self.values.append(('Protocol', 'None'))
Packit Service 82fcde
        elif protocol == PTHREAD_PRIO_INHERIT:
Packit Service 82fcde
            self.values.append(('Protocol', 'Priority inherit'))
Packit Service 82fcde
        elif protocol == PTHREAD_PRIO_PROTECT:
Packit Service 82fcde
            self.values.append(('Protocol', 'Priority protect'))
Packit Service 82fcde
Packit Service 82fcde
class ConditionVariablePrinter(object):
Packit Service 82fcde
    """Pretty printer for pthread_cond_t."""
Packit Service 82fcde
Packit Service 82fcde
    def __init__(self, cond):
Packit Service 82fcde
        """Initialize the printer's internal data structures.
Packit Service 82fcde
Packit Service 82fcde
        Args:
Packit Service 82fcde
            cond: A gdb.value representing a pthread_cond_t.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        data = cond['__data']
Packit Service 82fcde
        self.wrefs = data['__wrefs']
Packit Service 82fcde
        self.values = []
Packit Service 82fcde
Packit Service 82fcde
        self.read_values()
Packit Service 82fcde
Packit Service 82fcde
    def to_string(self):
Packit Service 82fcde
        """gdb API function.
Packit Service 82fcde
Packit Service 82fcde
        This is called from gdb when we try to print a pthread_cond_t.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        return 'pthread_cond_t'
Packit Service 82fcde
Packit Service 82fcde
    def children(self):
Packit Service 82fcde
        """gdb API function.
Packit Service 82fcde
Packit Service 82fcde
        This is called from gdb when we try to print a pthread_cond_t.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        return self.values
Packit Service 82fcde
Packit Service 82fcde
    def read_values(self):
Packit Service 82fcde
        """Read the condvar's info and store it in self.values.
Packit Service 82fcde
Packit Service 82fcde
        The data contained in self.values will be returned by the Iterator
Packit Service 82fcde
        created in self.children.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        self.read_status()
Packit Service 82fcde
        self.read_attributes()
Packit Service 82fcde
Packit Service 82fcde
    def read_status(self):
Packit Service 82fcde
        """Read the status of the condvar.
Packit Service 82fcde
Packit Service 82fcde
        This method reads whether the condvar is destroyed and how many threads
Packit Service 82fcde
        are waiting for it.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        self.values.append(('Threads known to still execute a wait function',
Packit Service 82fcde
                            self.wrefs >> PTHREAD_COND_WREFS_SHIFT))
Packit Service 82fcde
Packit Service 82fcde
    def read_attributes(self):
Packit Service 82fcde
        """Read the condvar's attributes."""
Packit Service 82fcde
Packit Service 82fcde
        if (self.wrefs & PTHREAD_COND_CLOCK_MONOTONIC_MASK) != 0:
Packit Service 82fcde
            self.values.append(('Clock ID', 'CLOCK_MONOTONIC'))
Packit Service 82fcde
        else:
Packit Service 82fcde
            self.values.append(('Clock ID', 'CLOCK_REALTIME'))
Packit Service 82fcde
Packit Service 82fcde
        if (self.wrefs & PTHREAD_COND_SHARED_MASK) != 0:
Packit Service 82fcde
            self.values.append(('Shared', 'Yes'))
Packit Service 82fcde
        else:
Packit Service 82fcde
            self.values.append(('Shared', 'No'))
Packit Service 82fcde
Packit Service 82fcde
class ConditionVariableAttributesPrinter(object):
Packit Service 82fcde
    """Pretty printer for pthread_condattr_t.
Packit Service 82fcde
Packit Service 82fcde
    In the NPTL this is a type that's always casted to struct pthread_condattr,
Packit Service 82fcde
    which has a single 'value' field containing the actual attributes.
Packit Service 82fcde
    """
Packit Service 82fcde
Packit Service 82fcde
    def __init__(self, condattr):
Packit Service 82fcde
        """Initialize the printer's internal data structures.
Packit Service 82fcde
Packit Service 82fcde
        Args:
Packit Service 82fcde
            condattr: A gdb.value representing a pthread_condattr_t.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        self.values = []
Packit Service 82fcde
Packit Service 82fcde
        try:
Packit Service 82fcde
            condattr_struct = gdb.lookup_type('struct pthread_condattr')
Packit Service 82fcde
            self.condattr = condattr.cast(condattr_struct)['value']
Packit Service 82fcde
            self.read_values()
Packit Service 82fcde
        except gdb.error:
Packit Service 82fcde
            # libpthread doesn't have debug symbols, thus we can't find the
Packit Service 82fcde
            # real struct type.  Just print the union members.
Packit Service 82fcde
            self.values.append(('__size', condattr['__size']))
Packit Service 82fcde
            self.values.append(('__align', condattr['__align']))
Packit Service 82fcde
Packit Service 82fcde
    def to_string(self):
Packit Service 82fcde
        """gdb API function.
Packit Service 82fcde
Packit Service 82fcde
        This is called from gdb when we try to print a pthread_condattr_t.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        return 'pthread_condattr_t'
Packit Service 82fcde
Packit Service 82fcde
    def children(self):
Packit Service 82fcde
        """gdb API function.
Packit Service 82fcde
Packit Service 82fcde
        This is called from gdb when we try to print a pthread_condattr_t.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        return self.values
Packit Service 82fcde
Packit Service 82fcde
    def read_values(self):
Packit Service 82fcde
        """Read the condattr's info and store it in self.values.
Packit Service 82fcde
Packit Service 82fcde
        The data contained in self.values will be returned by the Iterator
Packit Service 82fcde
        created in self.children.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        clock_id = (self.condattr >> 1) & ((1 << COND_CLOCK_BITS) - 1)
Packit Service 82fcde
Packit Service 82fcde
        if clock_id != 0:
Packit Service 82fcde
            self.values.append(('Clock ID', 'CLOCK_MONOTONIC'))
Packit Service 82fcde
        else:
Packit Service 82fcde
            self.values.append(('Clock ID', 'CLOCK_REALTIME'))
Packit Service 82fcde
Packit Service 82fcde
        if self.condattr & 1:
Packit Service 82fcde
            self.values.append(('Shared', 'Yes'))
Packit Service 82fcde
        else:
Packit Service 82fcde
            self.values.append(('Shared', 'No'))
Packit Service 82fcde
Packit Service 82fcde
class RWLockPrinter(object):
Packit Service 82fcde
    """Pretty printer for pthread_rwlock_t."""
Packit Service 82fcde
Packit Service 82fcde
    def __init__(self, rwlock):
Packit Service 82fcde
        """Initialize the printer's internal data structures.
Packit Service 82fcde
Packit Service 82fcde
        Args:
Packit Service 82fcde
            rwlock: A gdb.value representing a pthread_rwlock_t.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        data = rwlock['__data']
Packit Service 82fcde
        self.readers = data['__readers']
Packit Service 82fcde
        self.cur_writer = data['__cur_writer']
Packit Service 82fcde
        self.shared = data['__shared']
Packit Service 82fcde
        self.flags = data['__flags']
Packit Service 82fcde
        self.values = []
Packit Service 82fcde
        self.read_values()
Packit Service 82fcde
Packit Service 82fcde
    def to_string(self):
Packit Service 82fcde
        """gdb API function.
Packit Service 82fcde
Packit Service 82fcde
        This is called from gdb when we try to print a pthread_rwlock_t.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        return 'pthread_rwlock_t'
Packit Service 82fcde
Packit Service 82fcde
    def children(self):
Packit Service 82fcde
        """gdb API function.
Packit Service 82fcde
Packit Service 82fcde
        This is called from gdb when we try to print a pthread_rwlock_t.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        return self.values
Packit Service 82fcde
Packit Service 82fcde
    def read_values(self):
Packit Service 82fcde
        """Read the rwlock's info and store it in self.values.
Packit Service 82fcde
Packit Service 82fcde
        The data contained in self.values will be returned by the Iterator
Packit Service 82fcde
        created in self.children.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        self.read_status()
Packit Service 82fcde
        self.read_attributes()
Packit Service 82fcde
Packit Service 82fcde
    def read_status(self):
Packit Service 82fcde
        """Read the status of the rwlock."""
Packit Service 82fcde
Packit Service 82fcde
        if self.readers & PTHREAD_RWLOCK_WRPHASE:
Packit Service 82fcde
            if self.readers & PTHREAD_RWLOCK_WRLOCKED:
Packit Service 82fcde
                self.values.append(('Status', 'Acquired (Write)'))
Packit Service 82fcde
                self.values.append(('Writer ID', self.cur_writer))
Packit Service 82fcde
            else:
Packit Service 82fcde
                self.values.append(('Status', 'Not acquired'))
Packit Service 82fcde
        else:
Packit Service 82fcde
            r = self.readers >> PTHREAD_RWLOCK_READER_SHIFT
Packit Service 82fcde
            if r > 0:
Packit Service 82fcde
                self.values.append(('Status', 'Acquired (Read)'))
Packit Service 82fcde
                self.values.append(('Readers', r))
Packit Service 82fcde
            else:
Packit Service 82fcde
                self.values.append(('Status', 'Not acquired'))
Packit Service 82fcde
Packit Service 82fcde
    def read_attributes(self):
Packit Service 82fcde
        """Read the attributes of the rwlock."""
Packit Service 82fcde
Packit Service 82fcde
        if self.shared:
Packit Service 82fcde
            self.values.append(('Shared', 'Yes'))
Packit Service 82fcde
        else:
Packit Service 82fcde
            self.values.append(('Shared', 'No'))
Packit Service 82fcde
Packit Service 82fcde
        if self.flags == PTHREAD_RWLOCK_PREFER_READER_NP:
Packit Service 82fcde
            self.values.append(('Prefers', 'Readers'))
Packit Service 82fcde
        elif self.flags == PTHREAD_RWLOCK_PREFER_WRITER_NP:
Packit Service 82fcde
            self.values.append(('Prefers', 'Writers'))
Packit Service 82fcde
        else:
Packit Service 82fcde
            self.values.append(('Prefers', 'Writers no recursive readers'))
Packit Service 82fcde
Packit Service 82fcde
class RWLockAttributesPrinter(object):
Packit Service 82fcde
    """Pretty printer for pthread_rwlockattr_t.
Packit Service 82fcde
Packit Service 82fcde
    In the NPTL this is a type that's always casted to
Packit Service 82fcde
    struct pthread_rwlockattr, which has two fields ('lockkind' and 'pshared')
Packit Service 82fcde
    containing the actual attributes.
Packit Service 82fcde
    """
Packit Service 82fcde
Packit Service 82fcde
    def __init__(self, rwlockattr):
Packit Service 82fcde
        """Initialize the printer's internal data structures.
Packit Service 82fcde
Packit Service 82fcde
        Args:
Packit Service 82fcde
            rwlockattr: A gdb.value representing a pthread_rwlockattr_t.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        self.values = []
Packit Service 82fcde
Packit Service 82fcde
        try:
Packit Service 82fcde
            rwlockattr_struct = gdb.lookup_type('struct pthread_rwlockattr')
Packit Service 82fcde
            self.rwlockattr = rwlockattr.cast(rwlockattr_struct)
Packit Service 82fcde
            self.read_values()
Packit Service 82fcde
        except gdb.error:
Packit Service 82fcde
            # libpthread doesn't have debug symbols, thus we can't find the
Packit Service 82fcde
            # real struct type.  Just print the union members.
Packit Service 82fcde
            self.values.append(('__size', rwlockattr['__size']))
Packit Service 82fcde
            self.values.append(('__align', rwlockattr['__align']))
Packit Service 82fcde
Packit Service 82fcde
    def to_string(self):
Packit Service 82fcde
        """gdb API function.
Packit Service 82fcde
Packit Service 82fcde
        This is called from gdb when we try to print a pthread_rwlockattr_t.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        return 'pthread_rwlockattr_t'
Packit Service 82fcde
Packit Service 82fcde
    def children(self):
Packit Service 82fcde
        """gdb API function.
Packit Service 82fcde
Packit Service 82fcde
        This is called from gdb when we try to print a pthread_rwlockattr_t.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        return self.values
Packit Service 82fcde
Packit Service 82fcde
    def read_values(self):
Packit Service 82fcde
        """Read the rwlockattr's info and store it in self.values.
Packit Service 82fcde
Packit Service 82fcde
        The data contained in self.values will be returned by the Iterator
Packit Service 82fcde
        created in self.children.
Packit Service 82fcde
        """
Packit Service 82fcde
Packit Service 82fcde
        rwlock_type = self.rwlockattr['lockkind']
Packit Service 82fcde
        shared = self.rwlockattr['pshared']
Packit Service 82fcde
Packit Service 82fcde
        if shared == PTHREAD_PROCESS_SHARED:
Packit Service 82fcde
            self.values.append(('Shared', 'Yes'))
Packit Service 82fcde
        else:
Packit Service 82fcde
            # PTHREAD_PROCESS_PRIVATE
Packit Service 82fcde
            self.values.append(('Shared', 'No'))
Packit Service 82fcde
Packit Service 82fcde
        if rwlock_type == PTHREAD_RWLOCK_PREFER_READER_NP:
Packit Service 82fcde
            self.values.append(('Prefers', 'Readers'))
Packit Service 82fcde
        elif rwlock_type == PTHREAD_RWLOCK_PREFER_WRITER_NP:
Packit Service 82fcde
            self.values.append(('Prefers', 'Writers'))
Packit Service 82fcde
        else:
Packit Service 82fcde
            self.values.append(('Prefers', 'Writers no recursive readers'))
Packit Service 82fcde
Packit Service 82fcde
def register(objfile):
Packit Service 82fcde
    """Register the pretty printers within the given objfile."""
Packit Service 82fcde
Packit Service 82fcde
    printer = gdb.printing.RegexpCollectionPrettyPrinter('glibc-pthread-locks')
Packit Service 82fcde
Packit Service 82fcde
    printer.add_printer('pthread_mutex_t', r'^pthread_mutex_t$',
Packit Service 82fcde
                        MutexPrinter)
Packit Service 82fcde
    printer.add_printer('pthread_mutexattr_t', r'^pthread_mutexattr_t$',
Packit Service 82fcde
                        MutexAttributesPrinter)
Packit Service 82fcde
    printer.add_printer('pthread_cond_t', r'^pthread_cond_t$',
Packit Service 82fcde
                        ConditionVariablePrinter)
Packit Service 82fcde
    printer.add_printer('pthread_condattr_t', r'^pthread_condattr_t$',
Packit Service 82fcde
                        ConditionVariableAttributesPrinter)
Packit Service 82fcde
    printer.add_printer('pthread_rwlock_t', r'^pthread_rwlock_t$',
Packit Service 82fcde
                        RWLockPrinter)
Packit Service 82fcde
    printer.add_printer('pthread_rwlockattr_t', r'^pthread_rwlockattr_t$',
Packit Service 82fcde
                        RWLockAttributesPrinter)
Packit Service 82fcde
Packit Service 82fcde
    if objfile == None:
Packit Service 82fcde
        objfile = gdb
Packit Service 82fcde
Packit Service 82fcde
    gdb.printing.register_pretty_printer(objfile, printer)
Packit Service 82fcde
Packit Service 82fcde
register(gdb.current_objfile())