现象:
linux c编译的一个动态库,放到多台机器,其中一台机器产生core文件,其它机器正常运行。
分析:
由于编译成动态库,系统使用不生成core文件,无法跟踪问题。
一、直接编译动态库,调用出现core的函数
#include <stdio.h>
int main()
{
sign8256_20();
return 0;
}
注意编译和执行
将sign.so改成标准三方库名,并放到当前目录,修改LD_LIBRARY_PATH环境变量,执行./a.out
cp ~/dll/sign.so libsign.so
gcc test.c -L./ -lsign
export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH:
./a.out
二、单独编写dlsym程序,调用出现core的函数,进行测试。程序如下:
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#define FAIL -1
int (*p_func)();
void *p_handle;
int main()
{
int iRetCode;
char strFuncName[48+1] = {0};
char strFileName[256+1]= {0};
char strDllName[256+1] = {0};
memset(strDllName,0,sizeof(strDllName));
sprintf(strDllName,"%s/dll/sign.so",getenv("BASE"));
p_handle = dlopen(strDllName,RTLD_NOW);
if ( NULL == p_handle )
{
printf("error [%s][%d]\n",dlerror(),__LINE__);
dlclose(p_handle);
return FAIL;
}
sprintf(strFuncName,"sign8256_20");
p_func = (int (*))dlsym(p_handle,strFuncName);
if ( NULL == p_func )
{
printf("error [%s][%d]\n",dlerror(),__LINE__);
dlclose(p_handle);
return FAIL;
}
iRetCode = p_func();
if( iRetCode < 0)
{
printf("error [%s][%d]\n",dlerror(),__LINE__);
dlclose(p_handle);
return FAIL;
}
dlclose(p_handle);
return 0;
}
两种方式,运行程序,产生core文件。使用gdb跟踪时,发现程序进入这个函数之后,直接coredump。
gdb 使用info locals查看变量的时候发现,出现core文件这个台机器的打印出现了异常。最后变量报这个异常
stSign = <error reading variable stSign (Cannot access memory at address 0x7fffff56c980)>
结论:
确认为进程的默认的栈空间太小,该函数声明的变量超限。
执行ulimit -s 命令,发现系统默认栈空间大小为8192。
扩大系统默认栈空间,两种方案
1、/etc/rc.local 加入
ulimit -s 102400
2、/etc/security/limits.conf 加入
* soft stack 102400