gcc (g++) vs qcc: exception handling problem

Hi All

There are a few threads about exceptions issues in qnx but no general answer.
I believe many people already saw the problem and solved it. Could you kindly point to the discussion or provide your comments please.

I know qnx is advising using qcc instead of gcc, but I need this to port gnu application to qnx environment.

The problem is that binary compiled with qcc is workign fine, and the same code compiled with gcc directly is aborting. The logs are below.

PS platform: qnx 6.3.0 sp3 (tried both gcc 3.3.5 and gcc 2.95.3 - same issue)

working with qcc:

bash-2.05a# qcc -v hello.cpp
cc: looking for gcc_ntox86 in /usr/qnx630/host/qnx6/x86/etc/qcc/gcc/2.95.3/gcc_ntox86++.conf
cc: looking for gcc_ntox86 in /usr/qnx630/host/qnx6/x86/etc/qcc/gcc/2.95.3/gcc_ntox86.conf
/usr/qnx630/host/qnx6/x86/usr/lib/gcc-lib/ntox86/2.95.3/cpp0 -nostdinc -nostdinc++ -D__cplusplus -D__QNX__ -D__QNXNTO__ -D__GNUC__=2 -D__GNUC
MINOR_=95 -D__GNUG__=2 -D__unix__ -D__unix -D__ELF__ -D__X86__ -D__i386__ -D__LITTLEENDIAN__ -Acpu(386) -Acpu(i386) -Amachine(i386) -Asyste
m(unix) -Asystem(nto) -Asystem(qnx) -Asystem(qnxnto) -idirafter /usr/qnx630/target/qnx6/usr/include -isystem /usr/qnx630/target/qnx6/usr/incl
ude/cpp/c -isystem /usr/qnx630/target/qnx6/usr/include/cpp -lang-c++ hello.cpp -o - |
/usr/qnx630/host/qnx6/x86/usr/lib/gcc-lib/ntox86/2.95.3/cc1plus -quiet -fno-builtin -fhonor-std -fcheck-new -dumpbase hello.cpp -o - |
/usr/qnx630/host/qnx6/x86/usr/bin/ntox86-as -o hello.o
/usr/qnx630/host/qnx6/x86/usr/bin/ntox86-ld -b elf32-i386 -m i386nto --dynamic-linker /usr/lib/ldqnx.so.2 -rpath-link /usr/qnx630/target/qnx6
/x86/lib:/usr/qnx630/target/qnx6/x86/usr/lib:/usr/qnx630/target/qnx6/x86/lib/gcc/2.95.3:/usr/qnx630/target/qnx6/x86/opt/lib /usr/qnx630/targe
t/qnx6/x86/lib/crt1.o /usr/qnx630/target/qnx6/x86/lib/crti.o /usr/qnx630/host/qnx6/x86/usr/lib/gcc-lib/ntox86/2.95.3/crtbeginC++.o hello.o -o
a.out -Y/usr/qnx630/target/qnx6/x86/lib:/usr/qnx630/target/qnx6/x86/usr/lib:/usr/qnx630/target/qnx6/x86/opt/lib -L/usr/qnx630/host/qnx6/x86/
usr/lib/gcc-lib/ntox86/2.95.3/exceptions -L/usr/qnx630/target/qnx6/x86/lib/gcc/2.95.3 -L/usr/qnx630/target/qnx6/usr/ntox86/lib/exceptions -L/
usr/qnx630/target/qnx6/x86/lib/exceptions -L/usr/qnx630/target/qnx6/x86/lib -L/usr/qnx630/target/qnx6/x86/usr/lib -L/usr/qnx630/target/qnx6/x
86/opt/lib -lcpp /usr/qnx630/host/qnx6/x86/usr/lib/gcc-lib/ntox86/2.95.3/exceptions/libgcc.a -lc -dn -Bstatic -lc /usr/qnx630/host/qnx6/x86/u
sr/lib/gcc-lib/ntox86/2.95.3/exceptions/libgcc.a /usr/qnx630/host/qnx6/x86/usr/lib/gcc-lib/ntox86/2.95.3/crtendC++.o /usr/qnx630/target/qnx6/
x86/lib/crtn.o
cc: unlinking hello.o
bash-2.05a#

