zoukankan      html  css  js  c++  java
  • [Advance] How to debug a program (下):示例

    参考:[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 ./test
    (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;
    }
    
    Shell 1:
    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!
  • 相关阅读:
    C++输入cout与输出cin
    golang学习笔记
    vscode环境配置
    golang 微框架 gin
    git go使用socket5代理
    go包管理工具glide
    collectd的python插件(redis)
    zookeeper & kafka 集群
    redis复制集(sentinel)
    python加解密
  • 原文地址:https://www.cnblogs.com/zhenjing/p/advance_debug2.html
Copyright © 2011-2022 走看看