pthread_kill Segmentation fault

这几天在调试服务器程序,通过pthread_kill给接收线程对象发信号处理,发现程序运行到pthread_kill处失败,调用打印堆栈信息如下

frame 0 -- ./datactlserver(_Z13SignalHandleri+0x43) [0x80541bb]
frame 1 -- [0xf85400]
frame 2 -- /lib/i386-linux-gnu/libpthread.so.0(pthread_kill+0x9) [0x843b79]
frame 3 -- ./datactlserver(_ZN7CThread6WakeupEv+0x3a) [0x806ad6a]
frame 4 -- ./datactlserver(_ZN13CListenThread6ListenEv+0x40f) [0x80699d7]
frame 5 -- ./datactlserver(_ZN13CListenThread3RunEv+0x4e) [0x806947e]
frame 6 -- ./datactlserver(_ZN7CThread14ThreadFunctionEPv+0x1b) [0x806ac7d]
frame 7 -- /lib/i386-linux-gnu/libpthread.so.0(+0x6d31) [0x83ed31]
frame 8 -- /lib/i386-linux-gnu/libc.so.6(clone+0x5e) [0x9b30ce]


反汇编程序查看0x843b79指针地址如下:

    // 给该线程发送信号,唤醒当前线程,继续运行
    printf("pthread_kill error m_ThreadID=%d\n", m_ThreadID);
 806ad3d: 8b 45 08             mov    0x8(%ebp),%eax
 806ad40: 8b 40 08             mov    0x8(%eax),%eax
 806ad43: 89 44 24 04          mov    %eax,0x4(%esp)
 806ad47: c7 04 24 60 ea 06 08 movl   $0x806ea60,(%esp)
 806ad4e: e8 4d 8e fe ff       call   8053ba0
/home/dalek/work/2012/2.11/datactl/src/comm/src/thread.cpp:132
    iRet = pthread_kill(m_ThreadID, SIGRTMIN);
 806ad53: e8 78 8c fe ff       call   80539d0 <__libc_current_sigrtmin@plt>
 806ad58: 8b 55 08             mov    0x8(%ebp),%edx
 806ad5b: 8b 52 08             mov    0x8(%edx),%edx
 806ad5e: 89 44 24 04          mov    %eax,0x4(%esp)
 806ad62: 89 14 24             mov    %edx,(%esp)
 806ad65: e8 26 8c fe ff      call   8053990  
 806ad6a: 89 45 f4            mov    %eax,-0xc(%ebp)
/home/dalek/work/2012/2.11/datactl/src/comm/src/thread.cpp:133
    if ( DC_RET_OK != iRet )
 806ad6d: 83 7d f4 00          cmpl   $0x0,-0xc(%ebp)
 806ad71: 74 1a                je     806ad8d <_ZN7CThread6WakeupEv+0x5d>
/home/dalek/work/2012/2.11/datactl/src/comm/src/thread.cpp:136

可以断定程序运行到红色部分失败了,这说明确实调用pthread_kill 后程序崩溃,而且是在pthread_kill 内部,

这个是什么原因呢,我们来看下如下的信号测试程序,如下程序在ubuntu 11.10上测试执行通过:

g++ sigwait_test.cpp -lpthread

产生a.out

sigwait_test.cpp:

#include
#include
#include
#include
#include
#include
#include
#include


void sig_handler(int signum)
{
    printf("Receive signal. %d\n", signum);
}

void* sigmgr_thread(void *arg)
{
    sigset_t   waitset, oset;
    int        sig;
    int        rc;
    pthread_t  ppid = pthread_self();

    pthread_detach(ppid);

    sigemptyset(&waitset);
    sigaddset(&waitset, SIGRTMIN);

    while (1)  {
        rc = sigwait(&waitset, &sig);
        if (rc != -1) {
            sig_handler(sig);
        } else {
            printf("sigwaitinfo() returned err: %d; %s\n", errno, strerror(errno));
        }
    }
}

int main()
{
    sigset_t bset, oset;
    int             i;
    pid_t           pid = getpid();
    pthread_t       ppid;


    sigemptyset(&bset);
    sigaddset(&bset, SIGRTMIN);

    if (pthread_sigmask(SIG_BLOCK, &bset, &oset) != 0)
        printf("!! Set pthread mask failed\n");

    kill(pid, SIGRTMIN);

    printf("create thread\n");
    // Create the dedicated thread sigmgr_thread() which will handle signals synchronously
    pthread_create(&ppid, NULL, sigmgr_thread, NULL);


while(1)
{
printf("hello\n");
//sleep(1);
pthread_kill(ppid, SIGRTMIN);
//pthread_cancel(ppid);
}


    exit (0);
}

程序执行1小时未发现异常,那么这个Segmentation fault是怎么产生的呢,

我们修改下程序:

while(1)
{
printf("hello\n");
//sleep(1);
pthread_kill(8888, SIGRTMIN);

}

我们在来执行下程序,结果如下:

create thread
hello
Segmentation fault

由此可知段错误是因为给pthread_kill传入了一个非法的线程ID.

你可能感兴趣的:(linux/unix,c/c++)