boost-ext / sml

C++14 State Machine library
https://boost-ext.github.io/sml
Boost Software License 1.0
1.14k stars 177 forks source link

Violation of memory protection/Segmentation fault #241

Open hanusek opened 5 years ago

hanusek commented 5 years ago

The program returns "Segmentation fault (core dumped)". What is wrong? The implementation is based on the example - 'Nested' form documentation BOOST.SML: http://boost-experimental.github.io/sml/examples/index.html#nested SM is used to call methods from the Server. The Server is used to switch states in the SM.

#include <boost/sml.hpp>
#include <iostream>
namespace sml = boost::sml;
using namespace std;

template <class = class Dummy>
class Server
{
struct pollEvent{};
struct msgRcdEvent{};

class States
{
public:
 States(Server *server): _server(server){}

auto operator()() const noexcept
{
  auto msgRcdAction = [this] {
  std::cout << "HB server -> msgRcdAction " << std::endl;
 _server->recvMsg();
};

auto pollAction = [this] {
 std::cout << "HB server -> pollAction " << std::endl;
  _server->poll();
};

using namespace sml;

return make_transition_table(
 *"idle"_s + event<pollEvent> / pollAction    = "Poll"_s,
 "Poll"_s + event<msgRcdEvent> / msgRcdAction = "RcdMsg"_s,
 "RcdMsg"_s + event<pollEvent> / pollAction   = "Poll"_s
);
}
private:
 Server *_server{nullptr};
};

public:
 Server()
 {
  _states = new States(this);
  _sm     = new sml::sm<States>(*_states);
 }

 void process(){_sm->process_event(pollEvent{});}
 void poll(){_sm->process_event(msgRcdEvent{});}
 void recvMsg(){_sm->process_event(pollEvent{});}

private:
 States *_states{nullptr};
 sml::sm<States> *_sm{nullptr};
};

int main()
{
 Server<> s{};
 s.process();
 return 0;
}
arrtchiu commented 5 years ago

Try running it with address-sanitiser and/or undefined behaviour sanitisers turned on. It might be the same bug I just reported (#249). If so, you can work around it by changing auto pollAction = ... to std::function<void()> pollAction = ...

apmanol commented 5 years ago

Same issue with the example in dependencies.cpp


$ opt/clang/bin/clang++  --version 
clang version 8.0.0
$ opt/clang/bin/clang++ -std=c++14 -Wall -fsanitize=address,undefined  -ggdb -O2 -o dep.x dependencies.cpp  && ./dep.x
sml.hpp:439:49: runtime error: member call on address 0x7ffc1fd9de98 with insufficient space for an object of type '(lambda at dependencies.cpp:19:24)'
0x7ffc1fd9de98: note: pointer points here
 00 00 00 00  00 00 64 a6 d2 7f 00 00  00 00 00 00 00 00 00 00  a0 e0 d9 1f fc 7f 00 00  a8 e0 d9 1f
              ^ 
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior sml.hpp:439:49 in 
apmanol commented 5 years ago

The problem of the server above is the stack overflow.

AddressSanitizer:DEADLYSIGNAL
=================================================================
==6039==ERROR: AddressSanitizer: stack-overflow on address 0x7ffbff9b7f68 (pc 0x00000048e6ba bp 0x7ffbff9b87e0 sp 0x7ffbff9b7f70 T0)
    #0 0x48e6b9 in __interceptor_fwrite.part.56 clang/llvm/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:1100:1
    #1 0x7f22e7e1df63 in std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) (/lib64/libstdc++.so.6+0x11cf63)
    #2 0x52cc38 in std::basic_ostream<char, std::char_traits<char> >& std::operator<<<std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/ostream:561:2
    #3 0x52cc38 in Server<Dummy>::States::operator()() const::'lambda'()::operator()() const /tmp/sml/include/boost/server.cpp:22
.....

#312 0x52b307 in bool boost::sml::v1_1_0::back::sm_impl<boost::sml::v1_1_0::back::sm_policy<Server<Dummy>::States> >::process_event<Server<Dummy>::pollEvent, boost::sml::v1_1_0::aux::pool<Server<Dummy>::States>, boost::sml::v1_1_0::aux::pool<boost::sml::v1_1_0::back::sm_impl<boost::sml::v1_1_0::back::sm_policy<Server<Dummy>::States> > > >(Server<Dummy>::pollEvent const&, boost::sml::v1_1_0::aux::pool<Server<Dummy>::States>&, boost::sml::v1_1_0::aux::pool<boost::sml::v1_1_0::back::sm_impl<boost::sml::v1_1_0::back::sm_policy<Server<Dummy>::States> > >&) /tmp/sml/include/boost/./sml.hpp:1292:9

SUMMARY: AddressSanitizer: stack-overflow clang/llvm/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:1100:1 in __interceptor_fwrite.part.56