bash-2.05a# ./a.out
starting …
throwing
inside catch
bash-2.05a#

No problem at all …

=======================================

now with gcc …

bash-2.05a# g++ -v hello.cpp
Reading specs from /usr/qnx630/host/qnx6/x86/usr/lib/gcc-lib/ntox86/2.95.3/specs
gcc version 2.95.3
/usr/qnx630/host/qnx6/x86/usr/lib/gcc-lib/ntox86/2.95.3/cpp0 -lang-c++ -v -D__GNUC__=2 -D__GNUG__=2 -D__GNUC_MINOR__=95 -D__cplusplus -D__X8
6__ -Di386 -Dunix -D__QNXNTO__ -D__QNX__ -D__ELF__ -D__LITTLEENDIAN__ -D__X86__ -D__i386__ -D__unix__ -D__QNXNTO__ -D__QNX__ -D__ELF__ -D__LI
TTLEENDIAN__ -D__i386 -D__unix -Asystem(unix) -Asystem(nto) -Asystem(qnxnto) -Asystem(qnx) -Acpu(i386) -Amachine(i386) -D__EXCEPTIONS -idiraf
ter /usr/qnx630/target/qnx6/usr/include -idirafter /usr/qnx630/target/qnx6/usr/include/g+±3 -idirafter /usr/qnx630/target/qnx6/usr/ntox86/in
clude -idirafter /usr/qnx630/host/qnx6/x86/usr/lib/gcc-lib/ntox86/2.95.3/include -Acpu(i386) -Amachine(i386) -Di386 -D__i386 -D__i386__ -D_PT
HREADS=1 hello.cpp /tmp/ccYbOi0g.ii
GNU CPP version 2.95.3 (QNX/Neutrino)
#include “…” search starts here:
#include <…> search starts here:
//usr/lib/gcc-lib/ntox86/2.95.3/…/…/…/…/include/g+±3
/usr/qnx630/target/qnx6/usr/include
/usr/qnx630/target/qnx6/usr/include/g+±3
/usr/qnx630/host/qnx6/x86/usr/lib/gcc-lib/ntox86/2.95.3/include
End of search list.
The following default directories have been omitted from the search path:
//usr/lib/gcc-lib/ntox86/2.95.3/include
//usr/lib/gcc-lib/ntox86/2.95.3/…/…/…/…/ntox86/sys-include
//usr/lib/gcc-lib/ntox86/2.95.3/…/…/…/…/ntox86/include
End of omitted list.
/usr/qnx630/host/qnx6/x86/usr/lib/gcc-lib/ntox86/2.95.3/cc1plus /tmp/ccYbOi0g.ii -quiet -dumpbase hello.cc -version -o /tmp/ccItPU3o.s
GNU C++ version 2.95.3 (ntox86) compiled by GNU C version 2.95.3qnx-nto 20010315 (release).
/usr/qnx630/host/qnx6/x86/usr/bin/ntox86-as -V -Qy -o /tmp/ccotKRhB.o /tmp/ccItPU3o.s
GNU assembler version 2.12.1qnx-nto (i386-pc-nto-qnx6.3.0) using BFD version 2.12.1qnx-nto
/usr/qnx630/host/qnx6/x86/usr/lib/gcc-lib/ntox86/2.95.3/collect2 -V -Y P,/usr/qnx630/target/qnx6/x86/lib -Qy -m i386nto --dynamic-linker /us
r/lib/ldqnx.so.2 /usr/qnx630/target/qnx6/x86/lib/crt1.o /usr/qnx630/target/qnx6/x86/lib/crti.o /usr/qnx630/target/qnx6/x86/lib/crtbegin.o -L/
usr/qnx630/host/qnx6/x86/usr/lib/gcc-lib/ntox86/2.95.3 /tmp/ccotKRhB.o -lstdc++ -lm -lgcc -L /usr/qnx630/target/qnx6/x86/lib/gcc/2.95.3 -L /u
sr/qnx630/target/qnx6/x86/lib -L /usr/qnx630/target/qnx6/x86/usr/lib -L /usr/qnx630/target/qnx6/x86/opt/lib -rpath-link /usr/qnx630/target/qn
x6/x86/lib/gcc/2.95.3:/usr/qnx630/target/qnx6/x86/lib:/usr/qnx630/target/qnx6/x86/usr/lib:/usr/qnx630/target/qnx6/x86/opt/lib -lc -dn -Bstati
c -lc -lgcc /usr/qnx630/target/qnx6/x86/lib/crtend.o /usr/qnx630/target/qnx6/x86/lib/crtn.o
GNU ld version 2.12.1qnx-nto
Supported emulations:
i386nto
bash-2.05a#

