[Boost-bugs] [Boost C++ Libraries] #12311: boost::filesystem::directory_iterator(const path& p) iteration to cause a std::terminate()

Subject: [Boost-bugs] [Boost C++ Libraries] #12311: boost::filesystem::directory_iterator(const path& p) iteration to cause a std::terminate()
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2016-07-04 17:13:21


#12311: boost::filesystem::directory_iterator(const path& p) iteration to cause a
std::terminate()
--------------------------------+------------------------
 Reporter: florent.castelli@… | Owner: bemandawes
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: filesystem
  Version: Boost 1.61.0 | Severity: Problem
 Keywords: |
--------------------------------+------------------------
 Under some conditions, an iteration (for example using a C++11 for loop)
 over a directory_iterator can lead to a std::terminate()

 Happens with Clang from Xcode 7.3.1 on OSX in Release mode (-O2).

 Apparently, boost::filesystem::directory_iterator::increment is NOEXCEPT,
 but it is forwarding the "nullptr" error_code to the underlying function
 directory_iterator_increment. This one will throw on error if the
 error_code is "nullptr".

 The compiler optimization inlined the call into
 boost::filesystem::directory_iterator::increment and sees it's NOEXCEPT
 and thus calls std::terminate() directly and no try / catch in the caller
 will be able to intercept the errors.

 My program was fixed using the second constructor that takes an
 error_code, but I don't think the following code should hard crash
 programs:

 Local code (sorry, no repro available, the bug should be obvious without
 it):
 {{{
 try {
   for (auto &directory_entry :
 boost::filesystem::directory_iterator(path)) {
     // Do things
   }
 } catch (const boost::filesystem::filesystem_error &) {
   // swallow all errors but never reached
 }
 }}}
 Stacktrace:

 {{{
 * thread #2: tid = 0xe89aef, 0x00007fff9ac3cf06
 libsystem_kernel.dylib`__pthread_kill + 10, name = 'Thread name', stop
 reason = signal SIGABRT
   * frame #0: 0x00007fff9ac3cf06 libsystem_kernel.dylib`__pthread_kill +
 10
     frame #1: 0x00007fff921b24ec libsystem_pthread.dylib`pthread_kill + 90
     frame #2: 0x00007fff8da386e7 libsystem_c.dylib`abort + 129
     frame #3: 0x00007fff91880f81 libc++abi.dylib`abort_message + 257
     frame #4: 0x00007fff918a6a2f
 libc++abi.dylib`default_terminate_handler() + 243
     frame #5: 0x00007fff96fbb6c3 libobjc.A.dylib`_objc_terminate() + 124
     frame #6: 0x00007fff918a419e libc++abi.dylib`std::__terminate(void
 (*)()) + 8
     frame #7: 0x00007fff918a4213 libc++abi.dylib`std::terminate() + 51
     frame #8: 0x00000001000034ab storage_test`__clang_call_terminate + 11
     frame #9: 0x0000000100125be0
 storage_test`boost::filesystem::directory_iterator::increment(this=<unavailable>,
 ec=<unavailable>) + 32 at operations.hpp:913
     frame #10: 0x0000000100125125
 storage_test`boost::filesystem::detail::directory_iterator_construct(it=0x0000700000080c68,
 p=<unavailable>, ec=0x0000000000000000) + 453 at operations.cpp:2286
     frame #11: 0x000000010012653d
 storage_test`boost::filesystem::directory_iterator::directory_iterator(this=<unavailable>,
 p=<unavailable>) + 61 at operations.hpp:903
     frame #12: 0x0000000100126499
 storage_test`boost::filesystem::directory_iterator::directory_iterator(this=<unavailable>,
 p=<unavailable>) + 9 at operations.hpp:903
     frame #13: 0x000000010009829c
 storage_test`doStuff(this=0x0000000102805000,
 base_path="/var/folders/cc/v8qm1vps6fbfd8nnn761ys8w0000gn/T//8a4b3e25b7e08c81385601451ad4fae8d18948bb/storage_test/",
 files=0x0000700000080de0 size=0, allow_sleep=<unavailable>, where=1) + 236
 at storage_impl.cpp:1434
 }}}

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/12311>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:20 UTC