I am trying to write a simple C++ program on an AIX Box.
The program is given below:
# include <iostream>
# include <fstream>
using namespace std ;
int main()
{
ofstream of ;
of.open("license.txt") ;
of<<"hello"<<endl ;
of.close() ;
}
My LDFLAGS has is set as following:
-maix64 -L/disk3/TOOLS/GCCTools/gcc-4.5.1/lib/ppc64 \
-L/disk3/TOOLS/GCCTools/gcc-4.5.1/lib/gcc/powerpc-ibm-aix6.1.0.0/4.5.1/ppc64 \
-L/disk3/TOOLS/GCCTools/gcc-4.5.1/lib/gcc/powerpc-ibm-aix6.1.0.0/4.5.1 \
-L/disk3/TOOLS/OPENSSL/lib
CFLAGS is:
-O2 -maix64 -I/disk3/TOOLS/OPENSSL/include -D_ALL_SOURCE -D_XOPEN_SOURCE \
-D_XOPEN_SOURCE_EXTENDED -DSS_64BIT_SERVER -D_POSIX_SOURCE -D__64BIT__ \
-I/disk3/TOOLS/OPENSSL/include -I/usr/include \
-I/disk3/TOOLS/GCCTools/gcc-4.5.1/lib/gcc/powerpc-ibm-aix6.1.0.0/4.5.1/include
The program compiles fine. But when I try to run the same, the program comes out with a segmentation fault.
I ran the same with gdb and found the following issue when I use ofstream:
Program received signal SIGSEGV, Segmentation fault.
0x09000000036107c4 in std::locale::operator=(std::locale const&) (this=
findvar.c:706: internal-error: value_from_register: Value not stored anywhere!
Any idea on why this is happening?
Any help is appreciated :)
Note: fstream in itself works...
I meet the same error. The key points to repro the error are:
1 use std::stream(such as std::ofstream) in share libary;
2 use pthread function (such as pthread_self) in share library;
3 use "-O2" to optimize code.
Then it shows "Segmentation fault (core dumped)".
AIX provides 2 versions(64bit) of libstdc++.a. (see http://www.perzl.org/aix/index.php?n=Main.GCCBinariesVersionNeutral)
64-bit compilation, non-thread-safe (<prefix>/ppc64)
64-bit compilation, thread-safe (<prefix>/pthread/ppc64)
My solution is:
change LIBPATH to use "<prefix>/pthread/ppc64" version.
such as set LIBPATH as "/opt/freeware/lib/gcc/powerpc-ibm-aix6.1.0.0/4.6.1/pthread/ppc64/"
It works well in my machine.
It's been a while, but out of my head: don't you need to add -pthread to the compile / link options?
I have analyzed the issue and found a work around.
Here is what i did:
I did an ldd on my testprog executable:
ldd test
test needs:
/usr/lib/threads/libc.a(shr_64.o)
/disk3/TOOLS/GCCTools/gcc-4.5.1/lib/gcc/powerpc-ibm-aix6.1.0.0/4.5.1/pthread/ppc64/libstdc++.a(libstdc++.so.6)
/disk3/TOOLS/GCCTools/gcc-4.5.1/lib/gcc/powerpc-ibm-aix6.1.0.0/4.5.1/pthread/ppc64/libgcc_s.a(shr.o)
/unix
/lib/libcrypt.a(shr_64.o)
/lib/libpthreads.a(shr_xpg5_64.o)
I found that pthread's libstdc was being used. This was due to my LIBPATH having this path before /usr
Next, I reset my LIBPATH to exclude all those paths which had pthread's gcc being used, making sure that the other gcc libraries used where available in LIBPATH
Finally I compiled the test program with this new LIBPATH
Note: LD_LIBRARY_PATH is used by linux and LIBPATH is used by AIX.
Cheers!
Related
I made a C++ tool for off-screen rendering of 3D models. The rendering is done using OSMesa library.
The software was working flawlessly for more than a year, and I stopped to make updates to it something like 6 months ago. In the meanwhile my development environment was updated multiple times.
Now I was compiling it again and found an unexpected bug.
The plain version of the software was still working as expected, but the statically linked one is segfaulting.
I'm assuming that the error is mine in the OSmesa configuration/compilation/linking procedure and not in the library code, but any advice about better debugging of the segmentation fault is appreciated.
Having tried numerous variations of the compilation process without success, I'm now quite stuck.
Anyone can see something stupid I'm doing in some of the steps described below?
I recompiled a static version of the OSmesa library with the same version of the shared library that is working in my system (12.0.6), disabling all the non-needed features (using an Ubuntu based system, no static version of OSmesa lib is available from repositories):
./configure \
--disable-xvmc \
--disable-glx \
--disable-dri \
--with-dri-drivers="" \
--with-gallium-drivers="" \
--disable-shared-glapi \
--disable-egl \
--with-egl-platforms="" \
--enable-osmesa \
--enable-gallium-llvm=no \
--disable-gles1 \
--disable-gles2 \
--enable-static \
--disable-shared
This is the compile command of my off-screen rendering tool:
g++ -std=c++11 -Wall -O3 -g -static -static-libgcc -static-libstdc++ ./src/measure_model.cpp model.o thumbnail.o -o measure_model_debug -pthread -lOSMesa -ldl -lm -lpng -lz -lcrypto
This is a warning that I was getting by statically compiling using OSMesa, and it was present even a year ago with the working static binary:
/home/XXX/XXX/backend/lambda/mesa/mesa-12.0.6/src/mesa/main/dlopen.h:52: warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
This is what I get from running the tool:
Segmentation fault (core dumped)
But no segmentation fault is produced if I simply skip the OSmesa context creation step (and obviously all the 3D rendering)
This is the backtrace:
#0 0x0000000000000000 in ?? ()
#1 0x00000000004af20a in mtx_init (type=4, mtx=0xe10f70) at ../../include/c11/threads_posix.h:215
#2 _mesa_NewHashTable () at main/hash.c:135
#3 0x000000000052f295 in _mesa_alloc_shared_state (ctx=ctx#entry=0xdcc9b0) at main/shared.c:67
#4 0x000000000046e717 in _mesa_initialize_context (ctx=ctx#entry=0xdcc9b0, api=api#entry=API_OPENGL_COMPAT, visual=, share_list=share_list#entry=0x0, driverFunctions=driverFunctions#entry=0x7fffffffcd40) at main/context.c:1192
#5 0x000000000046c870 in OSMesaCreateContextAttribs (attribList=attribList#entry=0x7fffffffd290, sharelist=) at osmesa.c:834
#6 0x000000000046ccdc in OSMesaCreateContextExt (format=, depthBits=, stencilBits=, accumBits=, sharelist=) at osmesa.c:660
#7 0x0000000000468742 in generate_thumbnail(Model*, Json::Value) ()
#8 0x0000000000401c7d in main (argc=, argv=) at ./src/measure_model.cpp:107
A statically linked binary is a strict requirement.
The segmentation fault is happening on the same machine I use to compile the tool (OSmesa static lib is compiled in the same machine too), but no segmentation fault in the non-statically linked version of the same tool.
This is what I get from running the tool:
Segmentation fault (core dumped)
But no segmentation fault is produced if I simply skip the OSmesa context creation step (and obviously all the 3D rendering)
So, there is some problem from OSmesa creation. With your backtrace we can see that top function was executed from EIP of zero (jump to NULL / call of NULL), so there is call of some function in mtx_init, which is part of OS Mesa context creating.
#0 0x0000000000000000 in ?? ()
#1 0x00000000004af20a in mtx_init (type=4, mtx=0xe10f70) at ../../include/c11/threads_posix.h:215
#2 _mesa_NewHashTable () at main/hash.c:135
#3 0x000000000052f295 in _mesa_alloc_shared_state (ctx=ctx#entry=0xdcc9b0) at main/shared.c:67
#4 0x000000000046e717 in _mesa_initialize_context (ctx=ctx#entry=0xdcc9b0, api=api#entry=API_OPENGL_COMPAT, visual=, share_list=share_list#entry=0x0, driverFunctions=driverFunctions#entry=0x7fffffffcd40) at main/context.c:1192
#5 0x000000000046c870 in OSMesaCreateContextAttribs (attribList=attribList#entry=0x7fffffffd290, sharelist=) at osmesa.c:834
#6 0x000000000046ccdc in OSMesaCreateContextExt (format=, depthBits=, stencilBits=, accumBits=, sharelist=) at osmesa.c:660
#7 0x0000000000468742 in generate_thumbnail(Model*, Json::Value) ()
#8 0x0000000000401c7d in main (argc=, argv=) at ./src/measure_model.cpp:107
What was the function? According to online sources of include/c11/threads_posix.h: mtx_init() on github, there are only calls to pthread_mutex_init, pthread_mutexattr_init and several other mutex related functions of libpthread (-lpthread).
Why there was produced call to NULL instead of real function? Probably due to using static linkage of glibc and/or libpthread. Exact problem is still unidentified at this moment (I was able to found report of statically linked libpthread.a into some shared lib which is incorrect and will never work).
In your case there is only alias (strong one) of pthread_mutex_init in glibc/nptl/pthread_mutex_init.c (line 150) strong_alias (__pthread_mutex_init, pthread_mutex_init) and there may be some weak alias of the symbol in the glibc itself, probably uninitialized. Some was wrong in your linking options or/and in ld mind and he did not find/link the nptl/pthread_mutex_init.o (it is part of libpthread.a archive) with real symbol into final executable (ld often skips unused/unneeded objects of .a archives and don't link them into final executable), keeping the relocation pointing into NULL. Some expert of glibc may know, Employed Russian is one of experts on SO.
I suggest to link statically only to your internal libs or probably also to normal non-system libs like mesa (you may use -Wl,-Bstatic -lyour_lib -Wl,-Bdynamic options to temporary change linkage to static for libs listed between; or use cheat option of -l: as -l:libYour_lib.a found by Radek in the same q.). But do not link statically to most basic libs of glibc like libc, libpthread, librt (there are some problems in static linking of glibc when nss is used: target system must have exact same version of dynamic glibc to enable nss to work).
If you want to pack your application for older machines and you needs some features of glibc you may also try to pack your own version of shared glibc libs with your application; put them to some subdirectory, add rpath option of linker to change library search paths, also change INTERP section from default ABI ld-linux.so.2 loader to your own copy of ld-linux.so.2 from your version of glibc, ... And you still will have problems with too old kernels, as newer glibcs requires some modern features (syscalls, structs) of rather new kernel.
Or you can pack your application into some sort of container like Docker, or some other isolation solution (or chroot?) to always have your versions of libs...
UPDATE: Just found report of similar bt with NULL instead of mutex implementation from nptl: https://bugzilla.redhat.com/show_bug.cgi?id=163083 "Statically linked C++ program using pthreads will segfault" (2005-2007) pthread_mutex_init(&lock, NULL); g++ -g -static foo.cpp -o foo -lpthread where #0 0x00000000 in ?? () #1 0x08048232 in main () at foo.cpp:7
This is apparently due to certain pthreads functions not being included in the output executable. This bug may duplicate #115157, and I apologize if so, but hopefully the included test case will be useful.
Additional info:
The suggestion in #115157 to forcibly link in all of libpthread.a is a valid workaround.
https://bugzilla.redhat.com/show_bug.cgi?id=115157 "executables linked statically with /usr/lib/nptl/libpthread.a fail" - 2004-2009 CLOSED WONTFIX
Jakub Jelinek 2004-10-29 05:26:10 EDT
First of all, avoid -static if you can, it only creates problems,
both portability wise and others as well.
If you really need to create statically linked binary with -lpthread
linked in, then just use -Wl,--whole-archive -lpthread -Wl,--no-whole-archive
instead of -pthread. Anything else has really many problems.
I've built ICU 57.1 statically with MinGW x32;
As a result, I got the following files in the lib directory:
libsicudt.a
libsicuin.a
libsicuio.a
libsicule.a
libsiculx.a
libsicutest.a
libsicutu.a
libsicuuc.a
sicudt.a
sicudt.dll
Now I want to run one of the examples, but whatever I try it
I receive errors like
"undefined reference to unum_...
unum_setAttribute
unum_formatInt64
u_isspace".
Total number of errors at the beginning was about 1700.
Analyzing pkgconfig files I figured out some mutual dependencies and
after reordering .a files in cmd line reduced errors to 82.
But I have no idea where to go next.
Google shows that many people have same problem with ICU but
so far there is no solution that works for me and explains the cause.
When building, I use Qt Creator for convenience, here is my .pro file:
TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += main.cpp
ICUDIR=$$(ICU_PATH)
ICU_LIBPATH=$$ICUDIR"/dist/lib/"
INCLUDEPATH += $$ICUDIR"/dist/include"
LIBS += $$ICU_LIBPATH"libsicuuc.a" $$ICU_LIBPATH"libsicudt.a" \
$$ICU_LIBPATH"libsicuin.a" $$ICU_LIBPATH"libsicuio.a" \
$$ICU_LIBPATH"libsicule.a" $$ICU_LIBPATH"libsiculx.a" \
$$ICU_LIBPATH"libsicutu.a" $$ICU_LIBPATH"sicudt.a"
I have following questions:
1) Can anybody write a simple one line command that statically builds
the simpliest ICU app using g++? Is it even possible?
2) What is the correct order of .a files when passing them to linker?
3) What are files libsicudt.a, sicudt.a and sicudt.dll inteded for?
4) Is the file list I wrote above complete or my build is corrupt?
5) Is there anything I've missed of doing wrong?
Finally, I solved the problem. In order to share my experiece with you
I will describe four major pitfalls that I've encountered.
I assume that you use msys2 and MinGW-w32 if you want to repeat the steps.
Use same toolchain for everything. Note that MinGW, MinGW-w32 and MinGW-w64
are 3 different toolchains. If you have multiple installations of MinGW
like me, make sure that you use only one of them for the entire project.
I chose MinGW-w32 for compatibility reasons.
The newest versions of software often contain bugs, and they
require from you some more dancing with tambourins.
ICU v58 was buggy at the moment of writing this post.
The solution is to revert to an older version (57.1 in my case).
Before building ICU library, make sure to setup everything correctly.
Here problem is with using namespaces and renaming namespaces which
ICU does by default.
Find file C:\icu\source\common\unicode\uconfig.h and add the following
at the beginning after include guards:
#define U_DISABLE_RENAMING 1
#define U_USING_ICU_NAMESPACE 0
Save the file. Open MSYS2 terminal and set mingw-w32 as working toolset:
export PATH="/c/msys64/mingw32/bin:$PATH"
Go to icu/source dir:
cd /c/icu/source
Configure ICU for static build with no renaming and U_USING_ICU_NAMESPACE=0:
export CFLAGS="-DU_CHARSET_IS_UTF8=1 -DU_GNUC_UTF16_STRING=1 -DU_STATIC_IMPLEMENTATION"
export CXXFLAGS="-DU_USING_ICU_NAMESPACE=0 -std=gnu++11 -DU_CHARSET_IS_UTF8=1 -DU_GNUC_UTF16_STRING=1 -DU_HAVE_CHAR16_T=1 -DUCHAR_TYPE=char16_t -Wall --std=c++11 -DU_STATIC_IMPLEMENTATION" -static-libstdc++ -fno-exceptions
export CPPFLAGS="-DU_DISABLE_RENAMING=1 -DU_CHARSET_IS_UTF8=1 -DU_STATIC_IMPLEMENTATION"
export LDFLAGS="-std=gnu++11"
./runConfigureICU MinGW prefix=$PWD/../dist -enable-static -disable-shared --disable-renaming
Build and install ICU lib. -j4 speeds up the process if you have 4 cores:
mingw32-make -j4
mingw32-make install
Cleanup intermediate files:
mingw32-make clean
Now you should have static libraries located at icu/dist/lib .
PITFALL 4: when linking statically, you should pass libraries to
linker in correct order. That matters only for static linking.
But how to figure out which order is correct?
Here pkg-config tool comes handy.
What it does is the following: takes library package names as
parameter, calculates dependencies and returns the complete string
of parameters that can be fed directly to the compiler
or viewed by you to understand what's going on under the hood.
There are 5 packages located at C:\icu\dist\lib\pkgconfig.
Let's configure path for pkg-config:
export PKG_CONFIG_PATH="/c/icu/dist/lib/pkgconfig:$PKG_CONFIG_PATH"
In order to test it, type:
pkg-config --static --cflags --libs icu-uc icu-i18n icu-io icu-le icu-lx
The output should be:
-IC:/icu/dist/include -LC:/icu/dist/lib -lsicuio -lsicuin -lsiculx -lsicule -lsicuuc -lsicudt -lpthread -lm
That's the string we have to pass to compiler.
As final test, we will compile a simple example app using command line:
Create folder /c/icu/dist/test with file test.cpp inside:
#include <unicode/unistr.h>
#include <unicode/ustdio.h>
#include <unicode/brkiter.h>
#include <stdlib.h>
using namespace icu;
void printUnicodeString(UFILE *out, const UnicodeString &s) {
UnicodeString other = s;
u_fprintf(out, "\"%S\"", other.getTerminatedBuffer());
}
int main( void )
{
UFILE *out;
UErrorCode status = U_ZERO_ERROR;
out = u_finit(stdout, NULL, NULL);
if(!out) {
fprintf(stderr, "Could not initialize (finit()) over stdout! \n");
return 1;
}
ucnv_setFromUCallBack(u_fgetConverter(out), UCNV_FROM_U_CALLBACK_ESCAPE,
NULL, NULL, NULL, &status);
if(U_FAILURE(status)) {
u_fprintf(out, "Warning- couldn't set the substitute callback - err %s\n", u_errorName(status));
}
/* End Demo boilerplate */
u_fprintf(out,"ICU Case Mapping Sample Program\n\n");
u_fprintf(out, "C++ Case Mapping\n\n");
UnicodeString string("This is a test");
u_fprintf(out, "\nstring: ");
printUnicodeString(out, string);
string.toUpper(); /* string = "THIS IS A TEST" */
u_fprintf(out, "\ntoUpper(): ");
printUnicodeString(out, string);
return 0;
}
Go to the test dir:
cd /c/icu/dist/test
g++ -o test test.cpp \
`pkg-config --cflags --libs --static icu-uc icu-i18n icu-io icu-le icu-lx`
Run the app:
./test
Maybe this is not the best way to do,
especially concerning workspaces, but it works.
More about pgk-config here:
https://people.freedesktop.org/~dbn/pkg-config-guide.html
I am using a bash shell on my Mac OS X. I have fortran95 compiler installed in /sw/bin/gfortran. every time I attempt to access the compiler, I receive
the error:
"Segmentation fault: 11". I cannot call any programs the regular way
i.e. "gfortran program.f90 -o executable_name "
I am not sure about the problem. Even simple programs which print "hello world" to screen will not work.
May be a problem with your installation as already mentioned. A couple things I would try:
Make sure the shared libraries it is compiled against are being found:
otool -L /sw/bin/gfortran
Compile with some switches that might give you more helpful info. I found using the backtrace option really helps especially to debug seg. faults. You might try to compile with some options such as:
gfortran -g -fbounds-check -Wall -fbacktrace program.f90
I am attempting to install libzdb on my macbook however I see the following error message when running the configure:
configure:13334: error: setjmp is required
the setjmp.h file resides within /usr/include and is specified within my "$PATH" as
/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:/usr/include
Can someone please advise as to how i can rectify this issue?
thanks in advance
I've stumbled across this error while building one of my own programs when I wanted to use setjmp() and longjmp(). For some reason, the toolchain that resides in / on OS X is flawed, and the <setjmp.h> header file is missing the declarations and data types.
To fix it, I had to download Xcode (damn!) and tell the compiler to look for the headers in the freshly installed MacOSX10.7.sdk (or 8) folder:
clang -Wall -o foo foo.c -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk
ok finally figured it out. For those who have seen messages like this be warned that the configure logs can be misleading. It turned out the binary built fine, however it was failing during runtime because a few mysql libraries could not be found. using the following command *export DYLD_LIBRARY_PATH=/usr/local/mysql/lib/* would fix the problem
I'm using gcc on GNU/Linux and the debug-files and headers of libc and libstd++ are installed. But I don't know how to tell gdb to use the source-code of them, especially to debug into libstd++.
The source-code of libstdc++ itself seems to be provided in a complicated structure. I think the directory command is the right choice. I'm using here Debian/Ubuntu and downloaded the source with apt-get source libstdc++6 into my home-directory.
I'm pretty sure I didn't need take special steps for this with Fedora (some years ago). Maybe Fedora was prepared in a special way for this. So I will be glad about general instructions, which fit for every distribution.
Thank you
Update
I figured out, that I need to compile with -D_GLIBCXX_DEBUG in addition to -g, so compile command looks like $ g++ -o test test.cpp -g -D_GLIBCXX_DEBUG.
Furthermore I got warning about missing pretty printers, which I solved as described here:
http://gcc.gnu.org/onlinedocs/libstdc++/manual/debug.html#debug.gdb
Now I can debug into libstdc++, but I always got this message:
Breakpoint 1, main () at test.cpp:9
9 string str = "str";
(gdb) s
std::allocator<char>::allocator (this=0x7fffffffe1e0)
at /build/buildd/gcc-4.7-4.7.2/build/x86_64-linux-gnu/libstdc++-v3/include/bits/allocator.h:104
104 /build/buildd/gcc-4.7-4.7.2/build/x86_64-linux-gnu/libstdc++-v3/include/bits/allocator.h: No such file or directory.
(gdb) s
std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string (
this=0x7fffffffe1c0, __s=0x402930 "str", __a=...)
at /usr/include/c++/4.7/bits/basic_string.tcc:217
217 __s + npos, __a), __a)
I don't need to set the directory in gdb to the my downloaded source (I' think it search through my home-directory). So I thought I need a different command to fix this and found "set substitute-path" and pointed it to /home/username/gcc-4.7-4.7.2/gcc-4.7.2/libstdc++-v3 but I doesn't work. Why does gdb look for allocator.h in the completely wrong place?
First find out the sources from :-
https://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/index.html
Later compile libstdc++ with DEBUG_FLAGS set it ON.
Then, try it out to debug with gdb.