天天看点

gdb调试死锁的正确姿势

gdb搞起

这是我们的源码:

#include <unistd.h> 
#include <pthread.h> 
#include <string.h> 
pthread_mutex_t lock_a = PTHREAD_MUTEX_INITIALIZER; 
pthread_mutex_t lock_b = PTHREAD_MUTEX_INITIALIZER;

/*!

我们构造一个死锁 ab ba

 */

void *  pthread_fun_1()
{
	while(1)
	{
		pthread_mutex_lock(&lock_a);
		pthread_mutex_lock(&lock_b);
		printf("-------%x\n",pthread_self());
		pthread_mutex_unlock(&lock_b);
		pthread_mutex_unlock(&lock_a);
	}
		return NULL;
}

void *  pthread_fun_2()
{
	while(1)
	{
		pthread_mutex_lock(&lock_b);
		pthread_mutex_lock(&lock_a);
		printf("-------%x\n",pthread_self());
		pthread_mutex_unlock(&lock_a);
		pthread_mutex_unlock(&lock_b);
	}  
		return NULL;

}
int main (void )
{

	pthread_t tid[2]={0};
	pthread_create(&tid[0], NULL, pthread_fun_1, NULL);
	pthread_create(&tid[1], NULL, pthread_fun_2, NULL);


	pthread_join(tid[0],NULL);
	pthread_join(tid[1],NULL);
	return 0;
}
           

gdb搞起。。。。。。。。

[email protected]:~$ pidof a.out 
9744
[email protected]:~$ sudo gdb attach 9744
[sudo] password for online: 
GNU gdb (Ubuntu 7.7-0ubuntu3) 7.7
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
attach: No such file or directory.
Attaching to process 9744
Reading symbols from /home/online/DeadLock/a.out...done.
Reading symbols from /lib/x86_64-linux-gnu/libpthread.so.0...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/libpthread-2.19.so...done.
done.
[New LWP 9746]
[New LWP 9745]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Loaded symbols for /lib/x86_64-linux-gnu/libpthread.so.0
Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/libc-2.19.so...done.
done.
Loaded symbols for /lib/x86_64-linux-gnu/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/ld-2.19.so...done.
done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
0x00007fecccac165b in pthread_join (threadid=140655018829568, 
    thread_return=0x0) at pthread_join.c:92
92	pthread_join.c: No such file or directory.
(gdb) i thread
  Id   Target Id         Frame 
  3    Thread 0x7feccc6ee700 (LWP 9745) "a.out" __lll_lock_wait ()
    at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
  2    Thread 0x7feccbeed700 (LWP 9746) "a.out" __lll_lock_wait ()
    at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
* 1    Thread 0x7feccceda740 (LWP 9744) "a.out" 0x00007fecccac165b in pthread_join (threadid=140655018829568, thread_return=0x0) at pthread_join.c:92
(gdb) bt
#0  0x00007fecccac165b in pthread_join (threadid=140655018829568, 
    thread_return=0x0) at pthread_join.c:92
#1  0x000000000040088a in main () at dead_lock.c:47
(gdb) thread 2
[Switching to thread 2 (Thread 0x7feccbeed700 (LWP 9746))]
#0  __lll_lock_wait ()
    at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
135	../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: No such file or directory.
(gdb) bt
#0  __lll_lock_wait ()
    at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
#1  0x00007fecccac2649 in _L_lock_909 ()
   from /lib/x86_64-linux-gnu/libpthread.so.0
#2  0x00007fecccac2470 in __GI___pthread_mutex_lock (mutex=0x6010a0 <lock_a>)
    at ../nptl/pthread_mutex_lock.c:79
#3  0x00000000004007fa in pthread_fun_2 () at dead_lock.c:31
#4  0x00007fecccac0184 in start_thread (arg=0x7feccbeed700)
    at pthread_create.c:312
#5  0x00007feccc7ed03d in clone ()
    at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
(gdb) bt
#0  __lll_lock_wait ()
    at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
#1  0x00007fecccac2649 in _L_lock_909 ()
   from /lib/x86_64-linux-gnu/libpthread.so.0
#2  0x00007fecccac2470 in __GI___pthread_mutex_lock (mutex=0x6010a0 <lock_a>)
    at ../nptl/pthread_mutex_lock.c:79
#3  0x00000000004007fa in pthread_fun_2 () at dead_lock.c:31
#4  0x00007fecccac0184 in start_thread (arg=0x7feccbeed700)
    at pthread_create.c:312
#5  0x00007feccc7ed03d in clone ()
    at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
(gdb) l pthread_fun_2
22		}
23			return NULL;
24	}
25	
26	void *  pthread_fun_2()
27	{
28		while(1)
29		{
30			pthread_mutex_lock(&lock_b);
31			pthread_mutex_lock(&lock_a);
(gdb) p lock_aa
No symbol "lock_aa" in current context.
(gdb) 
No symbol "lock_aa" in current context.
(gdb) p lock_a
$1 = {__data = {__lock = 2, __count = 0, __owner = 9745, __nusers = 1, 
    __kind = 0, __spins = 0, __elision = 0, __list = {__prev = 0x0, 
      __next = 0x0}}, 
  __size = "\002\000\000\000\000\000\000\000\021&\000\000\001", '\000' <repeats 26 times>, __align = 2}
(gdb) thread 3
[Switching to thread 3 (Thread 0x7feccc6ee700 (LWP 9745))]
#0  __lll_lock_wait ()
    at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
135	../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: No such file or directory.
(gdb) bt
#0  __lll_lock_wait ()
    at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
#1  0x00007fecccac2649 in _L_lock_909 ()
   from /lib/x86_64-linux-gnu/libpthread.so.0
#2  0x00007fecccac2470 in __GI___pthread_mutex_lock (mutex=0x6010e0 <lock_b>)
    at ../nptl/pthread_mutex_lock.c:79
#3  0x00000000004007b5 in pthread_fun_1 () at dead_lock.c:18
#4  0x00007fecccac0184 in start_thread (arg=0x7feccc6ee700)
    at pthread_create.c:312
#5  0x00007feccc7ed03d in clone ()
    at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
(gdb) l pthread_fun_1
9	
10	
11	 */
12	
13	void *  pthread_fun_1()
14	{
15		while(1)
16		{
17			pthread_mutex_lock(&lock_a);
18			pthread_mutex_lock(&lock_b);
(gdb) p lock_b
$2 = {__data = {__lock = 2, __count = 0, __owner = 9746, __nusers = 1, 
    __kind = 0, __spins = 0, __elision = 0, __list = {__prev = 0x0, 
      __next = 0x0}}, 
  __size = "\002\000\000\000\000\000\000\000\022&\000\000\001", '\000' <repeats 26 times>, __align = 2}
(gdb) {__data = {__lock = 2, __count = 0, __owner = 9746, __nusers = 1, 
Undefined command: "".  Try "help".
(gdb)     __kind = 0, __spins = 0, __elision = 0, __list = {__prev = 0x0, 
Undefined command: "__kind".  Try "help".
(gdb)       __next = 0x0}}, 
Undefined command: "__next".  Try "help".
(gdb)   __size = "\002\000\000\000\000\000\000\000\022&\000\000\001", '\000' <r
           

我们通过gdb可以清楚的看出:

线程1需要的锁的持有者是线程2

线程2需要的锁的持有者是线程1

继续阅读