Skip to content

Roll back a rejected XML load as a whole, and keep Tree's destructor from throwing - #1289

Open
Quchaosheng wants to merge 2 commits into
BehaviorTree:masterfrom
Quchaosheng:fix-1282-1281-clean
Open

Quchaosheng wants to merge 2 commits into
BehaviorTree:masterfrom
Quchaosheng:fix-1282-1281-clean

Conversation

@Quchaosheng

Copy link
Copy Markdown

Two fixes for #1282 and #1281.

#1282 - #1266 dropped a document that failed to load, but the rollback
stopped at the document boundary. If main.xml includes sub.xml and then
fails, sub.xml has already registered its trees and they stay behind;
sub.xml also becomes the first document, so instantiateTree() reads
main_tree_to_execute from it. Take a snapshot of
tree_roots/tree_sources/suffix_count before the call and restore it on
failure. That also puts back a tree the call redefined, whose element lives in
the document about to be erased.

#1281 - Tree::~Tree() calls haltTree(), and halting may throw: a
TryCatch with catch_on_halt="true" ticks its catch child, and a tick is
allowed to throw. An exception leaving a destructor calls std::terminate, so
destroying such a tree aborted the process. Mark the destructor noexcept and
swallow the exception.

Both come with tests that fail on the current master:

  • XMLParserTest.RejectedIncludeKeepsNoTree and
    RejectedInlineIncludesKeepNoTree see the included tree survive a rejected load.
  • TreeDestructorTest.HaltThatThrowsDoesNotTerminate aborts with
    terminate called after throwing an instance of 'BT::NodeExecutionError'.

Full suite: 684 passed, 2 skipped. The XML side is also clean under
-fsanitize=address.

The noexcept on Tree::~Tree() changes a public header. If you would rather
keep the signature alone, dropping the keyword and keeping the try/catch in the
body is enough - say so and I will change it.

BehaviorTree#1266 dropped a document that failed to load, but the rollback stopped at the
document boundary. If main.xml includes sub.xml and then fails, sub.xml has
already registered its trees and they stay behind, and sub.xml becomes the
first document, so instantiateTree() reads main_tree_to_execute from it.

Take a snapshot before the call and restore it on failure. That also puts back
a tree this call redefined, whose element lives in the document about to be
erased.

Fixes BehaviorTree#1282
Tree::~Tree() calls haltTree(), and halting may throw: a TryCatch with
catch_on_halt="true" ticks its catch child, and a tick is allowed to throw.
An exception leaving a destructor calls std::terminate, so destroying such a
tree aborted the process.

Mark the destructor noexcept and swallow the exception. There is no caller
left to report to.

Fixes BehaviorTree#1281

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant