The following quick snippet crashes with GCC 4.5.0, on the second call to
get():

"""
#include <future>

int make_int() { return 52; }

int main()
{
  std::future<int> future_in = std::async(make_int);

  printf("%d\n", future_in.get());
  printf("%d\n", future_in.get());
}
"""

Backtrace:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000401c3f in std::__future_base::_State::wait (this=0x0) at
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.0/include/g++-v4/future:281
281             _M_run_deferred();
(gdb) backtrace 
#0  0x0000000000401c3f in std::__future_base::_State::wait (this=0x0) at
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.0/include/g++-v4/future:281
#1  0x0000000000402e9d in std::__basic_future<int>::_M_get_result
(this=0x7fffffffd880)
    at /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.0/include/g++-v4/future:515
#2  0x0000000000402560 in std::future<int>::get (this=0x7fffffffd880) at
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.0/include/g++-v4/future:594
#3  0x00000000004017a2 in main () at promise.cpp:10

Obviously this is not a valid operation, since get() moves the result and then
zaps itself (and valid() returns false after get() is called). However from a
usability standpoint this doesn't seem ideal. It looks like adding a check in
__basic_future::_M_get_result that ensures that _M_state is not NULL would be
sufficient to catch this case.

I would assume the result of doing a get() when !valid() is undefined, so
throwing an exception when someone does this would be conforming, and a lot
more obvious and friendly. If for some reason this couldn't work, even just an
assertion fail would be more informative than a NULL pointer deref.


-- 
           Summary: [c++0x] std::future will crash with NULL deref if get()
                    is called twice
           Product: gcc
           Version: 4.5.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: lloyd at randombit dot net
 GCC build triplet: x86_64-pc-linux-gnu
  GCC host triplet: x86_64-pc-linux-gnu
GCC target triplet: x86_64-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45133

Reply via email to