g++ and IBM AIX: another exception handling bug?

Florian Dörsch webmaster@ma.ra-doersch.de
Mon Jun 3 09:00:00 GMT 2019


Hi,

I hope this is the correct mailing list for my question:
currently we’re using a very old gcc 4.6.3 on an IBM AIX 7.2.
I recently discovered problems with exceptions (they do not work as they 
should) if you use them in static initializers, like:

--- test.cpp ---
#include <iostream>

bool MainFunc()
{
     static int nr = 0;

     std::cerr << "MainFunc" << std::endl;
     try
     {
         throw nr++;
     }
     catch(const int i)
     {
         std::cerr << "MainFunc caught exception: " << i << std::endl;
     }
     catch(...)
     {
         std::cerr << "MainFunc caught unknown exception" << std::endl;
     }
     std::cerr << "MainFunc end" << std::endl;

     return true;
}

static const bool _mainfunc = MainFunc();

int main(void) { return 0; }
---

TEST1: (fail)
# gcc -maix64 -pthread test.cpp -o test
# ./test

This will result in "IOT/Abort trap". The exception was not catched at all.

Well, I did some research on that topic, and found some changes were 
made for gcc in the last years.

So I built a 9.1.0 gcc (yep building  worked flawlessly)

# gcc-9.1.0/configure --prefix=... --with-local-prefix=... 
--with-as=/usr/bin/as --with-ld=/usr/bin/ld --enable-languages=c,c++ 
--enable-version-specific-runtime-libs --disable-nls 
--enable-decimal-float=dpd --with-cloog=no --with-ppl=no 
--disable-libstdcxx-pch --enable-__cxa_atexit

Now after a rebuild with gcc-9.1.0:

TEST2: (ok)
# gcc-9.1.0 -maix64 -pthread test.cpp -o test # ./test
 > MainFunc
 > MainFunc caught exception: 0
 > MainFunc end

Wow I thought, problem was fixed. So I've added an additional module

--- module1.cpp ---
#include <iostream>

bool Mod1Func()
{
     static int nr = 0;

     std::cerr << " Mod1Func " << std::endl;
     try
     {
         throw nr++;
     }
     catch(const int i)
     {
         std::cerr << " Mod1Func caught exception: " << i << std::endl;
     }
     catch(...)
     {
         std::cerr << " Mod1Func caught unknown exception" << std::endl;
     }
     std::cerr << " Mod1Func end" << std::endl;

     return true;
}

static const bool _mod1func = Mod1Func ();
---

TEST3: (fail)
# gcc -maix64 -pthread test.cpp module1.cpp -o test # ./test

I expected that this will work too but:

 > Mod1Func
 > terminate called after throwing an instance of 'int'
 > IOT /Abort trap

If I turn the files around:

TEST4: (fail)
# gcc -maix64 -pthread module1.cpp test.cpp -o test # ./test
 > MainFunc
 > MainFunc caught exception: 0
 > MainFunc end
 > Mod1Func
 > terminate called after throwing an instance of 'int'
 > IOT /Abort trap

It seems it only handles exceptions in the first initializer correctly?

TEST5: (ok???)
I also tried putting module1.cpp into a shared library (built with 
-shared) and what a miracle:
It worked! (all 2 initializers run+catch correctly)

TEST6: (ok???)
I also added a 3rd initializer (copied module1.cpp to module2.cpp and 
renamed all occurences of 1 to 2) to  the library:
I expected that this will crash on the second initializer inside the 
library, but:
It worked too! (all 3 initializers run+catch correctly)

TEST7: (ok)
Now I put module1.cpp and module2.cpp in two different libraries and 
tried that:
It worked. (all 3 initializers run+catch correctly)

Conclusion:
If I link two or more static initialized exception handling code 
directly to my application, it will fail horribly.


What's going wrong there? Is there any way to fix it?


Thank you very much

Regards
Florian



More information about the Gcc-help mailing list