問題:程序編譯通過,但是執行時報錯:coredump
- 2019 年 10 月 3 日
- 筆記
問題描述:
在一個客戶現場搭建環境時,遇到了一個棘手的問題,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動態庫不兼容導致。