diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | README.pretty-printers | 7 | ||||
-rw-r--r-- | nptl/nptl-printers.py | 33 | ||||
-rw-r--r-- | nptl/test-mutex-printers.py | 17 |
4 files changed, 43 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog index 47fccc7642..9573c5c4b2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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> * sysdeps/unix/sysv/linux/s390/htm.h: Adjust comments. diff --git a/README.pretty-printers b/README.pretty-printers index a2536cad80..2522cb858d 100644 --- a/README.pretty-printers +++ b/README.pretty-printers @@ -29,7 +29,7 @@ However, with a pretty printer gdb will output something like this: (gdb) print mutex $1 = pthread_mutex_t = { Type = Normal, - Status = Unlocked, + Status = Not acquired, Robust = No, Shared = No, 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 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 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 diff --git a/nptl/nptl-printers.py b/nptl/nptl-printers.py index 9d67865577..572a25c32e 100644 --- a/nptl/nptl-printers.py +++ b/nptl/nptl-printers.py @@ -101,9 +101,9 @@ class MutexPrinter(object): 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). + Architectures that support lock elision might not record the mutex owner + ID in the __owner field. In that case, the owner will be reported as + "Unknown". """ if self.kind == PTHREAD_MUTEX_DESTROYED: @@ -124,13 +124,14 @@ class MutexPrinter(object): """ if self.lock == PTHREAD_MUTEX_UNLOCKED: - self.values.append(('Status', 'Unlocked')) + self.values.append(('Status', 'Not acquired')) else: if self.lock & FUTEX_WAITERS: - self.values.append(('Status', 'Locked, possibly with waiters')) + self.values.append(('Status', + 'Acquired, possibly with waiters')) else: self.values.append(('Status', - 'Locked, possibly with no waiters')) + 'Acquired, possibly with no waiters')) if self.lock & FUTEX_OWNER_DIED: self.values.append(('Owner ID', '%d (dead)' % self.owner)) @@ -147,7 +148,7 @@ class MutexPrinter(object): 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 + Read info on whether the mutex is acquired, if it may have waiters and its owner (if any). """ @@ -157,7 +158,7 @@ class MutexPrinter(object): lock_value &= ~(PTHREAD_MUTEX_PRIO_CEILING_MASK) if lock_value == PTHREAD_MUTEX_UNLOCKED: - self.values.append(('Status', 'Unlocked')) + self.values.append(('Status', 'Not acquired')) else: if self.kind & PTHREAD_MUTEX_PRIO_INHERIT_NP: waiters = self.lock & FUTEX_WAITERS @@ -168,12 +169,18 @@ class MutexPrinter(object): owner = self.owner if waiters: - self.values.append(('Status', 'Locked, possibly with waiters')) + self.values.append(('Status', + 'Acquired, possibly with waiters')) else: self.values.append(('Status', - 'Locked, possibly with no waiters')) + 'Acquired, possibly with no waiters')) - self.values.append(('Owner ID', owner)) + if self.owner != 0: + 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): """Read the mutex's attributes.""" @@ -208,14 +215,14 @@ class MutexPrinter(object): def read_misc_info(self): """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. """ 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)) + self.values.append(('Times acquired by the owner', self.count)) class MutexAttributesPrinter(object): """Pretty printer for pthread_mutexattr_t. diff --git a/nptl/test-mutex-printers.py b/nptl/test-mutex-printers.py index 23f16b0b71..687a32c4f7 100644 --- a/nptl/test-mutex-printers.py +++ b/nptl/test-mutex-printers.py @@ -39,15 +39,18 @@ try: break_at(test_source, 'Test status (non-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() thread_id = get_current_thread_lwpid() - test_printer(var, to_string, {'Status': 'Locked, possibly with no waiters', - 'Owner ID': thread_id}) + # Owner ID might be reported either as the thread ID or as "Unknown" + # (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)') 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 # 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, 'State protected by this mutex': 'Inconsistent'}) next_cmd() - test_printer(var, to_string, {'Status': 'Unlocked', + test_printer(var, to_string, {'Status': 'Not acquired', 'State protected by this mutex': 'Not recoverable'}) set_scheduler_locking(False) break_at(test_source, '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() - test_printer(var, to_string, {'Times locked recursively': '3'}) + test_printer(var, to_string, {'Times acquired by the owner': '3'}) continue_cmd() # Exit except (NoLineError, pexpect.TIMEOUT) as exception: |