Closed lanphon closed 3 years ago
@lanphon, thanks for the report. How can I build and run your demo?
Just clone the project from https://github.com/lanphon/peglib_debug, and do following operations:
$ cd peglib_debug
$ cmake -S . -B build
$ cmake --build build
$ bin64/test_init
And on Linux platform, the bug will be reproduced. I've used the peglib in a shared object, and use teh code from another executable test_init
. The callstack of gdb showes it failures to do the parser's assign-copy.
@lanphon, this should work. Hope it helps.
@yhirose it seems the bug is still not solved yet. with the latest code, it still crash. On the other hand, I could avoid this error by specifying the move-assigment manually by:
parser& operator=(parser&& rhs)
{
if (&rhs != this)
{
log = std::move(rhs.log);
grammar_ = std::move(rhs.grammar_);
start_ = rhs.start_; // cannot be start_ = std::move(rhs.start_), which would cause the error
}
return *this;
}
it seems when moving the start_
, the auto-synthesis move-assignment operator= would failure(it's strange since it's just a literal string). After specifying the move assignment operator=, the error disappears, but a memory leak is reported, said there are 5 char(just the length of the "ROOT" string) leaking. I've tried to rename the "ROOT" of the PEG to other one, and shows the leaked size match with the PEG root node name size.
==243707== Memcheck, a memory error detector
==243707== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==243707== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==243707== Command: ./test_init
==243707==
==243707==
==243707== HEAP SUMMARY:
==243707== in use at exit: 4,573 bytes in 35 blocks
==243707== total heap usage: 1,622 allocs, 1,587 frees, 186,121 bytes allocated
==243707==
==243707== 5 bytes in 1 blocks are definitely lost in loss record 1 of 16
==243707== at 0x483ADEF: operator new(unsigned long) (vg_replace_malloc.c:342)
==243707== by 0x4BBA0BF: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_assign(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (basic_string.tcc:265)
==243707== by 0x4BBA43E: assign (basic_string.h:1366)
==243707== by 0x4BBA43E: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (basic_string.h:667)
==243707== by 0x49C829C: peg::parser::operator=(peg::parser&&) (peglib.h:3648)
==243707== by 0x49B2F43: representation_t::init() (represent.cpp:27)
==243707== by 0x498F725: representation_t::representation_t() (represent.h:16)
==243707== by 0x4983ECB: __static_initialization_and_destruction_0(int, int) (testlang.cpp:14)
==243707== by 0x4983EFE: _GLOBAL__sub_I_testlang.cpp (testlang.cpp:25)
==243707== by 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
==243707== by 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
==243707== by 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
==243707==
==243707== 4,568 (72 direct, 4,496 indirect) bytes in 1 blocks are definitely lost in loss record 16 of 16
==243707== at 0x483ADEF: operator new(unsigned long) (vg_replace_malloc.c:342)
==243707== by 0x49F5349: __gnu_cxx::new_allocator<std::_Sp_counted_ptr_inplace<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > >, std::allocator<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > > >, (__gnu_cxx::_Lock_policy)2> >::allocate(unsigned long, void const*) (new_allocator.h:115)
==243707== by 0x49F23CC: std::allocator_traits<std::allocator<std::_Sp_counted_ptr_inplace<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > >, std::allocator<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > > >, (__gnu_cxx::_Lock_policy)2> > >::allocate(std::allocator<std::_Sp_counted_ptr_inplace<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > >, std::allocator<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > > >, (__gnu_cxx::_Lock_policy)2> >&, unsigned long) (alloc_traits.h:460)
==243707== by 0x49EC727: std::__allocated_ptr<std::allocator<std::_Sp_counted_ptr_inplace<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > >, std::allocator<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > > >, (__gnu_cxx::_Lock_policy)2> > > std::__allocate_guarded<std::allocator<std::_Sp_counted_ptr_inplace<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > >, std::allocator<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > > >, (__gnu_cxx::_Lock_policy)2> > >(std::allocator<std::_Sp_counted_ptr_inplace<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > >, std::allocator<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > > >, (__gnu_cxx::_Lock_policy)2> >&) (allocated_ptr.h:97)
==243707== by 0x49E4FF7: std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > >, std::allocator<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > > >>(std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > >*&, std::_Sp_alloc_shared_tag<std::allocator<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > > > >) (shared_ptr_base.h:680)
==243707== by 0x49DD1CD: std::__shared_ptr<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > >, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > > >>(std::_Sp_alloc_shared_tag<std::allocator<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > > > >) (shared_ptr_base.h:1371)
==243707== by 0x49D6050: std::shared_ptr<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > > >::shared_ptr<std::allocator<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > > >>(std::_Sp_alloc_shared_tag<std::allocator<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > > > >) (shared_ptr.h:408)
==243707== by 0x49D0A5B: std::shared_ptr<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > > > std::allocate_shared<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > >, std::allocator<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > > >>(std::allocator<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > > > const&) (shared_ptr.h:860)
==243707== by 0x49CA109: std::shared_ptr<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > > > std::make_shared<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, peg::Definition, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, peg::Definition> > >>() (shared_ptr.h:876)
==243707== by 0x49B700C: peg::ParserGenerator::Data::Data() (peglib.h:2679)
==243707== by 0x49C6B38: peg::ParserGenerator::perform_core(char const*, unsigned long, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<peg::Ope>, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<peg::Ope> > > > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::function<void (unsigned long, unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>) (peglib.h:3156)
==243707== by 0x49B6B85: peg::ParserGenerator::parse(char const*, unsigned long, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<peg::Ope>, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<peg::Ope> > > > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::function<void (unsigned long, unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>) (peglib.h:2644)
==243707==
==243707== LEAK SUMMARY:
==243707== definitely lost: 77 bytes in 2 blocks
==243707== indirectly lost: 4,496 bytes in 33 blocks
==243707== possibly lost: 0 bytes in 0 blocks
==243707== still reachable: 0 bytes in 0 blocks
==243707== suppressed: 0 bytes in 0 blocks
==243707==
==243707== For lists of detected and suppressed errors, rerun with: -s
==243707== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
I've tried to use peglib on my personal project. When splitting the parser initialization to a shared library, it seems Linux platform with gcc would causing error. It's of no problem for macOS and Windows.
A simple sample to reproduce this case is placed into here. I've checked with following environments, all of which could reproduce it: