Friday, September 10, 2010

Internal error (40101) when pre-compiling a program based on pro*c

This article was originally posted in my csdn.net blog on 7 May 2009.


A pro*c based program was to be deployed on an AIX machine (AIX 5.3+Oracle 10.2.0.3) for test purpose, but unfortunately I encountered an error when pre-compiling the program. The error message was as follows:

System default option values taken from: /ora10g/product/102/precomp/admin/pcscfg.cfg

INTERNAL ERROR: Failed Assertion [Code=40101]


I googled this information and found there was somebody having the same problem on OTN: http://forums.oracle.com/forums/thread.jspa?messageID=2561956

I tried those programs in above OTN page and got the same results. According to some comments, the compile mode of xlc should be 64 bit, and the define option of proc should include __64BIT__. But both were eligible for our situation. Read this page thoroughly but there was no other useful information.

Our program doesn't use pid_t directly, but the header file pthread.h is included. Thus I wrote another test program like this:

/*abc.pc*/
#include <pthread.h>
#include <stdio.h>
main()
{
printf("hello\n");
}

Unfortunately the same error occured when the command 'proc abc' was issued. But It's ok when the included header file pthread.h was removed.

At last I turned to oracle technicians for help, and they gave me an FAQ on metalink:

Metalink Doc ID: 263286.1
Cause:
The Pro*C source code contains a long CASE statement or a long IF ELSE statement
Solution:
Split the CASE or the IF ELSE statement
References
Bug 530920 - SEGMENTATION FAULT(COREDUMP) WHEN PRECOMPILING VERY LONG IF STATEMENTS

Login metalink to get more details.


That is to say, there is a bug for oracle proc. I checked our program, there are some a little bit long switch, case, and if else statements. Therefore, I modified them to assure that only about 30 lines were included in the longest switch, case and if else statements. But the error still persisted.

Just when I was having no idea about that, I found some general oracle commands, such as sqlplus/exp/imp, couldn’t be used either. But all the command worked well when I switched to oracle user. According to this clue, I immediately switched to oracle use and pre-compile the above test program. It's ok! And then I moved the original program to oracle user and compilation was also successfully done.

And I also found it was ok as long as the user was in dba group. Therefore we could make a conclusion for this problem: there were some privilege problems when the oracle was installed and some directories or files couldn’t not be accessed by users in other group.

A conflicting scenario in header file sqltypes.h of Timesten and Informix

This article is originally posted in my csdn.net blog on 7 May 2009.


Oracle is usually used as the phisycal database when TimesTen is working as in-memory database, because the data synchronization is very easy by using cache connect in such situation. But we had to use Informix as the physical database in some projects and we encountered problems just at the compilation stage.

In our product, the database access component which was based on esql includes the header file $INFORMIXDIR/incl/esql/sqltypes.h, and the component for accessing TimesTen was ODBC-oriented and includes the header file $TIMESTEN_HOME/include/sqltypes.h.

These two files are identical in file name but not in content. What's more, there are some identical macro names which differ either in data type or value. For example, SQLCHAR is one of the macros defined as follows:

//definition in Informix

#define SQLCHAR 0

//definition in TT

typedef unsigned char UCHAR;
typedef UCHAR SQLCHAR;

These components were compiled in a big project with the above two header file directories included by -I option. So errors occurred in the compilation process.

If the directory of Informix is included prior to that of TT, errors occur when compiling the component for TT, and vice versa.

The solution is to change the directory inclusion sequence according to which component is compiling.

A solution for conflict of structure loc_t in header files of vac compiler and informix esql on AIX

This article was originally posted in my csdn.net blog on 6 May 2009.


I encountered an error several days ago when a program based on informix esql was compiled on AIX platform. Error message:

"/informix/incl/esql/locator.h", line 124.7: 1540-0400 (S) "loc_t" has a conflicting declaration.
"/usr/include/sys/localedef31.h", line 195.3: 1540-0425 (I) "loc_t" is defined on line 195 of "/usr/include/sys/localedef31.h".
make: 1254-004 The error code from the last command is 1.

The version of Informix CliSDK is 2.81.FC2.AIX5L, and the same error occured when I compiled it using different vac compilers in version 6.0 and 7.0.

According to the error message, it's easy to locate the problem. I checked both two header files. Both files include definition of a structure loc_t with totally different content. The file localedef31.h should be used in customised program because it includes the format definition of currency, time, number and so on, while loc_t in locator.h is defined for accessing large object in Informix.

By consulting the Informix technician, I got to know there is a pre-compilation macro _H_LOCALEDEF to invalidate the defintion in vac compiler. And the definition in Informix esql header file can also be invalidated by introduction of pre-compilation macro IFX_DISABLE_LOC_T if the Informix CliSDK verion is 3.50 or higher.

As for our project, we have to access the large object and the definition of loc_t in Informix esql should be kept. Therefore I added -D_H_LOCALEDEF in makefile to resolve the conflict.