开发者

Segmentation fault with trivial Spirit Parser grammar

I'm running into frequent segfaults with my Spirit Qi parser.

After spending days to debug the issue (I found the stacktraces impossible to grok) I decided to trim it down to a minimal example. Can anyone tell what I'm doing wrong, if anything?

Save code as bug.cpp, compile with g++ -Wall -o bug bug.cpp and you should be good to go.

//#define BOOST_SPIRIT_DEBUG_PRINT_SOME 80
//#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/version.hpp>
#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <fstream>
#include <iterator>
#include <string>

namespace /*anon*/
{
    using namespace boost::spirit::qi;

    template <typename Iterator, typename
        Skipper> struct bug_demo : 
            public grammar<Iterator, Skipper>
    {
        bug_demo() : 
            grammar<Iterator, Skipper>(story, "bug"),
            story(the),
            the("the")
        {
//          BOOST_SPIRIT_DEBUG_NODE(story);
//          BOOST_SPIRIT_DEBUG_NODE(the);
        }

        rule<Iterator, Skipper> story, the;
    };

    template <typename It>
        bool do_parse(It begin, It end)
    {
        bug_demo<It, space_type> grammar;
        return phrase_parse(begin, end, grammar, space);
    }
}

int main()
{
    std::cout << "Spirit version: " << std::hex << SPIRIT_VERSION << std::endl;

    try
    {
        std::string contents = "the lazy cow";
        if (do_parse(contents.begin(), contents.end()))
            return 0;
    } catch (std::exception e)
    {
        std::cerr << "exception: " << e.what() << std::开发者_JS百科endl;
    }
    return 255;
}

I've tested this with

  • g++ 4.4, 4.5, 4.6 and
  • boost versions 1.42 (ubuntu meerkat) and 1.46.1.1 (natty)

The output is

sehe@meerkat:/tmp$ ./bug 
Spirit version: 2020
Segmentation fault

Or, with boost 1.46.1 it will report Spirit version: 2042


Changing the initialization order as you suggested in your answer just hides the problem. The actual problem is, that rule<>'s have proper C++ copy semantics. You can fix this by rewriting your gramar initialization as:

bug_demo() : 
    grammar<Iterator, Skipper>(story, "bug"),
    story(the.alias()),
    the("the")
{}

For a rationale and a more detailed explanation, see here.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