首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Linux on Power 上的调试工具和技术(5)

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。
返回列表