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.
精彩评论