写一套程序,WebService的用了Thrift,还有一个单机版。单机版运行一直正常,Thrift版却总Crash在一个功能类的一个成员函数上。注意,是成员函数上,而不是成员函数里。但在GDB的调试过程中,运行无比正常,用GDB调试Core就显示在了该函数上。
出错原因是在运行时编译器发现函数中对栈空间的使用它搞不定了,就是太大了,于是在进入函数前就Crash掉了。
于是缩小了该函数中对栈的空间使用,正常通过。
也尝试了用各种方式来增加程序对栈的使用上限。
1. 用ulimit -s 查看大小,但用ulimit -s 40960等增加也并不管用。
2. 看一个帖子:http://zjf30366.blog.163.com/blog/static/4111645820117453719575/
用这样的程序来修改线程栈大小:
void *stackaddr;
size_t stacksize;
size_t guardsize;
pthread_attr_t attr;
if (pthread_attr_init(&attr) != 0){
printf("init attr failed.\n");
return -1;
}
if (pthread_attr_getstacksize(&attr,&stacksize) == 0){
printf("default stacksize:0x%x\n",stacksize);
}
if (pthread_attr_getstack(&attr,&stackaddr,&stacksize) == 0){
printf("default stacksize:0x%x,stack addr:%p\n",stacksize,stackaddr);
}
if (pthread_attr_getguardsize(&attr,&guardsize) == 0){
printf("default guardsize:%u\n",guardsize);
}
stacksize = 40960;
if (pthread_attr_setstacksize(&attr,stacksize) != 0){
printf("set thread stack size failed,error:%s\n",strerror(errno));
return -1;
}
printf("-----------\n");
if (pthread_attr_getstack(&attr,&stackaddr,&stacksize) == 0){
printf("after set stacksize,stacksize:0x%x,stack addr:%p\n",stacksize,stackaddr);
}
if (pthread_attr_setstack(&attr,(void *)0x80000,stacksize) != 0){
printf("set stack error:%s\n",strerror(errno));
}
if (pthread_attr_getguardsize(&attr,&guardsize) == 0){
printf("after set stack,guardsize:%u\n",guardsize);
}
if (pthread_attr_getstack(&attr,&stackaddr,&stacksize) == 0){
printf("after setstack,stacksize:0x%x,stack addr:%p\n",stacksize,stackaddr);
}
printf("-----------\n");
if (pthread_attr_getstacksize(&attr,&stacksize) == 0){
printf("default stacksize:0x%x\n",stacksize);
}
if (pthread_attr_getstack(&attr,&stackaddr,&stacksize) == 0){
printf("default stacksize:0x%x,stack addr:%p\n",stacksize,stackaddr);
}
if (pthread_attr_getguardsize(&attr,&guardsize) == 0){
printf("default guardsize:%u\n",guardsize);
}
也并不管用。
3. 用Thrift的PosixThreadFactory类中的void setStackSize(int value)函数来设置线程栈大小,该问题得以解决。
我是用的Thrift中非阻塞的方式:
threadManager = ThreadManager::newSimpleThreadManager(100);
shared_ptr<PosixThreadFactory> threadFactory = shared_ptr<PosixThreadFactory>(new PosixThreadFactory());
int nStackSize = threadFactory->getStackSize();
printf("1:stack size:%d\n", nStackSize); // default value is 1
threadFactory->setStackSize(10);
nStackSize = threadFactory->getStackSize();
printf("2:stack size:%d\n", nStackSize);
threadManager->threadFactory(threadFactory);
threadManager->start();
总结:
单机版运行无误,Thrift版运行Crash,是因为函数中除了自身需要的,Thrift也会占去一部分,而且不好用系统的系统的线程栈函数来修改,而用Thrift自已的接口函数来修改。
为求保险还是应该缩小函数中对栈空间的使用。