参考:[Advance] How to debug a program (上)
Example
Test ENV
nochen@bclnx64 ~/test$ uname -a
Linux bclnx64 2.6.9-34.ELsmp #1 SMP Thu Mar 9 06:23:23 GMT 2006 x86_64 x86_64 x86_64 GNU/Linux
nochen@bclnx64 ~/test$ g++ -v
Reading specs from /usr/lib/gcc/x86_64-redhat-linux/3.4.5/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-java-awt=gtk --host=x86_64-redhat-linux
Thread model: posix
gcc version 3.4.5 20051201 (Red Hat 3.4.5-2)
nochen@bclnx64 ~/test$ gdb -v
GNU gdb Red Hat Linux (6.3.0.0-1.96rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
Example 1
Aim: basic stack usage, basic assemble code
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
int
Add(
int
a,
int
b,
int
c){
int
arr[4] = {0};
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = a+b+c;
return
arr[3];
}
int
main() {
int
a = 0x100;
int
b = 0x200;
int
c = 0x345;
Add(a,b,c);
return
1;
}
|
(gdb) x/40i Add-2
0x400506 <frame_dummy+38>: nop
0x400507 <frame_dummy+39>: nop
0x400508 <_Z3Addiii>: push %rbp
0x400509 <_Z3Addiii+1>: mov %rsp,%rbp
0x40050c <_Z3Addiii+4>: mov %edi,0xfffffffffffffffc(%rbp)
0x40050f <_Z3Addiii+7>: mov %esi,0xfffffffffffffff8(%rbp)
0x400512 <_Z3Addiii+10>: mov %edx,0xfffffffffffffff4(%rbp)
0x400515 <_Z3Addiii+13>: movq $0x0,0xffffffffffffffe0(%rbp)
0x40051d <_Z3Addiii+21>: movq $0x0,0xffffffffffffffe8(%rbp)
0x400525 <_Z3Addiii+29>: mov 0xfffffffffffffffc(%rbp),%eax
0x400528 <_Z3Addiii+32>: mov %eax,0xffffffffffffffe0(%rbp)
0x40052b <_Z3Addiii+35>: mov 0xfffffffffffffff8(%rbp),%eax
0x40052e <_Z3Addiii+38>: mov %eax,0xffffffffffffffe4(%rbp)
0x400531 <_Z3Addiii+41>: mov 0xfffffffffffffff4(%rbp),%eax
0x400534 <_Z3Addiii+44>: mov %eax,0xffffffffffffffe8(%rbp)
0x400537 <_Z3Addiii+47>: mov 0xfffffffffffffff8(%rbp),%eax
0x40053a <_Z3Addiii+50>: add 0xfffffffffffffffc(%rbp),%eax
0x40053d <_Z3Addiii+53>: add 0xfffffffffffffff4(%rbp),%eax
0x400540 <_Z3Addiii+56>: mov %eax,0xffffffffffffffec(%rbp)
0x400543 <_Z3Addiii+59>: mov 0xffffffffffffffec(%rbp),%eax
0x400546 <_Z3Addiii+62>: leaveq
0x400547 <_Z3Addiii+63>: retq
0x400548 <main>: push %rbp
0x400549 <main+1>: mov %rsp,%rbp
0x40054c <main+4>: sub $0x10,%rsp
0x400550 <main+8>: movl $0x100,0xfffffffffffffffc(%rbp)
0x400557 <main+15>: movl $0x200,0xfffffffffffffff8(%rbp)
0x40055e <main+22>: movl $0x345,0xfffffffffffffff4(%rbp)
0x400565 <main+29>: mov 0xfffffffffffffff4(%rbp),%edx
0x400568 <main+32>: mov 0xfffffffffffffff8(%rbp),%esi
0x40056b <main+35>: mov 0xfffffffffffffffc(%rbp),%edi
0x40056e <main+38>: callq 0x400508 <_Z3Addiii>
0x400573 <main+43>: mov $0x1,%eax
0x400578 <main+48>: leaveq
0x400579 <main+49>: retq
0x40057a <main+50>: nop
(gdb) b Add
Breakpoint 1 at 0x400515: file stack2.cc, line 20.
(gdb) r
Starting program: /home/nochen/test/test
Breakpoint 1, Add (a=256, b=512, c=837) at stack2.cc:20
20 int arr[4] = {0};
(gdb) info register
rax 0x645 1605
rbx 0x0 0
rcx 0x20 32
rdx 0x345 837
rsi 0x200 512
rdi 0x100 256
rbp 0x7fbffff480 0x7fbffff480
rsp 0x7fbffff480 0x7fbffff480
r8 0x7fbffff4d0 548682069200
rip 0x400543 0x400543 <Add(int, int, int)+59>
eflags 0x302 770
(gdb) x/60gx $sp-32
0x7fbffff460: 0x0000020000000100 0x0000064500000345
0x7fbffff470: 0x00000345f5614c40 0x0000010000000200 // Add()ocal variables
0x7fbffff480: 0x0000007fbffff4a0 0x0000000000400573 //current rbp - last rbp - ret add
0x7fbffff490: 0x0000034500000000 0x0000010000000200 //main()ocal variables
0x7fbffff4a0: 0x0000003cf5b31738 0x0000003cf591c4bb //main rbp
0x7fbffff4b0: 0x0000000000400450 0x0000007fbffff578
0x7fbffff4c0: 0x0000000100000000 0x0000000000400548
Example 2
Aim: basic stack usage, basic assemble code
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
int Add(int a, int b, int c){
return a+b+c;
}
int main() {
int a = 0x100;
int b = 0x200;
int c = 0x345;
Add(a,b,c);
return 1;
}
gdb ./test
(gdb) x/40i Add
0x400508 <_Z3Addiii>: push %rbp
0x400509 <_Z3Addiii+1>: mov %rsp,%rbp
0x40050c <_Z3Addiii+4>: mov %edi,0xfffffffffffffffc(%rbp)
0x40050f <_Z3Addiii+7>: mov %esi,0xfffffffffffffff8(%rbp)
0x400512 <_Z3Addiii+10>: mov %edx,0xfffffffffffffff4(%rbp)
0x400515 <_Z3Addiii+13>: mov 0xfffffffffffffff8(%rbp),%eax
0x400518 <_Z3Addiii+16>: add 0xfffffffffffffffc(%rbp),%eax
0x40051b <_Z3Addiii+19>: add 0xfffffffffffffff4(%rbp),%eax
0x40051e <_Z3Addiii+22>: leaveq
0x40051f <_Z3Addiii+23>: retq
0x400520 <main>: push %rbp
0x400521 <main+1>: mov %rsp,%rbp
0x400524 <main+4>: sub $0x10,%rsp
0x400528 <main+8>: movl $0x100,0xfffffffffffffffc(%rbp)
0x40052f <main+15>: movl $0x200,0xfffffffffffffff8(%rbp)
0x400536 <main+22>: movl $0x345,0xfffffffffffffff4(%rbp)
0x40053d <main+29>: mov 0xfffffffffffffff4(%rbp),%edx
0x400540 <main+32>: mov 0xfffffffffffffff8(%rbp),%esi
0x400543 <main+35>: mov 0xfffffffffffffffc(%rbp),%edi
0x400546 <main+38>: callq 0x400508 <_Z3Addiii>
0x40054b <main+43>: mov $0x1,%eax
0x400550 <main+48>: leaveq
0x400551 <main+49>: retq
0x400552 <main+50>: nop
(gdb) b Add
Breakpoint 1 at 0x400515: file stack2.cc, line 29.
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/nochen/test/test
Breakpoint 1, Add (a=256, b=512, c=837) at stack2.cc:29
29 return a+b+c;
(gdb) info register
rax 0x0 0
rbx 0x0 0
rcx 0x20 32
rdx 0x345 837
rsi 0x200 512
rdi 0x100 256
rbp 0x7fbffff480 0x7fbffff480
rsp 0x7fbffff480 0x7fbffff480
r8 0x7fbffff4d0 548682069200
rip 0x400515 0x400515 <Add(int, int, int)+13>
eflags 0x206 518
(gdb) s
30 }
(gdb) x/16gx 0x7fbffff480-32
0x7fbffff460: 0x0000003cf87dfb00 0x0000000000000000
0x7fbffff470: 0x00000345f5614c40 0x0000010000000200
0x7fbffff480: 0x0000007fbffff4a0 0x000000000040054b
0x7fbffff490: 0x0000034500000000 0x0000010000000200
0x7fbffff4a0: 0x0000003cf5b31738 0x0000003cf591c4bb
0x7fbffff4b0: 0x0000000000400450 0x0000007fbffff578
0x7fbffff4c0: 0x0000000100000000 0x0000000000400520
0x7fbffff4d0: 0x0000000000000000 0x0000003cf5614c40
Example 3
Aim: a case for crashing stack
#include <stdlib.h>
int main (int argc, char** argv ) {
execve("/bin/sh", NULL, NULL); // correct: execve("/bin/sh", argv, NULL);
}
gdb ./test
(gdb) disassemble main
Dump of assembler code for function main:
0x0000000000400570 <main+0>: push %rbp
0x0000000000400571 <main+1>: mov %rsp,%rbp
0x0000000000400574 <main+4>: sub $0x10,%rsp
0x0000000000400578 <main+8>: mov %edi,0xfffffffffffffffc(%rbp)
0x000000000040057b <main+11>: mov %rsi,0xfffffffffffffff0(%rbp)
0x000000000040057f <main+15>: mov $0x0,%edx
0x0000000000400584 <main+20>: mov $0x0,%esi
0x0000000000400589 <main+25>: mov $0x40068c,%edi
0x000000000040058e <main+30>: callq 0x400480 // Use ‘disassemble execve’to get execve code // a little different with: 0x400480
0x0000000000400593 <main+35>: mov $0x1,%eax
0x0000000000400598 <main+40>: leaveq
0x0000000000400599 <main+41>: retq
End of assembler dump.
(gdb) r
Starting program: /home/nochen/test/test
Program received signal SIGSEGV, Segmentation fault.
0x0000000000418969 in ?? ()
(gdb) bt
#0 0x0000000000418969 in ?? ()
#1 0x0000000000000000 in ?? ()
(gdb) info register
rax 0x0 0
rbx 0x0 0
rcx 0x3cf592e813 261818083347
rdx 0x0 0
rsi 0x0 0
rdi 0x0 0
rbp 0x5b4870 0x5b4870 // rbp is wrong. I think Stack crash
rsp 0x7fbffffbb0 0x7fbffffbb0
rip 0x418969 0x418969
eflags 0x10246 66118
(gdb) x/16gx 0x5b4870-16
0x5b4860: 0x0000003cf5b2e680 0x0000000000000000
0x5b4870: 0x0000007fbffffee0 0x0000003cf5b2eb00
0x5b4880: 0x0000000000000000 0x0000000000000000
0x5b4890: 0x0000003cf5b2e8c0 0x0000000000000000
0x5b48a0: 0x0000000000000000 0x0000000000000000
0x5b48b0: 0x0000000000000000 0x0000000000000000
0x5b48c0: 0x0000000000000000 0x0000000000000000
0x5b48d0: 0x0000000000000000 0x0000000000000000
(gdb) x/16gx 0x0000007fbffffee0-16
0x7fbffffed0: 0x0000000000000000 0x0000000000000000
0x7fbffffee0: 0x0000000000000000 0x0000000000000010 // wrong last rbp addr
0x7fbffffef0: 0x00000000bfebfbff 0x0000000000000006
0x7fbfffff00: 0x0000000000001000 0x0000000000000011
0x7fbfffff10: 0x0000000000000064 0x0000000000000003
0x7fbfffff20: 0x0000000000400040 0x0000000000000004
0x7fbfffff30: 0x0000000000000038 0x0000000000000005
0x7fbfffff40: 0x0000000000000009 0x0000000000000007
(gdb) x/16i 0x0000000000418969-8
0x418961: add %cl,0xffffffffffffff89(%rax)
0x418964: add $0x19bf4f,%eax
0x418969: cmpb $0x2d,(%rax)
0x41896c: je 0x418c46
0x418972: mov 1687359(%rip),%rdx # 0x5b48b8
0x418979: cmpb $0x73,(%rdx)
0x41897c: je 0x418c21
0x418982: mov 1687343(%rip),%rdx # 0x5b48b8
0x418989: cmpb $0x73,(%rdx)
0x41898c: je 0x418bfa
0x418992: mov 1705607(%rip),%rdi # 0x5b9020
0x418999: mov %rbx,1687320(%rip) # 0x5b48b8
0x4189a0: test %rdi,%rdi
0x4189a3: jne 0x418bee
0x4189a9: mov 1687304(%rip),%rdi # 0x5b48b8
0x4189b0: callq 0x417380
(gdb)
For this case, I don't know how to debug it accord to these information!
Example 4
Aim: for dead-lock case.
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
pthread_t ntid;
class
Mutex
{
public
:
Mutex(
bool
recursive =
false
) {
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr,
recursive ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_ERRORCHECK );
pthread_mutex_init(&d_mutex, &attr);
pthread_mutexattr_destroy(&attr);
}
~Mutex() { pthread_mutex_destroy(&d_mutex); }
void
Lock() { pthread_mutex_lock(&d_mutex); }
void
Lock_Cancel() { pthread_testcancel(); pthread_mutex_lock(&d_mutex); }
void
Unlock() { pthread_mutex_unlock(&d_mutex); }
bool
TryLock() {
return
pthread_mutex_trylock(&d_mutex) == 0; }
private
:
pthread_mutex_t d_mutex;
};
void
printids(
const
char
*s)
{
pid_t pid;
pthread_t tid;
pid = getpid();
tid = pthread_self();
printf
(
"%s pid %u tid %u (0x%x)\n"
, s, (unsigned
int
)pid,
(unsigned
int
)tid, (unsigned
int
)tid);
}
Mutex locker, locker2;
void
* thr_fn(
void
*arg)
{
int
count = 1000;
if
(arg != NULL)
count = *((
int
*)arg);
locker.Lock();
int
i=0;
for
(i=0; i<count; ++i)
{
printf
(
"Func 1 Time %d : "
, i);
locker2.Lock();
printids(
"new thread: "
);
sleep(1);
locker2.Unlock();
}
locker.Unlock();
return
((
void
*)0);
}
int
main(
void
)
{
int
err;
pthread_t tid1, tid2;
void
* tret;
int
count = 10;
printf
(
"PID=%d\n"
, getpid());
// thread 1
err = pthread_create(&tid1, NULL, thr_fn, NULL);
if
(err != 0)
{
printf
(
"can't create thread : %s\n"
,
strerror
(err));
}
printf
(
"Create thread 1 : %u \n"
, (unsigned
int
)tid1);
// thread 2
err = pthread_create(&tid2, NULL, thr_fn, &count);
if
(err != 0)
{
printf
(
"can't create thread : %s\n"
,
strerror
(err));
}
printf
(
"Create thread 2 : %u \n"
, (unsigned
int
)tid2);
printids(
"main thread:"
);
sleep(1);
pthread_cancel(tid1);
printf
(
"Cancel thread 1\n"
);
err = pthread_join(tid1, &tret);
if
(err != 0)
printf
(
"can't join with thread 1: %s\n"
,
strerror
(err));
printf
(
"thread 1 exit code %d\n"
, (
int
)tret);
err = pthread_join(tid2, &tret);
if
(err != 0)
printf
(
"can't join with thread 2: %s\n"
,
strerror
(err));
printf
(
"thread 2 exit code %d\n"
, (
int
)tret);
return
0;
}
|
g++ -o test deadlock.cc –lpthread
(shell 1)nochen@bclnx64 ~/test$ ./test
PID=4249
Create thread 1 : 1084229984
Create thread 2 : 1094719840
main thread: pid 4249 tid 2505602208 (0x955874a0)
Func 1 Time 0 : new thread: pid 4249 tid 1084229984 (0x40a00960)
Cancel thread 1
thread 1 exit code -1
(shell 2)gdb ./test
(gdb) attach 4249
(gdb) info thread
2 Thread 1094719840 (LWP 4251) 0x0000003cf620adfb in __lll_mutex_lock_wait () from /lib64/tls/libpthread.so.0
1 Thread 182894228640 (LWP 4249) 0x0000003cf6206ffb in pthread_join () from /lib64/tls/libpthread.so.0
(gdb) bt
#0 0x0000003cf6206ffb in pthread_join () from /lib64/tls/libpthread.so.0
#1 0x0000000000400d8e in main ()
(gdb) thread 2
[Switching to thread 2 (Thread 1094719840 (LWP 4251))]#0 0x0000003cf620adfb in __lll_mutex_lock_wait ()
from /lib64/tls/libpthread.so.0
(gdb) bt
#0 0x0000003cf620adfb in __lll_mutex_lock_wait () from /lib64/tls/libpthread.so.0
#1 0x00000000414011e0 in ?? ()
#2 0x00000000414019f0 in ?? ()
#3 0x0000003cf6207bd4 in pthread_mutex_lock () from /lib64/tls/libpthread.so.0
#4 0x0000000000000000 in ?? ()
(gdb) info register
rax 0xfffffffffffffffc -4
rbx 0x0 0
rcx 0xffffffffffffffff -1
rdx 0x2 2
rsi 0x0 0
rdi 0x501740 5248832
rbp 0x414011b0 0x414011b0
rsp 0x41401100 0x41401100
rip 0x3cf620adfb 0x3cf620adfb <__lll_mutex_lock_wait+27>
eflags 0x202 514
(gdb) x/16gx 0x414011b0 - 16
0x414011a0: 0x0000000000000000 0x0000000000501740
0x414011b0: 0x00000000414011d0 0x0000000000400b4d
0x414011c0: 0x0000000a00000000 0x0000007fbffff3cc
0x414011d0: 0x0000000000000000 0x0000003cf620610a (not useful information)
0x414011e0: 0x0000000000000000 0x0000000041401960
0x414011f0: 0x0000000041401960 0x0000000000000000
0x41401200: 0x0000003cf6206080 0x0000003cf620d4e0
0x41401210: 0x0000000000000000 0x0000003cf620d4e0
(gdb) x/32i 0x0000000000400b4d - 4
0x400b49 <_Z6thr_fnPv+41>: push %rbx
0x400b4a <_Z6thr_fnPv+42>: add (%rax),%eax
0x400b4c <_Z6thr_fnPv+44>: add %al,%bh
0x400b4e <_Z6thr_fnPv+46>: rexXZ lock add %al,(%rax)
0x400b52 <_Z6thr_fnPv+50>: add %al,(%rax)
0x400b54 <_Z6thr_fnPv+52>: movl $0x0,0xfffffffffffffff0(%rbp)
0x400b5b <_Z6thr_fnPv+59>: mov 0xfffffffffffffff0(%rbp),%eax
0x400b5e <_Z6thr_fnPv+62>: cmp 0xfffffffffffffff4(%rbp),%eax
0x400b61 <_Z6thr_fnPv+65>: jge 0x400ba5 <_Z6thr_fnPv+133>
0x400b63 <_Z6thr_fnPv+67>: mov 0xfffffffffffffff0(%rbp),%esi
0x400b66 <_Z6thr_fnPv+70>: mov $0x401035,%edi
0x400b6b <_Z6thr_fnPv+75>: mov $0x0,%eax
From these information, we can know that the dead-lock is in function thr_fnPv+44 and thr_fnPv+46。 Thus we know it is because thread 2(1094719840) can’t get lock!
Example 5
Aim: for dead-lock case.
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
pthread_t ntid;
class
Mutex
{
public
:
Mutex(
bool
recursive =
false
) {
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr,
recursive ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_ERRORCHECK );
pthread_mutex_init(&d_mutex, &attr);
pthread_mutexattr_destroy(&attr);
}
~Mutex() { pthread_mutex_destroy(&d_mutex); }
void
Lock() { pthread_mutex_lock(&d_mutex); }
void
Lock_Cancel() { pthread_testcancel(); pthread_mutex_lock(&d_mutex); }
void
Unlock() { pthread_mutex_unlock(&d_mutex); }
bool
TryLock() {
return
pthread_mutex_trylock(&d_mutex) == 0; }
private
:
pthread_mutex_t d_mutex;
};
void
printids(
const
char
*s)
{
pid_t pid;
pthread_t tid;
pid = getpid();
tid = pthread_self();
printf
(
"%s pid %u tid %u (0x%x)\n"
, s, (unsigned
int
)pid,
(unsigned
int
)tid, (unsigned
int
)tid);
}
Mutex locker, locker2;
void
* thr_fn(
void
*arg)
{
int
count = 1000;
if
(arg != NULL)
count = *((
int
*)arg);
locker.Lock();
int
i=0;
for
(i=0; i<count; ++i)
{
printf
(
"Func 1 Time %d : "
, i);
locker2.Lock();
printids(
"new thread: "
);
sleep(1);
locker2.Unlock();
}
locker.Unlock();
return
((
void
*)0);
}
void
* thr_fn2(
void
*arg)
{
int
count = 1000;
if
(arg != NULL)
count = *((
int
*)arg);
locker2.Lock();
int
i=0;
for
(i=0; i<count; ++i)
{
printf
(
"Func2 Time %d : "
, i);
locker.Lock();
printids(
"new thread: "
);
sleep(1);
locker.Unlock();
}
locker2.Unlock();
return
((
void
*)0);
}
int
main(
void
)
{
int
err;
pthread_t tid1, tid2;
void
* tret;
int
count = 10;
printf
(
"PID=%d\n"
, getpid());
// thread 1
err = pthread_create(&tid1, NULL, thr_fn, NULL);
if
(err != 0)
{
printf
(
"can't create thread : %s\n"
,
strerror
(err));
}
printf
(
"Create thread 1 : %u \n"
, (unsigned
int
)tid1);
// thread 2
err = pthread_create(&tid2, NULL, thr_fn2, &count);
if
(err != 0)
{
printf
(
"can't create thread : %s\n"
,
strerror
(err));
}
printf
(
"Create thread 2 : %u \n"
, (unsigned
int
)tid2);
printids(
"main thread:"
);
sleep(1);
// pthread_cancel(tid1);
// printf("Cancel thread 1\n");
err = pthread_join(tid1, &tret);
if
(err != 0)
printf
(
"can't join with thread 1: %s\n"
,
strerror
(err));
printf
(
"thread 1 exit code %d\n"
, (
int
)tret);
// thread 2
/* err = pthread_create(&tid2, NULL, thr_fn, &count);
if (err != 0)
{
printf("can't create thread : %s\n", strerror(err));
}
printf("Create thread 2 : %u \n", (unsigned int)tid2); */
////////////////////////////////
err = pthread_join(tid2, &tret);
if
(err != 0)
printf
(
"can't join with thread 2: %s\n"
,
strerror
(err));
printf
(
"thread 2 exit code %d\n"
, (
int
)tret);
return
0;
}
|
g++ -g -o test deadlock.cc –lpthread
nochen@bclnx64 ~/test$ ./test
PID=6283
Create thread 1 : 1084229984
Create thread 2 : 1094719840
main thread: pid 6283 tid 2505602208 (0x955874a0)
Func 1 Time 0 : new thread: pid 6283 tid 1084229984 (0x40a00960)
Shell 2:
gdb ./test
(gdb) attach 6283
(gdb) info thread
3 Thread 1084229984 (LWP 6284) 0x0000003cf620adfb in __lll_mutex_lock_wait () from /lib64/tls/libpthread.so.0
2 Thread 1094719840 (LWP 6285) 0x0000003cf620adfb in __lll_mutex_lock_wait () from /lib64/tls/libpthread.so.0
* 1 Thread 182894228640 (LWP 6283) 0x0000003cf6206ffb in pthread_join () from /lib64/tls/libpthread.so.0
(gdb) thread 2
[Switching to thread 2 (Thread 1094719840 (LWP 6285))]#0 0x0000003cf620adfb in __lll_mutex_lock_wait ()
from /lib64/tls/libpthread.so.0
(gdb) info register
rax 0xfffffffffffffffc -4
rbx 0x0 0
rcx 0xffffffffffffffff -1
rdx 0x2 2
rsi 0x0 0
rdi 0x5016a0 5248672
rbp 0x414011b0 0x414011b0
rsp 0x41401100 0x41401100
rip 0x3cf620adfb 0x3cf620adfb <__lll_mutex_lock_wait+27>
eflags 0x202 514
(gdb) x/32gx 0x414011b0 - 16
0x414011a0: 0x0000000000000000 0x00000000005016a0
0x414011b0: 0x00000000414011d0 0x0000000000400bc5
0x414011c0: 0x0000000a00000000 0x0000007fbffff3cc
0x414011d0: 0x0000000000000000 0x0000003cf620610a
0x414011e0: 0x0000000000000000 0x0000000041401960
0x414011f0: 0x0000000041401960 0x0000000000000000
(gdb) x/32i 0x0000000000400bc5 - 2
0x400bc3 <_Z7thr_fn2Pv+93>: add %al,(%rax)
0x400bc5 <_Z7thr_fn2Pv+95>: mov $0x400fd7,%edi
0x400bca <_Z7thr_fn2Pv+100>: callq 0x400a88 <_Z8printidsPKc>
0x400bcf <_Z7thr_fn2Pv+105>: mov $0x1,%edi
0x400bd4 <_Z7thr_fn2Pv+110>: callq 0x400938
0x400bd9 <_Z7thr_fn2Pv+115>: mov $0x5016a0,%edi
0x400bde <_Z7thr_fn2Pv+120>: callq 0x400e20 <_ZN5Mutex6UnlockEv>
0x400be3 <_Z7thr_fn2Pv+125>: lea 0xfffffffffffffff0(%rbp),%rax
0x400be7 <_Z7thr_fn2Pv+129>: incl (%rax)
0x400be9 <_Z7thr_fn2Pv+131>: jmp 0x400ba1 <_Z7thr_fn2Pv+59>
0x400beb <_Z7thr_fn2Pv+133>: mov $0x5016e0,%edi
0x400bf0 <_Z7thr_fn2Pv+138>: callq 0x400e20 <_ZN5Mutex6UnlockEv>
0x400bf5 <_Z7thr_fn2Pv+143>: mov $0x0,%eax
0x400bfa <_Z7thr_fn2Pv+148>: leaveq
0x400bfb <_Z7thr_fn2Pv+149>: retq
(gdb) thread 3
[Switching to thread 3 (Thread 1084229984 (LWP 6284))]#0 0x0000003cf620adfb in __lll_mutex_lock_wait ()
from /lib64/tls/libpthread.so.0
(gdb) info register
rax 0xfffffffffffffffc -4
rbx 0x0 0
rcx 0xffffffffffffffff -1
rdx 0x2 2
rsi 0x0 0
rdi 0x5016e0 5248736
rbp 0x40a001b0 0x40a001b0
rsp 0x40a00100 0x40a00100
rip 0x3cf620adfb 0x3cf620adfb <__lll_mutex_lock_wait+27>
eflags 0x202 514
(gdb) x/16gx 0x40a001b0 - 16
0x40a001a0: 0x0000000040a001d0 0x00000000005016e0
0x40a001b0: 0x0000000040a001d0 0x0000000000400b2f
0x40a001c0: 0x000003e800000001 0x0000000000000000
0x40a001d0: 0x0000000000000000 0x0000003cf620610a
0x40a001e0: 0x0000000000000000 0x0000000040a00960
0x40a001f0: 0x0000000040a00960 0x0000000000000000
0x40a00200: 0x0000003cf6206080 0x0000003cf620d4e0
0x40a00210: 0x0000000000000000 0x0000003cf620d4e0
(gdb) x/32i 0x0000000000400b2f-2
0x400b2d <_Z6thr_fnPv+93>: add %al,(%rax)
0x400b2f <_Z6thr_fnPv+95>: mov $0x400fd7,%edi
0x400b34 <_Z6thr_fnPv+100>: callq 0x400a88 <_Z8printidsPKc>
0x400b39 <_Z6thr_fnPv+105>: mov $0x1,%edi
0x400b3e <_Z6thr_fnPv+110>: callq 0x400938
0x400b43 <_Z6thr_fnPv+115>: mov $0x5016e0,%edi
0x400b48 <_Z6thr_fnPv+120>: callq 0x400e20 <_ZN5Mutex6UnlockEv>
0x400b4d <_Z6thr_fnPv+125>: lea 0xfffffffffffffff0(%rbp),%rax
0x400b51 <_Z6thr_fnPv+129>: incl (%rax)
0x400b53 <_Z6thr_fnPv+131>: jmp 0x400b0b <_Z6thr_fnPv+59>
0x400b55 <_Z6thr_fnPv+133>: mov $0x5016a0,%edi
0x400b5a <_Z6thr_fnPv+138>: callq 0x400e20 <_ZN5Mutex6UnlockEv>
0x400b5f <_Z6thr_fnPv+143>: mov $0x0,%eax
0x400b64 <_Z6thr_fnPv+148>: leaveq
0x400b65 <_Z6thr_fnPv+149>: retq
0x400b66 <_Z7thr_fn2Pv>: push %rbp
0x400b67 <_Z7thr_fn2Pv+1>: mov %rsp,%rbp
0x400b6a <_Z7thr_fn2Pv+4>: sub $0x10,%rsp
0x400b6e <_Z7thr_fn2Pv+8>: mov %rdi,0xfffffffffffffff8(%rbp)
0x400b72 <_Z7thr_fn2Pv+12>: movl $0x3e8,0xfffffffffffffff4(%rbp)
0x400b79 <_Z7thr_fn2Pv+19>: cmpq $0x0,0xfffffffffffffff8(%rbp)
0x400b7e <_Z7thr_fn2Pv+24>: je 0x400b89 <_Z7thr_fn2Pv+35>
0x400b80 <_Z7thr_fn2Pv+26>: mov 0xfffffffffffffff8(%rbp),%rax
0x400b84 <_Z7thr_fn2Pv+30>: mov (%rax),%eax
0x400b86 <_Z7thr_fn2Pv+32>: mov %eax,0xfffffffffffffff4(%rbp)
0x400b89 <_Z7thr_fn2Pv+35>: mov $0x5016e0,%edi
0x400b8e <_Z7thr_fn2Pv+40>: callq 0x400e38 <_ZN5Mutex4LockEv>
0x400b93 <_Z7thr_fn2Pv+45>: movl $0x0,0xfffffffffffffff0(%rbp)
0x400b9a <_Z7thr_fn2Pv+52>: movl $0x0,0xfffffffffffffff0(%rbp)
0x400ba1 <_Z7thr_fn2Pv+59>: mov 0xfffffffffffffff0(%rbp),%eax
0x400ba4 <_Z7thr_fn2Pv+62>: cmp 0xfffffffffffffff4(%rbp),%eax
0x400ba7 <_Z7thr_fn2Pv+65>: jge 0x400beb <_Z7thr_fn2Pv+133>
(gdb) Quit
Thus we know function thr_fn and thr_fn2 is dead-lock!
本文转自 zhenjing 博客园博客,原文链接: http://www.cnblogs.com/zhenjing/archive/2011/03/23/advance_debug2.html ,如需转载请自行联系原作者