1对于多线程程序调试
例子:
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
typedef struct ct_sum
{ int sum;
pthread_mutex_t lock;
}ct_sum;
void * add1(void * cnt)
{
pthread_mutex_lock(&(((ct_sum*)cnt)->lock));
int i;
for( i=0;i<50;i++)
{(*(ct_sum*)cnt).sum+=i;
}
pthread_mutex_unlock(&(((ct_sum*)cnt)->lock));
pthread_exit(NULL);
return 0;
}
void * add2(void *cnt)
{
int i;
cnt= (ct_sum*)cnt;
pthread_mutex_lock(&(((ct_sum*)cnt)->lock));
for( i=50;i<101;i++)
{ (*(ct_sum*)cnt).sum+=i;
}
pthread_mutex_unlock(&(((ct_sum*)cnt)->lock));
pthread_exit(NULL);
return 0;
}
int main(void)
{ int i;
pthread_t ptid1,ptid2;
int sum=0;
ct_sum cnt;
pthread_mutex_init(&(cnt.lock),NULL);
cnt.sum=0;
pthread_create(&ptid1,NULL,add1,&cnt);
pthread_create(&ptid2,NULL,add2,&cnt);
pthread_mutex_lock(&(cnt.lock));
printf("sum %d\n",cnt.sum);
pthread_mutex_unlock(&(cnt.lock));
pthread_join(ptid1,NULL);
pthread_join(ptid2,NULL);
pthread_mutex_destroy(&(cnt.lock));
return 0;
}
Gdb –p pid
查询线程infothreads
(gdb) info threads
3Thread 0x7f8fe7800950 (LWP 29071) 0x00007f8fe78a2ce1 in nanosleep () from /lib64/libc.so.6
* 2 Thread 0x7f8fe6fff950 (LWP 29072) 0x00007f8fe7b67434 in __lll_lock_wait () from/lib64/libpthread.so.0
1Thread 0x7f8fe7f5b6f0 (LWP 29070) 0x00007f8fe7b67434 in __lll_lock_wait () from /lib64/libpthread.so.0
选择一个线程序
(gdb) thread 2
[Switching to thread 2 (Thread0x7f8fe6fff950 (LWP 29072))]#0 0x00007f8fe7b67434 in __lll_lock_wait () from /lib64/libpthread.so.0
查看线程的栈桢:
(gdb) bt
#0 0x00007f8fe7b67434 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x00007f8fe7b62cf0 in _L_lock_102 () from /lib64/libpthread.so.0
#2 0x00007f8fe7b625de in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00000000004008b6 in add2 (cnt=0x7fffeff94310) at mtux.c:32
#4 0x00007f8fe7b61070 in start_thread () from /lib64/libpthread.so.0
#5 0x00007f8fe78d410d in clone () from /lib64/libc.so.6
#6 0x0000000000000000 in ?? ()
选择线程的某一个栈桢:
(gdb) frame 2
#2 0x00007f8fe7b625de in pthread_mutex_lock () from /lib64/libpthread.so.0
(gdb) frame 3
#3 0x00000000004008b6 in add2 (cnt=0x7fffeff94310) at mtux.c:32
32 pthread_mutex_lock(&(((ct_sum*)cnt)->lock));
查看局部变量:
(gdb) info locals
i = 0
查看函数的参数:
(gdb) info args
cnt = (void *) 0x7fffeff94310
查看该参数的值:
(gdb) print *(ct_sum*)0x7fffeff94310
$23 = {sum = 1225, lock = {__data = {__lock= 2, __count = 0, __owner = 29071, __nusers = 1, __kind = 0, __spins = 0,__list = {
__prev = 0x0, __next = 0x0}}, __size = "\002\000\000\000\000\000\000\000\217q\000\000\001",'\0' <repeats 26 times>, __align = 2}}
(gdb) info registers
rax 0xfffffffffffffe00 -512
rbx 0x0 0
rcx 0xffffffffffffffff -1
rdx 0x7f8fe7b6aa20 140256044558880
rsi 0x80 128
rdi 0x7fffeff94318 140737219478296
rbp 0x7f8fe6fff130 0x7f8fe6fff130
rsp 0x7f8fe6fff110 0x7f8fe6fff110
r8 0x7f8fe6fff950 140256032586064
r9 0x7f8fe6fff950 140256032586064
r10 0x0 0
r11 0x246 582
r12 0x7f8fe7b6a860 140256044558432
r13 0x7f8fe6fff260 140256032584288
r14 0x0 0
r15 0x1000 4096
rip 0x4008b6 0x4008b6 <add2+25>
eflags 0x246 [PF ZF IF ]
cs 0x33 51
ss 0xe02b 57387
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
fctrl 0x37f 895
fstat 0x0 0
ftag 0xffff 65535
---Type <return> to continue, or q<return> to quit---
fiseg 0x0 0
fioff 0x0 0
foseg 0x0 0
fooff 0x0 0
fop 0x0 0
mxcsr 0x1f80 [ IM DM ZM OM UM PM ]
(gdb) info frame
Stack level 3, frame at 0x7f8fe6fff140:
rip= 0x4008b6 in add2 (mtux.c:32); saved rip 0x7f8fe7b61070
called by frame at 0x7f8fe6fff260, caller offrame at 0x7f8fe6fff110
source language c.
Arglist at 0x7f8fe6fff130, args:cnt=0x7fffeff94310
Locals at 0x7f8fe6fff130, Previous frame's spis 0x7f8fe6fff140
Saved registers:
rbpat 0x7f8fe6fff130, rip at 0x7f8fe6fff138
(gdb) disassemble add2
Dump of assembler code for function add2:
0x000000000040089d <add2+0>: push %rbp
0x000000000040089e <add2+1>: mov %rsp,%rbp
0x00000000004008a1 <add2+4>: sub $0x20,%rsp
0x00000000004008a5 <add2+8>: mov %rdi,-0x18(%rbp)
0x00000000004008a9 <add2+12>: mov -0x18(%rbp),%rax
0x00000000004008ad <add2+16>: lea 0x8(%rax),%rdi
0x00000000004008b1 <add2+20>: callq 0x400728 <pthread_mutex_lock@plt>
0x00000000004008b6 <add2+25>: movl $0x32,-0x4(%rbp)
0x00000000004008bd <add2+32>: jmp 0x4008d2 <add2+53>
0x00000000004008bf <add2+34>: mov -0x18(%rbp),%rdx
0x00000000004008c3 <add2+38>: mov -0x18(%rbp),%rax
0x00000000004008c7 <add2+42>: mov (%rax),%eax
0x00000000004008c9 <add2+44>: add -0x4(%rbp),%eax
0x00000000004008cc <add2+47>: mov %eax,(%rdx)
0x00000000004008ce <add2+49>: addl $0x1,-0x4(%rbp)
0x00000000004008d2 <add2+53>: cmpl $0x64,-0x4(%rbp)
0x00000000004008d6 <add2+57>: jle 0x4008bf <add2+34>
0x00000000004008d8 <add2+59>: mov $0x400a91,%edi
0x00000000004008dd <add2+64>: callq 0x4006c8 <puts@plt>
0x00000000004008e2 <add2+69>: mov $0x14,%edi
0x00000000004008e7 <add2+74>: callq 0x400708 <sleep@plt>
0x00000000004008ec <add2+79>: jmp 0x4008d8 <add2+59>
End of assembler dump.
可以从上面看到 在call pthread_mutex_lock的时候,
参数保存在rdi中
(gdb) print/x $rdi
$25 = 0x7fffeff94318
(gdb) print *(ct_sum*)0x7fffeff94310
$27 = {sum = 1225, lock = {__data = {__lock= 2, __count = 0, __owner = 29071, __nusers = 1, __kind = 0, __spins = 0,__list = {
__prev = 0x0, __next = 0x0}}, __size ="\002\000\000\000\000\000\000\000\217q\000\000\001", '\0' <repeats26 times>, __align = 2}}
(gdb) print*(pthread_mutex_t*)0x7fffeff94318
$29 = {__data = {__lock = 2, __count = 0,__owner = 29071, __nusers = 1, __kind = 0, __spins = 0, __list = {__prev = 0x0,__next = 0x0}},
__size = "\002\000\000\000\000\000\000\000\217q\000\000\001",'\0' <repeats 26 times>, __align = 2}
(gdb) frame 2
#2 0x00007f8fe7b625de in pthread_mutex_lock () from /lib64/libpthread.so.0
(gdb) info frame
Stack level 2, frame at 0x7f8fe6fff110:
rip= 0x7f8fe7b625de in pthread_mutex_lock; saved rip 0x4008b6
called by frame at 0x7f8fe6fff140, caller offrame at 0x7f8fe6fff0d0
Arglist at 0x7f8fe6fff0c8, args:
Locals at 0x7f8fe6fff0c8, Previous frame's spis 0x7f8fe6fff110
Saved registers:
rbxat 0x7f8fe6fff0d8, rbp at 0x7f8fe6fff0e0, r12 at 0x7f8fe6fff0e8, r13 at0x7f8fe6fff0f0, r14 at 0x7f8fe6fff0f8, r15 at 0x7f8fe6fff100,
ripat 0x7f8fe6fff108
(gdb) disassemble pthread_mutex_lock
Dump of assembler code for functionpthread_mutex_lock:
0x00007f8fe7b62570<pthread_mutex_lock+0>: push %r15
0x00007f8fe7b62572<pthread_mutex_lock+2>: push %r14
0x00007f8fe7b62574<pthread_mutex_lock+4>: push %r13
0x00007f8fe7b62576 <pthread_mutex_lock+6>: push %r12
0x00007f8fe7b62578<pthread_mutex_lock+8>: push %rbp
0x00007f8fe7b62579<pthread_mutex_lock+9>: push %rbx
0x00007f8fe7b6257a<pthread_mutex_lock+10>: mov %rdi,%rbx
0x00007f8fe7b6257d<pthread_mutex_lock+13>: sub $0x8,%rsp
0x00007f8fe7b62581<pthread_mutex_lock+17>: mov %fs:0x90,%r13d
0x00007f8fe7b6258a<pthread_mutex_lock+26>: mov 0x10(%rdi),%esi
0x00007f8fe7b6258d<pthread_mutex_lock+29>: mov %rsi,%rax
0x00007f8fe7b62590<pthread_mutex_lock+32>: and $0x7f,%eax
0x00007f8fe7b62593<pthread_mutex_lock+35>: cmp $0x43,%rax
0x00007f8fe7b62597<pthread_mutex_lock+39>: jbe 0x7f8fe7b625ad<pthread_mutex_lock+61>
0x00007f8fe7b62599<pthread_mutex_lock+41>: mov $0x16,%eax
0x00007f8fe7b6259e <pthread_mutex_lock+46>: add $0x8,%rsp
0x00007f8fe7b625a2<pthread_mutex_lock+50>: pop %rbx
0x00007f8fe7b625a3<pthread_mutex_lock+51>: pop %rbp
0x00007f8fe7b625a4<pthread_mutex_lock+52>: pop %r12
0x00007f8fe7b625a6<pthread_mutex_lock+54>: pop %r13
0x00007f8fe7b625a8<pthread_mutex_lock+56>: pop %r14
0x00007f8fe7b625aa<pthread_mutex_lock+58>: pop %r15
0x00007f8fe7b625ac<pthread_mutex_lock+60>: retq
0x00007f8fe7b625ad<pthread_mutex_lock+61>: lea 0x846c(%rip),%rdx # 0x7f8fe7b6aa20
0x00007f8fe7b625b4<pthread_mutex_lock+68>: movslq(%rdx,%rax,4),%rax
0x00007f8fe7b625b8<pthread_mutex_lock+72>: add %rdx,%rax
---Type <return> to continue, or q<return> to quit---
0x00007f8fe7b625bb<pthread_mutex_lock+75>: jmpq *%rax
0x00007f8fe7b625bd <pthread_mutex_lock+77>: cmp 0x8(%rdi),%r13d
0x00007f8fe7b625c1<pthread_mutex_lock+81>: je 0x7f8fe7b62ab0<pthread_mutex_lock+1344>
0x00007f8fe7b625c7<pthread_mutex_lock+87>: and $0x80,%esi
0x00007f8fe7b625cd<pthread_mutex_lock+93>: mov $0x1,%edi
0x00007f8fe7b625d2<pthread_mutex_lock+98>: xor %eax,%eax
0x00007f8fe7b625d4<pthread_mutex_lock+100>: lockcmpxchg %edi,(%rbx)
0x00007f8fe7b625d8<pthread_mutex_lock+104>: jne 0x7f8fe7b62ce1 <_L_lock_102>
0x00007f8fe7b625de <pthread_mutex_lock+110>: mov 0x8(%rbx),%esi
0x00007f8fe7b625e1<pthread_mutex_lock+113>: test %esi,%esi
0x00007f8fe7b625e3<pthread_mutex_lock+115>: jne 0x7f8fe7b62bf7<pthread_mutex_lock+1671>
0x00007f8fe7b625e9<pthread_mutex_lock+121>: addl $0x1,0xc(%rbx)
0x00007f8fe7b625ed<pthread_mutex_lock+125>: mov %r13d,0x8(%rbx)
0x00007f8fe7b625f1<pthread_mutex_lock+129>: add $0x8,%rsp
0x00007f8fe7b625f5<pthread_mutex_lock+133>: pop %rbx
0x00007f8fe7b625f6<pthread_mutex_lock+134>: pop %rbp
0x00007f8fe7b625f7 <pthread_mutex_lock+135>: pop %r12
0x00007f8fe7b625f9<pthread_mutex_lock+137>: pop %r13
0x00007f8fe7b625fb<pthread_mutex_lock+139>: pop %r14
0x00007f8fe7b625fd<pthread_mutex_lock+141>: xor %eax,%eax
0x00007f8fe7b625ff<pthread_mutex_lock+143>: pop %r15
0x00007f8fe7b62601<pthread_mutex_lock+145>: retq
0x00007f8fe7b62602<pthread_mutex_lock+146>: cmp %r13d,0x8(%rdi)
0x00007f8fe7b62606<pthread_mutex_lock+150>: mov (%rdi),%ecx
0x00007f8fe7b62608<pthread_mutex_lock+152>: jne 0x7f8fe7b62621<pthread_mutex_lock+177>
0x00007f8fe7b6260a<pthread_mutex_lock+154>: mov %esi,%eax
0x00007f8fe7b6260c<pthread_mutex_lock+156>: and $0x3,%eax
---Type <return> to continue, or q<return> to quit---
0x00007f8fe7b6260f<pthread_mutex_lock+159>: cmp $0x2,%eax
0x00007f8fe7b62612<pthread_mutex_lock+162>: je 0x7f8fe7b62ab0<pthread_mutex_lock+1344>
0x00007f8fe7b62618<pthread_mutex_lock+168>: sub $0x1,%eax
0x00007f8fe7b6261b<pthread_mutex_lock+171>: je 0x7f8fe7b628fa <pthread_mutex_lock+906>
0x00007f8fe7b62621<pthread_mutex_lock+177>: mov $0xffffffff,%ebp
0x00007f8fe7b62626<pthread_mutex_lock+182>: mov $0xca,%r14d
0x00007f8fe7b6262c<pthread_mutex_lock+188>: mov %ecx,%r12d
0x00007f8fe7b6262f<pthread_mutex_lock+191>: shr $0x13,%r12d
0x00007f8fe7b62633<pthread_mutex_lock+195>: callq 0x7f8fe7b694e0<__pthread_current_priority>
0x00007f8fe7b62638<pthread_mutex_lock+200>: cmp %eax,%r12d
0x00007f8fe7b6263b<pthread_mutex_lock+203>: jl 0x7f8fe7b62aba <pthread_mutex_lock+1354>
0x00007f8fe7b62641<pthread_mutex_lock+209>: mov %r12d,%esi
0x00007f8fe7b62644<pthread_mutex_lock+212>: mov %ebp,%edi
0x00007f8fe7b62646<pthread_mutex_lock+214>: callq 0x7f8fe7b69610<__pthread_tpp_change_priority>
0x00007f8fe7b6264b <pthread_mutex_lock+219>: test %eax,%eax
0x00007f8fe7b6264d<pthread_mutex_lock+221>: jne 0x7f8fe7b6259e<pthread_mutex_lock+46>
0x00007f8fe7b62653<pthread_mutex_lock+227>: mov %r12d,%r15d
0x00007f8fe7b62656<pthread_mutex_lock+230>: shl $0x13,%r15d
0x00007f8fe7b6265a<pthread_mutex_lock+234>: mov %r15d,%r9d
0x00007f8fe7b6265d<pthread_mutex_lock+237>: mov %r15d,%eax
0x00007f8fe7b62660<pthread_mutex_lock+240>: or $0x1,%r9d
0x00007f8fe7b62664<pthread_mutex_lock+244>: lockcmpxchg %r9d,(%rbx)
0x00007f8fe7b62669<pthread_mutex_lock+249>: cmp %r15d,%eax
0x00007f8fe7b6266c<pthread_mutex_lock+252>: je 0x7f8fe7b626c6<pthread_mutex_lock+342>
0x00007f8fe7b6266e<pthread_mutex_lock+254>: mov %r15d,%r8d
0x00007f8fe7b62671 <pthread_mutex_lock+257>: or $0x2,%r8d
0x00007f8fe7b62675<pthread_mutex_lock+261>: nopl (%rax)
---Type <return> to continue, or q<return> to quit---q
(gdb) x 0x7f8fe6fff118
0x7f8fe6fff118: 0xeff94310
(gdb) x 0x7f8fe6fff11c
0x7f8fe6fff11c: 0x00007fff
info frame
Stack level 2, frame at 0x7f8fe6fff110:
rip= 0x7f8fe7b625de in pthread_mutex_lock; saved rip 0x4008b6
called by frame at 0x7f8fe6fff140, caller offrame at 0x7f8fe6fff0d0
Arglist at 0x7f8fe6fff0c8, args:
Locals at 0x7f8fe6fff0c8, Previous frame's spis 0x7f8fe6fff110
Saved registers:
rbxat 0x7f8fe6fff0d8, rbp at 0x7f8fe6fff0e0, r12 at 0x7f8fe6fff0e8, r13 at0x7f8fe6fff0f0, r14 at 0x7f8fe6fff0f8, r15 at 0x7f8fe6fff100,
ripat 0x7f8fe6fff108
参数的位置在:
(gdb) x/10 0x7f8fe6fff110
0x7f8fe6fff110: 0x00000000 0x00000000 0xeff94310 0x00007fff
0x7f8fe6fff120: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f8fe6fff130: 0x00000000 0x00000000
(gdb) print *(ct_sum*)0x00007fffeff94310
$40 = {sum = 1225, lock = {__data = {__lock= 2, __count = 0, __owner = 29071, __nusers = 1, __kind = 0, __spins = 0,__list = {
__prev = 0x0, __next = 0x0}}, __size ="\002\000\000\000\000\000\000\000\217q\000\000\001", '\0' <repeats26 times>, __align = 2}}
编译8个字节:
(gdb) print *(pthread_mutex_t*)0x00007fffeff94318
$41 = {__data = {__lock = 2, __count = 0,__owner = 29071, __nusers = 1, __kind = 0, __spins = 0, __list = {__prev = 0x0,__next = 0x0}},
__size = "\002\000\000\000\000\000\000\000\217q\000\000\001",'\0' <repeats 26 times>, __align = 2}