• Kristian Nielsen's avatar
    MDEV-6582: DEBUG_SYNC does not reset mysys_var->current_mutex, causes... · 06d0d090
    Kristian Nielsen authored
    MDEV-6582: DEBUG_SYNC does not reset mysys_var->current_mutex, causes assertion "Trying to unlock mutex that wasn't locked"
    
    The bug was in DEBUG_SYNC. When waiting, debug_sync_execute() temporarily sets
    thd->mysys_var->current_mutex to a new value while waiting. However, if the
    old value of current_mutex was NULL, it was not restored, current_mutex
    remained set to the temporary value (debug_sync_global.ds_mutex).
    
    This made possible the following race: Thread T1 goes to KILL thread T2. In
    THD::awake(), T1 loads T2->mysys_var->current_mutex, it is set to ds_mutex, T1
    locks this mutex.
    
    Now T2 runs, it does ENTER_COND, it sets T2->mysys_var->current_mutex to
    LOCK_wait_commit (for example).
    
    Then T1 resumes, it reloads mysys_var->current_mutex, now it is set to
    LOCK_wait_commit, T1 unlocks this mutex instead of the ds_mutex that it locked
    previously.
    
    This causes safe_mutex to assert with the message: "Trying to unlock mutex
    LOCK_wait_commit that wasn't locked".
    
    The fix is to ensure that DEBUG_SYNC also will restore
    mysys_var->current_mutex in the case where the original value was NULL.
    
    06d0d090
debug_sync.cc 47.7 KB