天天看點

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

繼續閱讀