您的位置:首页 > 其它

pthread_kill Segmentation fault

2012-02-12 11:20 375 查看
这几天在调试服务器程序,通过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 <printf@plt>

/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 <pthread_kill@plt> 
 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 <signal.h>

#include <errno.h>

#include <pthread.h>

#include <unistd.h>

#include <sys/types.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  kill thread null 测试 ubuntu