bash-2.05a# ./a.out
starting …
throwing
abort (core dumped)

bash-2.05a# gdb a.out /root/a.out.core
GNU gdb 5.2.1qnx-nto
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB. Type “show warranty” for details.
This GDB was configured as “ntox86”…(no debugging symbols found)…
Program terminated with signal 6, Aborted.
Reading symbols from /usr/qnx630/target/qnx6/x86/lib/libstdc++.so.2.2.10.0…done.
Loaded symbols for /usr/qnx630/target/qnx6/x86/lib/libstdc++.so.2.2.10.0
Reading symbols from /usr/qnx630/target/qnx6/x86/lib/libm.so.2…done.
Loaded symbols for /usr/qnx630/target/qnx6/x86/lib/libm.so.2
Reading symbols from /usr/qnx630/target/qnx6/x86/lib/libc.so.2…done.

Loaded symbols for /usr/qnx630/target/qnx6/x86/lib/libc.so.2
#0 0xb032e7f5 in SignalKill () from /usr/qnx630/target/qnx6/x86/lib/libc.so.2
(gdb) bt
#0 0xb032e7f5 in SignalKill () from /usr/qnx630/target/qnx6/x86/lib/libc.so.2
#1 0xb03217c8 in raise () from /usr/qnx630/target/qnx6/x86/lib/libc.so.2
#2 0xb03204f1 in abort () from /usr/qnx630/target/qnx6/x86/lib/libc.so.2
#3 0xb822b09c in __terminate () at …/…/gcc/libgcc2.c:-1
#4 0xb822b0b9 in __terminate () from /usr/qnx630/target/qnx6/x86/lib/libstdc++.so.2.2.10.0
#5 0xb822ba94 in throw_helper (eh=0x804a198, pc=0x8048786, my_udata=0x8047b64, offset_p=0x8047b60)
from /usr/qnx630/target/qnx6/x86/lib/libstdc++.so.2.2.10.0
#6 0xb822bc4d in __throw () from /usr/qnx630/target/qnx6/x86/lib/libstdc++.so.2.2.10.0
#7 0x08048787 in main ()
(gdb)

the code …

bash-2.05a# cat hello.cpp
#include
#include

int main(int argc, char *argv[]) {
std::cout << “starting …” << std::endl;
try {
std::cout << “throwing” << std::endl;
throw 123;
return EXIT_SUCCESS;
}

    catch (int a)
    {
            std::cout << "inside catch " << std::endl;
    }
    return EXIT_SUCCESS;

}
bash-2.05a#

Ev,

First, if your porting this to QNX, why can’t you just use qcc? It’s a simple matter of replacing gcc in the make file with qcc and you’ll be ready to go. Otherwise this kind of subtle issue may creep in.

The problem is not at compile time, but rather at link time. Your not linking in the exception library in the gcc compile. Take a look at the qcc output and you’ll see the following at link time:

