Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP


dangerous pessimization at throw_io_failure #73

ArtemGr opened this Issue · 5 comments

3 participants


I've just seen this

 Invalid read of size 8
==15807==    at 0x8AFAB28: uw_update_context (unwind-dw2.c:216)
==15807==    by 0x8AFBF7B: _Unwind_RaiseException (
==15807==    by 0x85C6A30: __cxa_throw (in /usr/lib/x86_64-linux-gnu/
==15807==    by 0x7FF55B2: cppa::detail::fd_util::throw_io_failure(std::string&&, bool) (fd_util.cpp:57)
==15807==    by 0x7FF59DA: cppa::detail::fd_util::handle_write_result(long, bool) (fd_util.cpp:105)
==15807==    by 0x7FF5A4B: cppa::detail::fd_util::handle_read_result(long, bool) (fd_util.cpp:110)
==15807==    by 0x801CE45: cppa::detail::ipv4_io_stream::read(void*, unsigned long) (ipv4_io_stream.cpp:69)
==15807==    by 0x8066A77: cppa::remote_actor(std::pair<cppa::intrusive_ptr<cppa::util::input_stream>, cppa::intrusive_ptr<cppa::util::output_stream> >) (unicast_network.cpp:77)

And looking at the code, I think that
might benefit from less std::move and &&,

What do you think?


Well, the signature throw_io_failure(std::string, bool) would do as well. Though, I cannot see a bug in the code. I'll have a closer look at this next week.


Well, the "Invalid read" isn't repeating, so this is some corner case, but '&&' shouldn't be used in the normal code if I read c++ FAQs correctly.


The && just binds to an rvalue reference argument. Because the argument is named, it is an lvalue inside the function body. Removing it only broadens the interface, i.e., it will be up to the caller to decide whether to incur a move or copy. (IIRC, it would be a glvalue then, whereas it is an rvalue right now.) Without having run the code, it does not look like the culprit to me.

The only issue I see with the above code snippet is that std::ios_base::failure does not have an rvalue constructor, so you could change

throw std::ios_base::failure(std::move(tmp));


throw std::ios_base::failure(tmp);

Indeed, throw std::ios_base::failure(std::move(tmp)); seems to be the line the stack trace is pointing to.
Maybe this cast of tmp to rvalue is messing things for some compilers?

@Neverlord Neverlord closed this issue from a commit
@Neverlord Neverlord changed throw_io_failure to use ostringstream
this patch re-implements throw_io_failure to take a const char* and
use a string stream to build error message, fixes #73
@Neverlord Neverlord closed this in ae663f8

Even after reviewing the code again, I don't see a problem with the code. Looks like either a compiler bug or false alarm of valgrind to me. Nevertheless, I have revised the implementation and changed it to make use of std::ostringstream instead of concatenate the string by hand. This makes the implementation both shorter and should fix the strange behavior you're observing.

@Neverlord Neverlord added improvement and removed other labels
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.