Please sign in to comment.
Use flag instead of lock state to track running status
LLDB requires that the inferior process be stopped before, and remain stopped during, certain accesses to process state. Previously this was achieved with a wrlock that was held while the process was running, and released while the process was stopped. Any access to process state was performed with a read lock held. POSIX requires that pthread_rwlock_unlock() be called from the same thread as pthread_rwlock_wrlock(), but lldb needs to stop and start the process from different threads. All read lock consumers use ReadTryLock() and handle failure to obtain the lock (typically by logging an error "process is running"). Thus, instead of using the lock state itself to track the running state, add an explicit m_running flag. ReadTryLock tests the flag, and keeps the read lock held if available. WriteLock and WriteTryLock (if successful) set m_running with the lock held. This way, read consumers can determine if the process is running and act appropriately, and write consumers are still held off from starting the process if read consumers are active. Note that with this change there are still some questionable access patterns, such as calling WriteUnlock twice in a row, and there's no protection from multiple threads trying to simultaneously start the process (i.e., take the write lock). In practice this does not seem to be a problem, and was already exposing undefined POSIX behaviour. This is a proof of concept patch, and should be cleaned up further assuming the approach is sound -- at least, ReadLock / WriteLock should be renamed.
- Loading branch information...