/usr/qnx630/host/qnx6/x86/usr/bin/ntox86-ld -b elf32-i386 -m i386nto --dynamic-linker /usr/lib/ldqnx.so.2 -rpath-link /usr/qnx630/target/qnx6
/x86/lib:/usr/qnx630/target/qnx6/x86/usr/lib:/usr/qnx630/target/qnx6/x86/lib/gcc/2.95.3:/usr/qnx630/target/qnx6/x86/opt/lib /usr/qnx630/targe
t/qnx6/x86/lib/crt1.o /usr/qnx630/target/qnx6/x86/lib/crti.o /usr/qnx630/host/qnx6/x86/usr/lib/gcc-lib/ntox86/2.95.3/crtbeginC++.o hello.o -o
a.out -Y/usr/qnx630/target/qnx6/x86/lib:/usr/qnx630/target/qnx6/x86/usr/lib:/usr/qnx630/target/qnx6/x86/opt/lib -L/usr/qnx630/host/qnx6/x86/
usr/lib/gcc-lib/ntox86/2.95.3/exceptions -L/usr/qnx630/target/qnx6/x86/lib/gcc/2.95.3 -L/usr/qnx630/target/qnx6/usr/ntox86/lib/exceptions -L/
usr/qnx630/target/qnx6/x86/lib/exceptions -L/usr/qnx630/target/qnx6/x86/lib -L/usr/qnx630/target/qnx6/x86/usr/lib -L/usr/qnx630/target/qnx6/x
86/opt/lib -lcpp /usr/qnx630/host/qnx6/x86/usr/lib/gcc-lib/ntox86/2.95.3/exceptions/libgcc.a -lc -dn -Bstatic -lc /usr/qnx630/host/qnx6/x86/u
sr/lib/gcc-lib/ntox86/2.95.3/exceptions/libgcc.a /usr/qnx630/host/qnx6/x86/usr/lib/gcc-lib/ntox86/2.95.3/crtendC++.o /usr/qnx630/target/qnx6/
x86/lib/crtn.o

Now look at the gcc link lines. You’ll notice there is no reference to the exception library. That’s why the exceptions aren’t being handled correctly.

Tim

Tim,
thanks for the suggestion.

I am looking at using QCC/qcc from the very begining. I have learned qcc prepares environment and works flexibly for many target cpus. This is good. But it does not recognise many options “configure” script gives to it while preparing makefiles.

Regarding exceptions, I was advised that in my example g++ and QCC are linking final binary against different c++ libararies …

Ev

Ev,

Very true. If you plan to regularly need to run the configure scripts it will be necessary to modify them to give the appropriate options to qcc.

Generally though, you should only need to run them once to set up the environment for your needs and then you can manually figure out which options you need for qcc at which time you never need those scripts again. At least in theory ;)

This is also very likely the case although both libraries have exception support (you are not linking it in). g++ uses the GNU C++ lib which is no longer recommended (it’s older and more out of date on QNX). The Dinkum libraries are the recommended ones now (unless you splurged the big bucks on the Intel compiler). You can see all the library options by doing a ‘qcc -V’.

We use the 3.3.5 compiler (the 2.95.3 is the default and what your getting with g++) and the Dinkum exceptions library. So my CC/LD lines look like:

CC = qcc -V3.3.5, gcc_ntox86
LD = qcc -V3.3.5, gcc_ntox86
CXX = CC

and my CFLAGS/LIBFLAGS look like:

ifeq ($(WITHOUT_DEBUG_SYMBOLS), 1)
CFLAGS = -lang-c++ -O -D_PTHREADS=1 -w9 -Wall -Werror -Wno-deprecated -Wp,-MD
else
CFLAGS = -lang-c++ -D_PTHREADS=1 -g -w9 -Wall -Werror -Wno-deprecated -Wp,-MD
endif
CXXFLAGS = $(CFLAGS)

LIBFLAGS = -Vgcc_ntox86 -A

ifeq ($(WITHOUT_DEBUG_SYMBOLS), 1)
LDFLAGS = -lang-c++ -O -M -D_PTHREADS=1 -l m
else
LDFLAGS = -lang-c++ -g -M -D_PTHREADS=1 -l m
endif

Hope this helps you some.

Tim

Thanks Tim,
I’ve got your point, but will try to avoid changing makefiles, as the base project will be changing in the near future.

The exception isssue for gcc 3.3.5 is solved by adding -fexceptions option to “g++”.

Ev