Linux GDB分析死锁

目录

示例代码

分析

结论


示例代码

// DeadLock.cpp : 定义控制台应用程序的入口点。
//

#include 
#include 
#include 
#include 

static std::mutex mutex1;
static std::mutex mutex2;

static int threadFunc1()
{		
	std::cout << "Enter threadFunc1" << std::endl;
	std::lock_guard lock1(mutex1);	
	std::this_thread::sleep_for(std::chrono::seconds(20));
	std::lock_guard lock2(mutex2);
	std::cout << "Leave threadFunc1" << std::endl;	
	return 0;
}

static int threadFunc2()
{
	std::cout << "Enter threadFunc2" << std::endl;
	std::lock_guard lock1(mutex2);		
	std::this_thread::sleep_for(std::chrono::seconds(20));	
	std::lock_guard lock2(mutex1);
	std::cout << "Leave threadFunc2" << std::endl;	
	return 0;
}

int main()
{
	std::thread thread1(threadFunc1);
	std::thread thread2(threadFunc2);
	
	thread1.join();
	thread2.join();

	std::cout << "All thread end,now exit" << std::endl;	
    return 0;
}

编译运行(目标程序为testDemo):./testDemo

Enter threadFunc1

Enter threadFunc2

并未输出:Leave threadFunc1 、 Leave threadFunc2、All thread end,now exit,随后程序处于挂起状态

分析

1、Gdb调试:gdb ./testDemo

2、 待到程序无反应时,通过Ctrl+C中断程序运行

3、查看线程信息:info threads

Id   Target Id         Frame

* 1    Thread 0x7ffff7fdb740 (LWP 4315) "testDemo" 0x00007ffff7bbed2d in __GI___pthread_timedjoin_ex (threadid=140737335809792, thread_return=0x0,

    abstime=0x0, block=) at pthread_join_common.c:89

  2    Thread 0x7ffff6e85700 (LWP 4319) "testDemo" __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135

  3    Thread 0x7ffff6684700 (LWP 4320) "testDemo" __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135

我们看到,一共有三个线程,分别为主线程,以及两个子线程,线程号分别为4319及4320。并且两个子线程都处于锁等待的状态。

4、查看子线程4319堆栈信息:thread 2; bt(2 是相对线程号)

#0  __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135

#1  0x00007ffff7bc0023 in __GI___pthread_mutex_lock (mutex=0x5555557581a0 ) at ../nptl/pthread_mutex_lock.c:78

#2  0x00005555555550bf in __gthread_mutex_lock (__mutex=0x5555557581a0 ) at /usr/include/x86_64-linux-gnu/c++/7/bits/gthr-default.h:748

#3  0x0000555555555614 in std::mutex::lock (this=0x5555557581a0 ) at /usr/include/c++/7/bits/std_mutex.h:103

#4  0x0000555555555690 in std::lock_guard::lock_guard (this=0x7ffff6e84dc0, __m=...) at /usr/include/c++/7/bits/std_mutex.h:162

#5  0x0000555555555183 in threadFunc1 () at DeadLock.cpp:17

省略…..

子线程4319在等待mutex2

5、查看子线程4320堆栈信息:thread 3; bt(3 是相对线程号)

#0  __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135

#1  0x00007ffff7bc0023 in __GI___pthread_mutex_lock (mutex=0x555555758160 ) at ../nptl/pthread_mutex_lock.c:78

#2  0x00005555555550bf in __gthread_mutex_lock (__mutex=0x555555758160 ) at /usr/include/x86_64-linux-gnu/c++/7/bits/gthr-default.h:748

#3  0x0000555555555614 in std::mutex::lock (this=0x555555758160 ) at /usr/include/c++/7/bits/std_mutex.h:103

#4  0x0000555555555690 in std::lock_guard::lock_guard (this=0x7ffff6683dc0, __m=...) at /usr/include/c++/7/bits/std_mutex.h:162

#5  0x000055555555529e in threadFunc2 () at DeadLock.cpp:27

子线程4320在等待锁mutex1

6、查看mutex1、mutex2的信息

p mutex1:

{

  = {

    _M_mutex = pthread_mutex_t = {

      Type = Normal,

      Status = Acquired, possibly with waiters,

      Owner ID = 4319,

      Robust = No,

      Shared = No,

      Protocol = None

    }

  }

p mutex2:

{

  = {

    _M_mutex = pthread_mutex_t = {

      Type = Normal,

      Status = Acquired, possibly with waiters,

      Owner ID = 4320,

      Robust = No,

      Shared = No,

      Protocol = None

    }

  }

mutex1的当前所属线程是4319(相对线程号为2),mutex2的当前所属线程是4320(相对线程号为3。同时,mutex1及mutex2中的Status字段均表示其已经被获取,并且可能有等待者。

结论

将上述分析结果以表格形式汇总:

相对线程号

线程号

拥有锁

等待锁

2

4319

mutex1

mutex2

3

4320

mutex2

mutex1

从汇总结果看,线程4319,43202形成了死锁,导致程序挂起。

Linux GDB分析死锁_第1张图片 扫描二维码,关注“清远的梦呓”公众号,发现更多文章

 

你可能感兴趣的:(C++,Linux)