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 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) x 0x7f8fe6fff118 (x命令,打印地址的值)
0x7f8fe6fff118: 0xeff94310
(gdb) x 0x7f8fe6fff11c
0x7f8fe6fff11c: 0x00007fff
参数的位置在:
(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}}