问题描述:
在一个客户现场搭建环境时,遇到了一个棘手的问题,C代码编译通过后,无法正常运行,启动会出现“coredump”错误。
运行环境为新搭建的AIX6.1,数据库为Oracle11.2.0.2.0。
将平台的C代码部署到用户下之后,makefile编译成功,之后启动程序,发现无法正常运行,启动会出现“coredump”错误。
问题排查:
根据dbx工具定位的代码位置,检查代码并未发现内存泄漏、越界等bug;到这就卡住了。
为了确定是否为代码的问题,新创建test.ec程序如下:
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <string.h> 4 #include "sqlca.h" 5 6 int main(int argc, char *argv[]) 7 { 8 9 int iRet ; 10 int ch; 11 char ll[20]; 12 char hh[20]; 13 char tt[20]; 14 char *p=NULL; 15 16 memset(ll,0x00,sizeof(ll)); 17 memset(hh,0x00,sizeof(hh)); 18 memset(tt,0x00,sizeof(tt)); 19 20 while((ch=getopt(argc,argv,"l:h:t:")) != -1) 21 { 22 switch (ch) { 23 case 'l': 24 strcpy(ll,optarg); 25 printf("ll=[%s]\n",ll); 26 break; 27 case 'h': 28 strcpy(hh,optarg); 29 printf("hh=[%s]\n",hh); 30 break; 31 case 't': 32 strcpy(tt,optarg); 33 printf("tt=[%s]\n",tt); 34 break; 35 case '?': 36 break; 37 } 38 } 39 printf("获取入参成功!\n"); 40 p=strstr(tt,"b"); 41 printf("p=[%s]\n",p); 42 return 0; 43 }
Makefile如下:
1 all: test 2 3 test:test.ec 4 proc line=yes def_sqlcode=yes code=ansi_c ltype=short parse=partial proc mode=ansi define=__64BIT__ define=_IBM_C define=_LONG_LONG "include=$(ORACLE_HOME)/precomp/public" define=_WITH_ORACLE define=_WITH_ORACLE_PROC_PARSE iname=test.ec 5 xlc -U_STR_ -q64 -qcpluscmt -g -brtl -qformat -bhalt:5 -DAIX -DDEBUG -I$(ORACLE_HOME)/precomp/public -D_WITH_ORACLE -o test test.c -L$(ORACLE_HOME)/lib -lclntsh
编译过程未出错,而在执行的时候,直接报错:
之后根据dbx调试,发现程序在执行getopt函数的时候coredump的:
设置断点调试:
而在断点调试过程中,发现getopt函数本身并不会导致程序溢出,网上查了一下,有人说是因为包含了多余的头文件导致,故将#include <string.h >代码注释掉,发现可以执行,但是strstr函数执行会coredump,所以问题不在这里。
此时,基本可以断定问题不在代码上,应该是环境的问题,因此又挨个注释Makefile中的链接动态库发现,将oracle动态库libclntsh.so的链接去掉后,可以执行成功:
故初步判断是oracle动态库与当前系统不兼容导致。
对链接动态库进行测试,发现不链接libclntsh.so时,程序可运行,否则会出现coredump。
将test程序移植到另外一台服务器A上测试,发现可以正常运行,推测服务器环境有问题。对比2台服务器,差别如下:
1、操作系统版本偏低(当前服务器为6100-05-01-1016,A服务器上的版本为6100-06-08-1216)。
2、VAC版本偏低(当前服务器为11.1.0.0,A服务器上的版本为11.1.0.7)。
3、数据库版本偏低(当前服务器为11.2.0.2.0,A服务器上的版本为11.2.0.3.0)。
问题解决:
首先对xlc编译器升级,打补丁到11.1.0.7版本,发现程序不再coredump。
确定问题为xlc编译器版本过低,与oracle动态库不兼容导致。