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