[statechart] state_machine send_event assertion fails

Hello,
I'm a new user of statechart and for the most part am enjoying it very much. I've implemented a state machine with about 30 states (9 orthogonal regions) and over 50 events. It works very well and as expected, except for this one issue. Every once in a while, and in a way I've been unable to consistently repeat, I get an assertion failure resulting in a core dump.
/usr/include/boost/statechart/state_machine.hpp:873: boost::statechart::detail::reaction_result boost::statechart::state_machine

Hi Dustin
boost::statechart::result Container::react(const e_still&)
{
post_event(i_still_action());
post_event(i_still_moving());
return discard_event();
}
I am unsure if these reactions are the cause of the assertion failure, but given that the error message says "Container" is the InitialState, I have to assume so. Given that, I don't see how either Container or GripperPosition are inactive and don't know how to interpret this error. I'd appreciate some guidance.
Your react function looks fine. Do you by any chance directly or indirectly call state_machine::process_event from inside the state-machine (e.g. in- state reaction, transition, entry action, exit action, etc.)? Thanks, Andreas

Dustin, I have to agree with the last response. As long as you are calling post_event as opposed to process_event, your reaction looks fine. The issue might not be with this particular reaction. But if somewhere else you are inadvertently calling process_event while responding to a transition, you might be corrupting your state which is only later detected by this assertion. Dan -----Original Message----- From: Boost-users [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Andreas Huber Sent: Friday, June 14, 2013 7:36 To: boost-users@lists.boost.org Subject: Re: [Boost-users] [statechart] state_machinesend_event assertion fails Hi Dustin
boost::statechart::result Container::react(const e_still&)
{
post_event(i_still_action());
post_event(i_still_moving());
return discard_event();
}
I am unsure if these reactions are the cause of the assertion failure, but given that the error message says "Container" is the InitialState, I have to assume so. Given that, I don't see how either Container or GripperPosition are inactive and don't know how to interpret this error. I'd appreciate some guidance.
Your react function looks fine. Do you by any chance directly or indirectly call state_machine::process_event from inside the state-machine (e.g. in- state reaction, transition, entry action, exit action, etc.)? Thanks, Andreas _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users ________________________________ IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

On Jun 14, 2013, at 6:35 AM, Andreas Huber
Your react function looks fine. Do you by any chance directly or indirectly call state_machine::process_event from inside the state-machine (e.g. in- state reaction, transition, entry action, exit action, etc.)?
Thanks for the quick response. I only call process_event directly from outside the state machine. From inside, I do call transit() in a couple of reactions. That's how I understood guards were implemented. Maybe I missed something? Some of those transit() calls are to sibling states but most are to an uncle state (sibling to parent state). I never transit() to the same state. Here's an example: boost::statechart::result Inactive::react(const i_ready_command&) { if (state_downcast< const NotFaulted * >() != 0) { return transit<Active>(); } return discard_event(); } In few state's constructors, I call post_event(). -- dustin

Your reaction with guard looks fine to me. I've never had a problem implementing it like this.
-- Dan
-----Original Message-----
From: Boost-users [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Gooding, Dustin R. (JSC-ER411)
Sent: Friday, June 14, 2013 9:19
To: boost-users@lists.boost.org
Subject: Re: [Boost-users] [statechart] state_machinesend_event assertion fails
On Jun 14, 2013, at 6:35 AM, Andreas Huber
Your react function looks fine. Do you by any chance directly or indirectly call state_machine::process_event from inside the state-machine (e.g. in- state reaction, transition, entry action, exit action, etc.)?
Thanks for the quick response. I only call process_event directly from outside the state machine. From inside, I do call transit() in a couple of reactions. That's how I understood guards were implemented. Maybe I missed something? Some of those transit() calls are to sibling states but most are to an uncle state (sibling to parent state). I never transit() to the same state. Here's an example: boost::statechart::result Inactive::react(const i_ready_command&) { if (state_downcast< const NotFaulted * >() != 0) { return transit<Active>(); } return discard_event(); } In few state's constructors, I call post_event(). -- dustin _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users ________________________________ IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

I only call process_event directly from outside the state machine.
From inside, I do call transit() in a couple of reactions. That's
how I understood guards were implemented. Maybe I missed something?
As long as you call transit (and its relatives like e.g. terminate) only from react functions, you're not missing anything.
Some of
those transit() calls are to sibling states but most are to an uncle state (sibling to parent state). I
never transit() to the same state.
You can transit to any state, even the one you are currently in, so no problem here either.
In few state's constructors, I call post_event().
That's fine too. So far everything seems in order. The only suggestion I have is that you try to reproduce the problem and then whittle it down to something that you are comfortable to post or send me by private email. I know this is sometimes hard, but the statechart internals are such that the library should exhibit exactly the same behavior when two newly constructed FSMs of the same type are fed the same events in the same order. So, if possible log all events and wait for the problem to resurface? Regards, Andreas

On Jun 14, 2013, at 3:25 PM, Andreas Huber
That's fine too.
That's what's so frustrating. Everything *looks* right. And Boost, in general, is so picky about things that if it even compiles that tells me I'm on the right track.
So, if possible log all events and wait for the problem to resurface?
That's my next step. I'll instrument before every send_event, process_event and transit. I'm also in the process of converting a bunch of custom_reactions into more appropriate things like in_state_reactions, just to eliminate unnecessary event handling on my part. I'll post back when/if I ever nail it down. It happens very infrequently, but enough to give me heartburn. -- dustin

On Fri, 14 Jun 2013 22:36:59 +0200, Gooding, Dustin R. (JSC-ER411)
"GripperPosition" is my state_machine. "Container" is the simple_state the state machine initially enters. Container > has no transitions, but many sub states (it's the owner of the 9 orthogonal regions). (As far as I can tell, if the state machine is alive, then "Container" is an active state.) "Container" has a handful of custom_reactions that essentially listen for user-supplied events, "forward" those events in to the appropriate orthogonal regions using internal-only events, and then discard the user-supplied events. The intention here is to have a single event propagate to multiple orthogonal regions, allowing them all to react. For example:
AFAIK boost statechart is not thread-safe, so ensure you're not processing the external events simultaneously.
I'll post back when/if I ever nail it down. It happens very infrequently, but enough to give me heartburn.
For me the assertion condition (+comment before if available) with the stacktrace at the assertion moment always explained the issue. Look at your stack trace, you'll likely see unambiguously what is causing send_event() in an unstable state. If the assertion is not reproducible all the time, I'd check for memory/threading errors with valgrind tools. -- Slava
participants (4)
-
Andreas Huber
-
Gooding, Dustin R. (JSC-ER411)
-
Kelly, Dan
-
Slava