现象:

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​