boost::filesystem exception not caught on MacOS X
Hi, I have a strange problem that an exception thrown by a boost::filesystem directory_iterator is not caugth on MacOS X. Please consider the following code: ("const string &dir" is a parameter) bool retVal = true; try { directory_iterator i(dir); directory_iterator end; while (i != end) { // do something ++i; } } catch (...) { retVal = false; } While this works perfectly on Windows and Linux (the exception is caught fine), on MacOS I get the following: terminate called after throwing an instance of 'boost::filesystem::basic_filesystem_error<boost::filesystem::basic_path<std::string, boost::filesystem::path_traits> >' what(): boost::filesystem::basic_directory_iterator constructor Abort trap The program runs fine (withouth the trap) if I comment out the upper lines. I use the boost 1.34.0 lib built as universal binary on MacOS 10.5, according to the instructions at http://svn.boost.org/trac/boost/wiki/CMakeConfigAndBuild I link to the static non-debug mt version of boost_filesystem. Exceptions within my program are caught fine, just this boost exception is not caught. The program is also compiled as non-debug. Any help would be very much appreciated. Regards, Lothar
Hi, I'm still stuck with the uncaught exception, I have no idea what is going wrong there. Does anyone have any hint on what I could check? I tried to compile the corresponding code in Xcode (MacOS 10.5), and there I'm getting hundreds of link warnings like warning boost::detail::shared_count::~shared_count()has different visibility (2) in /Users/l-may/projects/test/build/Debug/ libtest.a(justatest.o) and (1) in /Users/l-may/projects/test/obj/ testapp.build/Debug/testapp.build/Objects-normal/i386/test.o Not sure whether this is related to the exception problem. Any help? Best regards, Lothar On Nov 24, 2007, at 9:27 PM, Lothar May wrote:
Hi,
I have a strange problem that an exception thrown by a boost::filesystem directory_iterator is not caugth on MacOS X. Please consider the following code:
("const string &dir" is a parameter)
bool retVal = true; try { directory_iterator i(dir); directory_iterator end;
while (i != end) { // do something ++i; } } catch (...) { retVal = false; }
While this works perfectly on Windows and Linux (the exception is caught fine), on MacOS I get the following:
terminate called after throwing an instance of 'boost ::filesystem ::basic_filesystem_error<boost::filesystem::basic_path<std::string, boost::filesystem::path_traits> >' what(): boost::filesystem::basic_directory_iterator constructor Abort trap
The program runs fine (withouth the trap) if I comment out the upper lines.
I use the boost 1.34.0 lib built as universal binary on MacOS 10.5, according to the instructions at http://svn.boost.org/trac/boost/wiki/CMakeConfigAndBuild
I link to the static non-debug mt version of boost_filesystem. Exceptions within my program are caught fine, just this boost exception is not caught. The program is also compiled as non-debug.
Any help would be very much appreciated.
Regards,
Lothar
Hi, I still have no idea how to solve this problem. This time I'm using the boost patch of the adobe open source library to build boost 1.34.1 as universal binary according to http://opensource.adobe.com/asl_readme.html A simple program to reproduce the problem is: --cut here-- #include <iostream> #include <boost/filesystem.hpp> using namespace std; using namespace boost::filesystem; int main() { try { directory_iterator i("does_not_exist"); } catch(...) { cout << "This is never printed on MacOS 10.5." << endl; } return 0; } --cut here-- Compile and link as follows (on MacOS 10.5): g++ test.cpp -lboost_filesystem-mt-1_34_1 -o test Loads of linker warnings will show up (all of them "ld: warning ... has different visibility ..."). Run: ./test terminate called after throwing an instance of 'boost ::filesystem ::basic_filesystem_error<boost::filesystem::basic_path<std::string, boost::filesystem::path_traits> >' what(): boost::filesystem::basic_directory_iterator constructor Is boost not supported on MacOS 10.5? Thanks, Lothar On Dec 1, 2007, at 2:35 AM, Lothar May wrote:
Hi,
I'm still stuck with the uncaught exception, I have no idea what is going wrong there. Does anyone have any hint on what I could check? I tried to compile the corresponding code in Xcode (MacOS 10.5), and there I'm getting hundreds of link warnings like
warning boost::detail::shared_count::~shared_count()has different visibility (2) in /Users/l-may/projects/test/build/Debug/ libtest.a(justatest.o) and (1) in /Users/l-may/projects/test/obj/ testapp.build/Debug/testapp.build/Objects-normal/i386/test.o
Not sure whether this is related to the exception problem. Any help?
Best regards,
Lothar
On Nov 24, 2007, at 9:27 PM, Lothar May wrote:
Hi,
I have a strange problem that an exception thrown by a boost::filesystem directory_iterator is not caugth on MacOS X. Please consider the following code:
("const string &dir" is a parameter)
bool retVal = true; try { directory_iterator i(dir); directory_iterator end;
while (i != end) { // do something ++i; } } catch (...) { retVal = false; }
While this works perfectly on Windows and Linux (the exception is caught fine), on MacOS I get the following:
terminate called after throwing an instance of 'boost ::filesystem ::basic_filesystem_error<boost::filesystem::basic_path<std::string, boost::filesystem::path_traits> >' what(): boost::filesystem::basic_directory_iterator constructor Abort trap
The program runs fine (withouth the trap) if I comment out the upper lines.
I use the boost 1.34.0 lib built as universal binary on MacOS 10.5, according to the instructions at http://svn.boost.org/trac/boost/wiki/CMakeConfigAndBuild
I link to the static non-debug mt version of boost_filesystem. Exceptions within my program are caught fine, just this boost exception is not caught. The program is also compiled as non-debug.
Any help would be very much appreciated.
Regards,
Lothar
At 5:31 PM +0100 12/6/07, Lothar May wrote:
Hi,
I still have no idea how to solve this problem. This time I'm using the boost patch of the adobe open source library to build boost 1.34.1 as universal binary according to http://opensource.adobe.com/asl_readme.html
A simple program to reproduce the problem is:
--cut here--
#include <iostream> #include <boost/filesystem.hpp>
using namespace std; using namespace boost::filesystem;
int main() { try { directory_iterator i("does_not_exist"); } catch(...) { cout << "This is never printed on MacOS 10.5." << endl; } return 0; }
--cut here--
Compile and link as follows (on MacOS 10.5):
g++ test.cpp -lboost_filesystem-mt-1_34_1 -o test
Loads of linker warnings will show up (all of them "ld: warning ... has different visibility ...").
Except for the "catch ( ... )" not catching it, this sounds like a problem that gcc has on Mac OS (and probably elsewhere) having to do with catching exceptions thrown across shared library boundaries. There's an explanation here <http://developer.apple.com/technotes/tn2007/tn2185.html>, or you can search the archives of the "carbon-dev" mailing list at lists.apple.com for more information. The basic problem is that when the runtime compares type_info's to see if a catch block can catch the exception, it compares to see _if they have the same address_. This fails, of course, if a shared library and an application each have their own copy of the type_info structure. Mucking with the visibility of the symbols (your "loads of linker warnings" ) can fix this. -- -- Marshall Marshall Clow Idio Software <mailto:marshall@idio.com> It is by caffeine alone I set my mind in motion. It is by the beans of Java that thoughts acquire speed, the hands acquire shaking, the shaking becomes a warning. It is by caffeine alone I set my mind in motion.
Hi Marshall, thanks for the answer.
Except for the "catch ( ... )" not catching it, this sounds like a problem that gcc has on Mac OS (and probably elsewhere) having to do with catching exceptions thrown across shared library boundaries.
Anyway I'm using the static library... So it should work, shouldn't it? :-( Regards, Lothar
Hi, Marshall Clow wrote:
The basic problem is that when the runtime compares type_info's to see if a catch block can catch the exception, it compares to see _if they have the same address_. This fails, of course, if a shared library and an application each have their own copy of the type_info structure. Mucking with the visibility of the symbols (your "loads of linker warnings" ) can fix this.
I have fixed the linker warnings, but the exception is still not caught. I tried two different things: 1) Compile the test application using -fvisibility=hidden according to known issues: http://developer.apple.com/releasenotes/DeveloperTools/RN-Id/index.html g++ test.cpp -fvisibility=hidden -lboost_filesystem-mt-1_34_1 -o test No more linker warnings will show up, but the exception still won't be caught. 2) Compile the static boost libs with -fvisibility=default (by patching the build file) and then g++ test.cpp -lboost_filesystem-mt-1_34_1 -o test Again, no linker warnings about visibility, but still the exception is not caught. I'm definitely using the static libs. Any hints? Regards, Lothar
Lothar May: ...
2) Compile the static boost libs with -fvisibility=default (by patching the build file) and then
g++ test.cpp -lboost_filesystem-mt-1_34_1 -o test
Again, no linker warnings about visibility, but still the exception is not caught.
It strikes me that you're using the -mt version of libboost_filesystem, but at the same time seem to be compiling test.cpp in single-threaded mode by not passing -pthread. Could the two exception handling runtimes be different enough to not recognize each other's exceptions?
Hi Peter, Peter Dimov schrieb:
It strikes me that you're using the -mt version of libboost_filesystem, but at the same time seem to be compiling test.cpp in single-threaded mode by not passing -pthread. Could the two exception handling runtimes be different enough to not recognize each other's exceptions?
Thanks for the hint - but the application I initially had the problem with does provide the "-pthread". With the test app, it makes no difference at all (the binaries are identical, whether I use the switch or not). Regards, Lothar
Marshall Clow wrote:
The basic problem is that when the runtime compares type_info's to see if a catch block can catch the exception, it compares to see _if they have the same address_. This fails, of course, if a shared library and an application each have their own copy of the type_info structure. Mucking with the visibility of the symbols (your "loads of linker warnings" ) can fix this.
[snip]
I'm definitely using the static libs. Any hints?
If you're definitely using static libs, then the problem that I described isn't what's wrong. -- -- Marshall Marshall Clow Idio Software <mailto:marshall@idio.com> It is by caffeine alone I set my mind in motion. It is by the beans of Java that thoughts acquire speed, the hands acquire shaking, the shaking becomes a warning. It is by caffeine alone I set my mind in motion.
I have encoutered this same problem today (with regex sending a std::runtime_error) I was wondering if you figured it out. This only occurs with the release version of the boost:regex lib (not the debug). I am also using static (and MT) -- View this message in context: http://www.nabble.com/boost%3A%3Afilesystem-exception-not-caught-on-MacOS-X-... Sent from the Boost - Users mailing list archive at Nabble.com.
I got a direct response from Lothar, which I am posting here for others:
Yes. The solution is to add the option -no_dead_strip_inits_and_terms to the release configuration when building. It disables certain optimisations which cause the error.
See also
-- View this message in context: http://www.nabble.com/boost%3A%3Afilesystem-exception-not-caught-on-MacOS-X-... Sent from the Boost - Users mailing list archive at Nabble.com.
On Sun, Sep 21, 2008 at 1:30 PM, Brice Rivé <bricerive@free.fr> wrote:
I got a direct response from Lothar, which I am posting here for others:
Yes. The solution is to add the option -no_dead_strip_inits_and_terms to the release configuration when building. It disables certain optimisations which cause the error.
See also
I'm not familiar with this particular problem but in general there are no guarantees that a static object in a given cpp file will be initialized unless a function from that cpp file is called directly. This also means that the linker is free to kill all such static objects, as well as everything they would have bootstrapped. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode
participants (6)
-
Brice Rivé
-
Emil Dotchevski
-
Lothar May
-
Lothar May
-
Marshall Clow
-
Peter Dimov