3

私はSpiritQiパーサーで頻繁にsegfaultに遭遇しています。

問題をデバッグするために何日も費やした後(スタックトレースを理解するのは不可能であることがわかりました)、最小限の例に切り詰めることにしました。誰かが私が間違っていることを教えてもらえますか?

コードをbug.cppとして保存し、でコンパイルg++ -Wall -o bug bug.cppすれば、準備は完了です。

//#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::endl;
    }
    return 255;
}

私はこれをテストしました

  • g ++ 4.4、4.5、4.6および
  • ブーストバージョン1.42(ubuntu meerkat)および1.46.1.1(natty)

出力は

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

または、ブースト1.46.1では、レポートされますSpirit version: 2042

4

1 に答える 1

5

回答で提案したように初期化の順序を変更すると、問題が隠されます。実際の問題は、rule<>が適切なC++コピーセマンティクスを持っていることです。これを修正するには、文法の初期化を次のように書き直します。

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

理論的根拠とより詳細な説明については、ここを参照してください。

于 2011-05-14T13:41:13.297 に答える