I am working in an IBM i 7.3 environment from IBM's CECC service. I'm attempting to test a large application in the PASE environment, but I've had trouble with scripts that use the <fstream>
library. Opening a file in write mode causes scripts to terminate with SIGILL
.
To test this problem, I wrote the following script:
#include <iostream>
#include <fstream>
int main()
{
std::ofstream writer;
std::cout << "Writing file.\n" << std::endl;
writer.open( "out.txt" );
if ( !writer.is_open() || !writer.good() )
{
std::cerr << "Unable to open file." << std::endl;
return (1);
}
writer << "This is a test.\n" << std::endl;
writer.close();
return (0);
}
Executing the script results in:
Writing file.
Illegal instruction (core dumped)
In GDB:
(gdb) run
Starting program: /storage/persist/[app-directory]/test/log/test_write
[New Thread 1]
Writing file.
Program received signal SIGILL, Illegal instruction.
[Switching to Thread 1]
0x08001000a0027940 in _localeinit.bss_3_ () from /QOpenSys/pkgs/bin/../lib/gcc/powerpc-ibm-aix6.1.0.0/6.3.0/../../../libstdc++.so.6(shr_64.o)
(gdb) bt
#0 0x08001000a0027940 in _localeinit.bss_3_ () from /QOpenSys/pkgs/bin/../lib/gcc/powerpc-ibm-aix6.1.0.0/6.3.0/../../../libstdc++.so.6(shr_64.o)
I ran a quick sanity check on the code by compiling and running it on a CentOS7 dev system, where it runs as expected and returns without errors. I've also copied the code to my home folder, where it creates and writes out.txt
as expected, but still fails with SIGILL
rather than returning with no error code. (Running in the application's directory also creates out.txt correctly, but had been failing when out.txt
had already been created with permissions -rwx------
).
Details
g++ --version
g++-6.bin (GCC) 6.3.0
Copyright (C) 2016 Free Software Foundation, Inc.
g++ -dumpmachine
powerpc-ibm-aix6.1.0.0
The C++ std library was installed with the following package:
libstdcplusplus-devel.ppc64 6.3.0-29 @ibm
The code was compiled with the following command:
g++ -std=c++17 -Wall -g3 -O0 -fpie test_write.cpp -o test_write -lpthread
Other programs that do not use <fstream>
compile and run without errors. I've had trouble finding documentation explaining potential causes for this issue, due to the esoteric nature of the PASE for i platform, but I'm expecting it has something to do with the compiler settings. I'd like to figure out what the cause is so that I can make the appropriate changes to my code and/or makefiles to resolve it.
When using GCC to compile for PASE you must use -pthread
instead of -lpthread
(or also set -D_THREAD_SAFE
). Without this you can run in to problems as AIX header files shipped by PASE have compile-time threading behavior. In addition, the libstdc++ has a different ABI depending on whether you compile with -pthread
or without on AIX platforms. On AIX, GCC will automatically set the binary's runtime library path appropriately to load the pthread or non-pthread GCC libraries while in the open source environment on PASE, we only ship the pthread version.