mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-01 10:06:57 +03:00
Fix mutex pretty printer test and pretty printer output.
This fixes the mutex pretty printer so that, if the owner ID isn't recorded (such as in the current lock elision implementation), "Owner ID" will be shown as "Unknown" instead of 0. It also changes the mutex printer output so that it says "Acquired" instead of "Locked". The mutex tests are updated accordingly. In addition, this adds a paragraph to the "Known issues" section of the printers README explaining that the printer output isn't guaranteed to cover every detail. 2017-01-14 Martin Galvan <martingalvan@sourceware.org> * README.pretty-printers (Known issues): Warn about printers not always covering everything. * nptl/nptl-printers.py (MutexPrinter): Change output. * nptl/test-mutex-printers.py: Fix test and adapt to changed output.
This commit is contained in:
@ -1,3 +1,10 @@
|
|||||||
|
2017-01-14 Martin Galvan <martingalvan@sourceware.org>
|
||||||
|
|
||||||
|
* README.pretty-printers (Known issues): Warn about printers not
|
||||||
|
always covering everything.
|
||||||
|
* nptl/nptl-printers.py (MutexPrinter): Change output.
|
||||||
|
* nptl/test-mutex-printers.py: Fix test and adapt to changed output.
|
||||||
|
|
||||||
2017-01-20 Stefan Liebler <stli@linux.vnet.ibm.com>
|
2017-01-20 Stefan Liebler <stli@linux.vnet.ibm.com>
|
||||||
|
|
||||||
* sysdeps/unix/sysv/linux/s390/htm.h: Adjust comments.
|
* sysdeps/unix/sysv/linux/s390/htm.h: Adjust comments.
|
||||||
|
@ -29,7 +29,7 @@ However, with a pretty printer gdb will output something like this:
|
|||||||
(gdb) print mutex
|
(gdb) print mutex
|
||||||
$1 = pthread_mutex_t = {
|
$1 = pthread_mutex_t = {
|
||||||
Type = Normal,
|
Type = Normal,
|
||||||
Status = Unlocked,
|
Status = Not acquired,
|
||||||
Robust = No,
|
Robust = No,
|
||||||
Shared = No,
|
Shared = No,
|
||||||
Protocol = Priority protect,
|
Protocol = Priority protect,
|
||||||
@ -145,6 +145,11 @@ any changes to the target code must also update the corresponding printers.
|
|||||||
On the plus side, the printer code itself may serve as a kind of documentation
|
On the plus side, the printer code itself may serve as a kind of documentation
|
||||||
for the target code.
|
for the target code.
|
||||||
|
|
||||||
|
* There's no guarantee that the information the pretty printers provide is
|
||||||
|
complete, i.e. some details might be left off. For example, the pthread_mutex_t
|
||||||
|
printers won't report whether a thread is spin-waiting in an attempt to acquire
|
||||||
|
the mutex.
|
||||||
|
|
||||||
* Older versions of the gdb Python API have a bug where
|
* Older versions of the gdb Python API have a bug where
|
||||||
gdb.RegexpCollectionPrettyPrinter would not be able to get a value's real type
|
gdb.RegexpCollectionPrettyPrinter would not be able to get a value's real type
|
||||||
if it was typedef'd. This would cause gdb to ignore the pretty printers for
|
if it was typedef'd. This would cause gdb to ignore the pretty printers for
|
||||||
|
@ -101,9 +101,9 @@ class MutexPrinter(object):
|
|||||||
def read_status(self):
|
def read_status(self):
|
||||||
"""Read the mutex's status.
|
"""Read the mutex's status.
|
||||||
|
|
||||||
For architectures which support lock elision, this method reads
|
Architectures that support lock elision might not record the mutex owner
|
||||||
whether the mutex appears as locked in memory (i.e. it may show it as
|
ID in the __owner field. In that case, the owner will be reported as
|
||||||
unlocked even after calling pthread_mutex_lock).
|
"Unknown".
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.kind == PTHREAD_MUTEX_DESTROYED:
|
if self.kind == PTHREAD_MUTEX_DESTROYED:
|
||||||
@ -124,13 +124,14 @@ class MutexPrinter(object):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if self.lock == PTHREAD_MUTEX_UNLOCKED:
|
if self.lock == PTHREAD_MUTEX_UNLOCKED:
|
||||||
self.values.append(('Status', 'Unlocked'))
|
self.values.append(('Status', 'Not acquired'))
|
||||||
else:
|
else:
|
||||||
if self.lock & FUTEX_WAITERS:
|
if self.lock & FUTEX_WAITERS:
|
||||||
self.values.append(('Status', 'Locked, possibly with waiters'))
|
self.values.append(('Status',
|
||||||
|
'Acquired, possibly with waiters'))
|
||||||
else:
|
else:
|
||||||
self.values.append(('Status',
|
self.values.append(('Status',
|
||||||
'Locked, possibly with no waiters'))
|
'Acquired, possibly with no waiters'))
|
||||||
|
|
||||||
if self.lock & FUTEX_OWNER_DIED:
|
if self.lock & FUTEX_OWNER_DIED:
|
||||||
self.values.append(('Owner ID', '%d (dead)' % self.owner))
|
self.values.append(('Owner ID', '%d (dead)' % self.owner))
|
||||||
@ -147,7 +148,7 @@ class MutexPrinter(object):
|
|||||||
def read_status_no_robust(self):
|
def read_status_no_robust(self):
|
||||||
"""Read the status of a non-robust mutex.
|
"""Read the status of a non-robust mutex.
|
||||||
|
|
||||||
Read info on whether the mutex is locked, if it may have waiters
|
Read info on whether the mutex is acquired, if it may have waiters
|
||||||
and its owner (if any).
|
and its owner (if any).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -157,7 +158,7 @@ class MutexPrinter(object):
|
|||||||
lock_value &= ~(PTHREAD_MUTEX_PRIO_CEILING_MASK)
|
lock_value &= ~(PTHREAD_MUTEX_PRIO_CEILING_MASK)
|
||||||
|
|
||||||
if lock_value == PTHREAD_MUTEX_UNLOCKED:
|
if lock_value == PTHREAD_MUTEX_UNLOCKED:
|
||||||
self.values.append(('Status', 'Unlocked'))
|
self.values.append(('Status', 'Not acquired'))
|
||||||
else:
|
else:
|
||||||
if self.kind & PTHREAD_MUTEX_PRIO_INHERIT_NP:
|
if self.kind & PTHREAD_MUTEX_PRIO_INHERIT_NP:
|
||||||
waiters = self.lock & FUTEX_WAITERS
|
waiters = self.lock & FUTEX_WAITERS
|
||||||
@ -168,12 +169,18 @@ class MutexPrinter(object):
|
|||||||
owner = self.owner
|
owner = self.owner
|
||||||
|
|
||||||
if waiters:
|
if waiters:
|
||||||
self.values.append(('Status', 'Locked, possibly with waiters'))
|
self.values.append(('Status',
|
||||||
|
'Acquired, possibly with waiters'))
|
||||||
else:
|
else:
|
||||||
self.values.append(('Status',
|
self.values.append(('Status',
|
||||||
'Locked, possibly with no waiters'))
|
'Acquired, possibly with no waiters'))
|
||||||
|
|
||||||
|
if self.owner != 0:
|
||||||
self.values.append(('Owner ID', owner))
|
self.values.append(('Owner ID', owner))
|
||||||
|
else:
|
||||||
|
# Owner isn't recorded, probably because lock elision
|
||||||
|
# is enabled.
|
||||||
|
self.values.append(('Owner ID', 'Unknown'))
|
||||||
|
|
||||||
def read_attributes(self):
|
def read_attributes(self):
|
||||||
"""Read the mutex's attributes."""
|
"""Read the mutex's attributes."""
|
||||||
@ -208,14 +215,14 @@ class MutexPrinter(object):
|
|||||||
def read_misc_info(self):
|
def read_misc_info(self):
|
||||||
"""Read miscellaneous info on the mutex.
|
"""Read miscellaneous info on the mutex.
|
||||||
|
|
||||||
For now this reads the number of times a recursive mutex was locked
|
For now this reads the number of times a recursive mutex was acquired
|
||||||
by the same thread.
|
by the same thread.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
mutex_type = self.kind & PTHREAD_MUTEX_KIND_MASK
|
mutex_type = self.kind & PTHREAD_MUTEX_KIND_MASK
|
||||||
|
|
||||||
if mutex_type == PTHREAD_MUTEX_RECURSIVE and self.count > 1:
|
if mutex_type == PTHREAD_MUTEX_RECURSIVE and self.count > 1:
|
||||||
self.values.append(('Times locked recursively', self.count))
|
self.values.append(('Times acquired by the owner', self.count))
|
||||||
|
|
||||||
class MutexAttributesPrinter(object):
|
class MutexAttributesPrinter(object):
|
||||||
"""Pretty printer for pthread_mutexattr_t.
|
"""Pretty printer for pthread_mutexattr_t.
|
||||||
|
@ -39,15 +39,18 @@ try:
|
|||||||
|
|
||||||
break_at(test_source, 'Test status (non-robust)')
|
break_at(test_source, 'Test status (non-robust)')
|
||||||
continue_cmd() # Go to test_status_no_robust
|
continue_cmd() # Go to test_status_no_robust
|
||||||
test_printer(var, to_string, {'Status': 'Unlocked'})
|
test_printer(var, to_string, {'Status': 'Not acquired'})
|
||||||
next_cmd()
|
next_cmd()
|
||||||
thread_id = get_current_thread_lwpid()
|
thread_id = get_current_thread_lwpid()
|
||||||
test_printer(var, to_string, {'Status': 'Locked, possibly with no waiters',
|
# Owner ID might be reported either as the thread ID or as "Unknown"
|
||||||
'Owner ID': thread_id})
|
# (if e.g. lock elision is enabled).
|
||||||
|
test_printer(var, to_string,
|
||||||
|
{'Status': 'Acquired, possibly with no waiters',
|
||||||
|
'Owner ID': r'({0}|Unknown)'.format(thread_id)})
|
||||||
|
|
||||||
break_at(test_source, 'Test status (robust)')
|
break_at(test_source, 'Test status (robust)')
|
||||||
continue_cmd() # Go to test_status_robust
|
continue_cmd() # Go to test_status_robust
|
||||||
test_printer(var, to_string, {'Status': 'Unlocked'})
|
test_printer(var, to_string, {'Status': 'Not acquired'})
|
||||||
|
|
||||||
# We'll now test the robust mutex locking states. We'll create a new
|
# We'll now test the robust mutex locking states. We'll create a new
|
||||||
# thread that will lock a robust mutex and exit without unlocking it.
|
# thread that will lock a robust mutex and exit without unlocking it.
|
||||||
@ -75,15 +78,15 @@ try:
|
|||||||
test_printer(var, to_string, {'Owner ID': thread_id,
|
test_printer(var, to_string, {'Owner ID': thread_id,
|
||||||
'State protected by this mutex': 'Inconsistent'})
|
'State protected by this mutex': 'Inconsistent'})
|
||||||
next_cmd()
|
next_cmd()
|
||||||
test_printer(var, to_string, {'Status': 'Unlocked',
|
test_printer(var, to_string, {'Status': 'Not acquired',
|
||||||
'State protected by this mutex': 'Not recoverable'})
|
'State protected by this mutex': 'Not recoverable'})
|
||||||
set_scheduler_locking(False)
|
set_scheduler_locking(False)
|
||||||
|
|
||||||
break_at(test_source, 'Test recursive locks')
|
break_at(test_source, 'Test recursive locks')
|
||||||
continue_cmd() # Go to test_recursive_locks
|
continue_cmd() # Go to test_recursive_locks
|
||||||
test_printer(var, to_string, {'Times locked recursively': '2'})
|
test_printer(var, to_string, {'Times acquired by the owner': '2'})
|
||||||
next_cmd()
|
next_cmd()
|
||||||
test_printer(var, to_string, {'Times locked recursively': '3'})
|
test_printer(var, to_string, {'Times acquired by the owner': '3'})
|
||||||
continue_cmd() # Exit
|
continue_cmd() # Exit
|
||||||
|
|
||||||
except (NoLineError, pexpect.TIMEOUT) as exception:
|
except (NoLineError, pexpect.TIMEOUT) as exception:
|
||||||
|
Reference in New Issue
Block a user