Search⌘ K
AI Features

Identify Deadlocks

Explore how to identify deadlocks by analyzing Linux core dumps. Understand how to list thread stack traces, examine mutex ownership, and investigate exception handling to diagnose deadlock causes in multi-threaded applications.

Deadlocks occur frequently in the absence of proper concurrency management. In this lesson, we’ll see how to identify them from the core dump.

Application source code

For reference, here’s the code of this application:

C
// Build (App11):
// g++ main.cpp -pthread -static -o App11
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
pthread_mutex_t mutexA, mutexB;
void procC()
{
throw 0;
}
void procA()
{
try
{
pthread_mutex_lock(&mutexA);
procC();
pthread_mutex_unlock(&mutexA);
}
catch (...)
{
}
sleep(20);
pthread_mutex_lock(&mutexB);
pthread_mutex_unlock(&mutexB);
}
void procB()
{
pthread_mutex_lock(&mutexB);
pthread_mutex_lock(&mutexA);
sleep(30);
pthread_mutex_lock(&mutexA);
pthread_mutex_lock(&mutexB);
}
#define THREAD_DECLARE(num, func) \
void bar_##num() \
{ \
func; \
} \
\
void foo_##num() \
{ \
bar_##num(); \
} \
\
void *thread_##num(void *arg) \
{ \
foo_##num(); \
return 0; \
}
THREAD_DECLARE(one, sleep(-1))
THREAD_DECLARE(two, procA())
THREAD_DECLARE(three, sleep(-1))
THREAD_DECLARE(four, procB())
THREAD_DECLARE(five, sleep(-1))
#define THREAD_CREATE(num) \
{ \
pthread_t threadID_##num; \
pthread_create(&threadID_##num, NULL, thread_##num, NULL); \
}
int main(int argc, const char *argv[])
{
pthread_mutex_init(&mutexA, NULL);
pthread_mutex_init(&mutexB, NULL);
THREAD_CREATE(one)
THREAD_CREATE(two)
sleep(10);
THREAD_CREATE(three)
THREAD_CREATE(four)
THREAD_CREATE(five)
sleep(-1);
return 0;
}

Loading the core dump

Start by loading the core dump:

gdb -c App11.core.594 -se App11

The above command will output the following to the terminal:

Listing all thread stacks

We can list all the thread stack traces and identify possible wait chains and deadlocks.

thread apply all bt

The above command will output the following to the terminal:

We see that Thread 3 and Thread 5 are waiting ...