Hi, I try to write a testcase that shows the unsafe optimization of catch clauses in shared library, in GCC 4.1.1. I try the following example, but GCC/g++ 4.1.1 does not optimize it (which is unsafe, as I read) : $ cat regular.cpp void f() {} $ cat regular.hpp void f(); $ cat hijack.cpp #include <iostream> void f() { std::cout << "hijack call\n"; throw "blah"; } $ cat main.cpp #include "regular.hpp" #include <iostream> void g() { try { f(); } catch( ... ) { std::cerr << "exception caught\n"; } std::cout << "end\n"; } int main() { g(); } I compile that with the following jamfile : 8<--------------------------------------------------------- lib libregular : regular.cpp ; lib libhijack : hijack.cpp ; exe myexe : main.cpp .//libregular : ; install dist : myexe libregular libhijack : <location>dist ; 8<--------------------------------------------------------- invoked as release variant, it produces the following commands : "ccache" "g++" -Wall -ftemplate-depth-100 -O3 -finline-functions -Wno-inline -fPIC -DNDEBUG -c -o "bin/gcc-4.1.1/release/regular.o" "regular.cpp" "ccache" "g++" -o "bin/gcc-4.1.1/release/libregular.so" -Wl,-h -Wl,libregular.so -shared "bin/gcc-4.1.1/release/regular.o" -Wl,--strip-all "ccache" "g++" -Wall -ftemplate-depth-100 -O3 -finline-functions -Wno-inline -fPIC -DNDEBUG -c -o "bin/gcc-4.1.1/release/hijack.o" "hijack.cpp" "ccache" "g++" -o "bin/gcc-4.1.1/release/libhijack.so" -Wl,-h -Wl,libhijack.so -shared "bin/gcc-4.1.1/release/hijack.o" -Wl,--strip-all "ccache" "g++" -Wall -ftemplate-depth-100 -O3 -finline-functions -Wno-inline -fPIC -DNDEBUG -c -o "bin/gcc-4.1.1/release/main.o" "main.cpp" "ccache" "g++" -Wl,-R -Wl,"/home/fabien/prog/C++/Preload/GCC-Diff-4.1.1-4.1.2/bin/gcc-4.1.1/release" -Wl,-rpath-link -Wl,"/home/fabien/prog/C++/Preload/GCC-Diff-4.1.1-4.1.2/bin/gcc-4.1.1/release" -o "bin/gcc-4.1.1/release/myexe" "bin/gcc-4.1.1/release/main.o" "bin/gcc-4.1.1/release/libregular.so" -Wl,--strip-all "ccache" "g++" -Wl,-rpath-link -Wl,"/home/fabien/prog/C++/Preload/GCC-Diff-4.1.1-4.1.2/bin/gcc-4.1.1/release" -o "dist/myexe" "bin/gcc-4.1.1/release/main.o" "bin/gcc-4.1.1/release/libregular.so" -Wl,--strip-all cp "bin/gcc-4.1.1/release/libregular.so" "dist/libregular.so" cp "bin/gcc-4.1.1/release/libhijack.so" "dist/libhijack.so" I've exported LD_LIBRARY_PATH=., then I launch the program using LD_PRELOAD : $ LD_PRELOAD=./libhijack.so ./myexe, and the exception raised by f() in hijack.cpp is caught by the catch clause in g(). What am I missing ? What (unsafe) optimization affect the catch clause suppression ? (I am on an i686-pc-linux-gnu.) ------------------------------------------------------------- Other question, when trying to reproduce the unsafe optimization, I move the function g() in regular.cpp, and call it from the main. To be clear, I write the following code : $ cat regular.cpp #include <iostream> void f() {} void g() { try { f(); } catch( ... ) { std::cerr << "exception caught\n"; } std::cout << "end\n"; } $ cat regular.hpp void f(); void g(); $ cat hijack.cpp #include <iostream> void f() { std::cout << "hijack call\n";release throw "blah"; } $ cat main.cpp #include "regular.hpp" int main() { g(); } When I compiled it with optimization -- the previous commands -- the hijack f() is not called. When I compile whithout optimization, hijack f() is called, but the catch clause in g() doesn't catch the exception thrown and it produces on stdout : $ LD_PRELOAD=./libhijack.so ./myexe hijack call terminate called after throwing an instance of 'char const*' This is the same behaviour with 4.1.1, 4.1.2, 3.4.6 and I stopped there. I'm sure I'm missing something, but I suspect the behaviour of GCC to be a bit strange in those corner cases. Could you comment about that ? Thanks. -- Fab