Summary: | ASTERISK-22455: Asterisk 12 on Ubuntu Lucid deadlocks with DEBUG_THREADS+OPTIONAL_API enabled | ||
Reporter: | David M. Lee (dlee) | Labels: | |
Date Opened: | 2013-09-04 09:22:05 | Date Closed: | 2013-09-09 15:00:01 |
Priority: | Blocker | Regression? | |
Status: | Closed/Complete | Components: | |
Versions: | 12.0.0-alpha1 | Frequency of Occurrence | |
Related Issues: | |||
Environment: | Attachments: | ||
Description: | @mmichelson discovered that Asterisk 12 will deadlock when DEBUG_THREADS+OPTIONAL_API is enabled, on Ubuntu Lucid.
It deadlocks consistently on startup with the sample config installed. I've tried various permutations trying to narrow down the problem. * Ubuntu Raring - no deadlock * CentOS 5 - no deadlock * Disable DEBUG_THREADS - no deadlock * Disable OPTIONAL_API - no deadlock * Update to r397988 (before the optional_api changes) - no deadlock | ||
Comments: | By: David M. Lee (dlee) 2013-09-04 12:46:23.738-0500 Figured it out. When debug threads are enabled, {{ast_pthread_mutex_lock}} invokes {{backtrace()}}. In Lucid's libc (glibc-2.11.1), {{backtrace()}} ends up calling {{dl_iterate_phdr()}}, which "allows an application to inquire at run time to find out which shared objects it has loaded". When log functions are called from {{__constructor__}} functions, they execute during a {{dlopen()}}. If glibc holds a lock while this happens, then it's a classic lock ordering problem. dlopen() locks the module list, then (buried in some calls) it locks the {{logmsgs}} reentrancy lock (for debug threads). The logger thread locks the {{logmsgs}} reentrancy lock, then (buried in {{backtrace()}}) locks the module list. {code} Main thread | Logger thread -----------------------------------+----------------------------- - dlopen() | - AST_LIST_LOCK(&logmsgs) - lock(dl) | - ast_reentrancy_lock(lt) - __constructor__ | - backtrace() - ast_verb() | - lock(dl) - AST_LIST_LOCK(&logmsgs) | *** DEADLOCK *** - ast_reentrancy_lock(lt) | *** DEADLOCK *** | {code} |