Linux on Power 上的调试工具和技术(5)
- UID
- 1066743
|
Linux on Power 上的调试工具和技术(5)
清单 22. 查看每个线程运行到了什么地方1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
| (gdb) thread apply 1 where
Thread 1 (Thread 1073991712 (LWP 9510)):
#0 0x0ff4ac40 in __write_nocancel () from /lib/tls/libc.so.6
#1 0x0ff4ac28 in __write_nocancel () from /lib/tls/libc.so.6
Previous frame identical to this frame (corrupt stack?)
#0 0x0ff4ac40 in __write_nocancel () from /lib/tls/libc.so.6
(gdb) thread apply 2 where
Thread 2 (Thread 1090771744 (LWP 9514)):
#0 0x0ffe94ec in __lll_lock_wait () from /lib/tls/libpthread.so.0
#1 0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#2 0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#3 0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#4 0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
Previous frame inner to this frame (corrupt stack?)
#0 0x0ff4ac40 in __write_nocancel () from /lib/tls/libc.so.6
(gdb) thread apply 3 where
Thread 3 (Thread 1086577440 (LWP 9513)):
#0 0x0ffe94ec in __lll_lock_wait () from /lib/tls/libpthread.so.0
#1 0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#2 0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#3 0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#4 0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
Previous frame inner to this frame (corrupt stack?)
#0 0x0ff4ac40 in __write_nocancel () from /lib/tls/libc.so.6
(gdb) thread apply 4 where
Thread 4 (Thread 1082383136 (LWP 9512)):
#0 0x0ffe94ec in __lll_lock_wait () from /lib/tls/libpthread.so.0
#1 0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#2 0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#3 0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#4 0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
Previous frame inner to this frame (corrupt stack?)
#0 0x0ff4ac40 in __write_nocancel () from /lib/tls/libc.so.6
(gdb) thread apply 5 where
Thread 5 (Thread 1078188832 (LWP 9511)):
#0 0x0ffe94ec in __lll_lock_wait () from /lib/tls/libpthread.so.0
#1 0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#2 0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#3 0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#4 0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
Previous frame inner to this frame (corrupt stack?)
#0 0x0ff4ac40 in __write_nocancel () from /lib/tls/libc.so.6
|
每个线程都试图对一个互斥体进行加锁,但是这个互斥体却是不可用的,可能是因为有另外一个线程已经对其进行加锁了。从上面的证据我们可以判断程序中一定存在死锁。您还可以看到哪个线程现在拥有这个互斥体。
清单 23. 查看哪个线程拥有互斥体1
2
3
4
5
6
7
8
9
10
11
| (gdb) print AccountA_mutex
$1 = {__m_reserved = 2, __m_count = 0, __m_owner = 0x2527, <br>
__m_kind = 0, __m_lock = {__status = 1, __spinlock = 0}}
(gdb) print 0x2527
$2 = 9511
(gdb) print AccountB_mutex
$3 = {__m_reserved = 2, __m_count = 0, __m_owner = 0x2529, <br>
__m_kind = 0, __m_lock = {__status = 1, __spinlock = 0}}
(gdb) print 0x2529
$4 = 9513
(gdb)
|
从上面的命令中,我们可以看出 AccontA_mutex 是被线程 5(LWP 9511)加锁(拥有)的,而 AccontB_mutex 是被线程 3(LWP 9513)加锁(拥有)的。
为了解决上面的死锁情况,可以按照相同的顺序对互斥体进行加锁,如下所示:
清单 24. 按照相同的顺序对互斥体进行加锁1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| .
.
void * transferAB (void* amount_ptr) {
int amount = *((int*)amount_ptr);
pthread_mutex_lock(&AccountA_mutex);
pthread_mutex_lock(&AccountB_mutex);
if (accountA.balance < amount) {
printf("There is not enough memory in Account A!\n");
pthread_mutex_unlock(&AccountA_mutex);
pthread_exit((void *)1);
}
accountA.balance -=amount;
sleep(1);
accountB.balance +=amount;
pthread_mutex_unlock(&AccountA_mutex);
pthread_mutex_unlock(&AccountB_mutex);
}
void * transferBA (void* amount_ptr) {
int amount = *((int*)amount_ptr);
pthread_mutex_lock(&AccountA_mutex);
pthread_mutex_lock(&AccountB_mutex);
if (accountB.balance < amount) {
printf("There is not enough memory in Account B!\n");
pthread_mutex_unlock(&AccountB_mutex);
pthread_exit((void *)1);
}
accountB.balance -=amount;
sleep(1);
accountA.balance +=amount;
pthread_mutex_unlock(&AccountA_mutex);
pthread_mutex_unlock(&AccountB_mutex);
}
.
.
|
或者对每个帐号单独进行加锁,如下所示:
清单 25. 对每个帐号单独进行加锁1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| .
.
void * transferAB (void* amount_ptr) {
int amount = *((int*)amount_ptr);
pthread_mutex_lock(&AccountA_mutex);
if (accountA.balance < amount) {
printf("There is not enough memory in Account A!\n");
pthread_mutex_unlock(&AccountA_mutex);
pthread_exit((void *)1);
}
accountA.balance -=amount;
sleep(1);
pthread_mutex_unlock(&AccountA_mutex);
pthread_mutex_lock(&AccountB_mutex);
accountB.balance +=amount;
pthread_mutex_unlock(&AccountB_mutex);
}
void * transferBA (void* amount_ptr) {
int amount = *((int*)amount_ptr);
pthread_mutex_lock(&AccountB_mutex);
if (accountB.balance < amount) {
printf("There is not enough memory in Account B!\n");
pthread_mutex_unlock(&AccountB_mutex);
pthread_exit((void *)1);
}
accountB.balance -=amount;
sleep(1);
pthread_mutex_unlock(&AccountB_mutex);
pthread_mutex_lock(&AccountA_mutex);
accountA.balance +=amount;
pthread_mutex_unlock(&AccountA_mutex);
}
.
.
.
|
要调试 64 位的应用程序(使用 GCC 的 –m64 选项或 IBM XL C/C++ 编译器的 –q64 选项编译),应该使用一个特别的 gdb 版本 gdb64。 |
|
|
|
|
|