Why is my CRITICAL_SECTION's RecursionCount so large? Debugging a deadlock


I've combined my Eagle GUI library with Allegro 5 for graphics and input. When I use Allegro 5's al_register_trace_handler function to pipe the output from allegro's debugging log to my own, I get a deadlock in a thread spawned by allegro to create a win32 window and display. It specifically hangs on a call to ALLEGRO_INFO which is a logging macro used by allegro. The CRITICAL_SECTION used to prevent race conditions in the log shows up as held by my main thread. When I output the CRITICAL_SECTION in gdb, I get the following report :

(gdb) p *(trace_info.trace_mutex.cs)
$1 = {DebugInfo = 0xffffffff, LockCount = -2, RecursionCount = 176, OwningThread = 0x4750, LockSemaphore = 0x0, SpinCount = 33556432}

Thread 4750 is Main as identified by gdb and info threads. If I don't register a trace handler with allegro, everything works fine, but if I do, and I use a debugging level of 'Debug' or 'Info' it deadlocks in the mentioned log output call. I found a case where the allegro trace function wasn't releasing the CRITICAL_SECTION in the case of a registered trace handler and I thought that would fix it by releasing the lock, but it did nothing, and the output remains the same.

Does the value of the ReferenceCount field in the critical section indicate a failure to properly unlock the log's mutex (CS) and why is the lock still held by the main thread?

I'm reaching the end of my debugging skills. I log the state of all my own threads and none of them are in contention. But the fact that main holds the CRITICAL_SECTION being used by allegro in a different thread seems to indicate I've done something wrong.

So, any help getting relevant info out of allegro and gdb would be appreciated. Like I said, it works fine if I don't register a trace handler, but if I do, it hangs on allegro code.

Advice and debugging tips welcome. Please and thank you for helping me out. Marc

asked on Stack Overflow May 12, 2021 by BugSquasher • edited May 12, 2021 by BugSquasher

1 Answer


The offending missing LeaveCriticalSection call was left out in the path in allegro code where a user trace handler was used. The following patch fixed the problem.

--- C:/Users/Marc/AppData/Local/Temp/TortoiseGit/debug-619c69e3.002.c   Thu May 13 11:18:03 2021
+++ E:/usr/libs/Allegro52X/src/debug.c  Wed May 12 11:20:57 2021
@@ -300,6 +300,7 @@
    if (_al_user_trace_handler) {
       static_trace_buffer[0] = '\0';
+      _al_mutex_unlock(&trace_info.trace_mutex);
answered on Stack Overflow May 13, 2021 by BugSquasher

User contributions licensed under CC BY-SA 3.0