<ab.json ./jtc -w'<phone>l:' -w'<phone>l:[-1:]' -s / -w'<phone>l:' -l leaks memory
D4N opened this issue · 2 comments
The following example from User Guide.md
results in a memory leak:
bash $ <ab.json jtc -w'<phone>l:' -w'<phone>l:[-1:]' -s / -w'<phone>l:' -l
"phone": {
"number": "113-123-2368",
"type": "mobile"
}
"phone": {
"number": "223-283-0372",
"type": "mobile"
}
"phone": {
"number": "333-638-0238",
"type": "home"
}
=================================================================
==240775==ERROR: LeakSanitizer: detected memory leaks
Indirect leak of 960 byte(s) in 6 object(s) allocated from:
#0 0x63c677 in operator new(unsigned long) (/home/dan/projects/github.com/ldn-softdev/jtc/jtc+0x63c677)
#1 0x855f8c in __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode> > >::allocate(unsigned long, void const*) /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/ext/new_allocator.h:115:27
#2 0x855ef0 in std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode> > > >::allocate(std::allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode> > >&, unsigned long) /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/bits/alloc_traits.h:460:20
#3 0x855e99 in std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode> >, std::less<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, Jnode> > >::_M_get_node() /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/bits/stl_tree.h:584:16
#4 0x94aa4f in std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode> >* std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode> >, std::less<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, Jnode> > >::_M_create_node<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Jnode>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, Jnode&&) /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/bits/stl_tree.h:634:23
#5 0x94a407 in std::pair<std::_Rb_tree_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode> >, bool> std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode> >, std::less<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, Jnode> > >::_M_emplace_unique<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Jnode>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, Jnode&&) /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/bits/stl_tree.h:2414:19
#6 0x7a9df1 in std::pair<std::_Rb_tree_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode> >, bool> std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Jnode, std::less<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, Jnode> > >::emplace<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Jnode>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, Jnode&&) /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/bits/stl_map.h:577:16
#7 0x675912 in Json::parse_array_(Jnode&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/./lib/Json.hpp:3074:20
#8 0x670232 in Json::parse_(Jnode&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/./lib/Json.hpp:3015:29
#9 0x6734ff in Json::parse_object_(Jnode&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/./lib/Json.hpp:3112:3
#10 0x670145 in Json::parse_(Jnode&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/./lib/Json.hpp:3014:30
#11 0x6749ac in Json::parse_array_(Jnode&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/./lib/Json.hpp:3058:3
#12 0x670232 in Json::parse_(Jnode&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/./lib/Json.hpp:3015:29
#13 0x6734ff in Json::parse_object_(Jnode&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/./lib/Json.hpp:3112:3
#14 0x670145 in Json::parse_(Jnode&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/./lib/Json.hpp:3014:30
#15 0x66d604 in Json::parse(Streamstr::const_iterator&, Json::ParseTrailing) /home/dan/projects/github.com/ldn-softdev/jtc/./lib/Json.hpp:2961:2
#16 0x70798e in Jtc::parsejson(Streamstr::const_iterator&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/jtc.cpp:1392:12
#17 0x704d88 in run_single_optset(CommonResource&, Streamstr::const_iterator&, Json&, Json&) /home/dan/projects/github.com/ldn-softdev/jtc/jtc.cpp:905:11
#18 0x7007c9 in run_decomposed_optsets(CommonResource&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/jtc.cpp:888:3
#19 0x6f595f in main /home/dan/projects/github.com/ldn-softdev/jtc/jtc.cpp:814:6
#20 0x7ff4d9941041 in __libc_start_main (/lib64/libc.so.6+0x27041)
Indirect leak of 960 byte(s) in 6 object(s) allocated from:
#0 0x63c677 in operator new(unsigned long) (/home/dan/projects/github.com/ldn-softdev/jtc/jtc+0x63c677)
#1 0x855f8c in __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode> > >::allocate(unsigned long, void const*) /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/ext/new_allocator.h:115:27
#2 0x855ef0 in std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode> > > >::allocate(std::allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode> > >&, unsigned long) /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/bits/alloc_traits.h:460:20
#3 0x855e99 in std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode> >, std::less<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, Jnode> > >::_M_get_node() /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/bits/stl_tree.h:584:16
#4 0xa175ef in std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode> >* std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode> >, std::less<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, Jnode> > >::_M_create_node<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&&, Jnode&&) /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/bits/stl_tree.h:634:23
#5 0xa16f37 in std::pair<std::_Rb_tree_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode> >, bool> std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode> >, std::less<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, Jnode> > >::_M_emplace_unique<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&&, Jnode&&) /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/bits/stl_tree.h:2414:19
#6 0x7b1121 in std::pair<std::_Rb_tree_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode> >, bool> std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Jnode, std::less<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, Jnode> > >::emplace<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Jnode>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&&, Jnode&&) /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/bits/stl_map.h:577:16
#7 0x6742b2 in Json::parse_object_(Jnode&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/./lib/Json.hpp:3120:21
#8 0x670145 in Json::parse_(Jnode&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/./lib/Json.hpp:3014:30
#9 0x6749ac in Json::parse_array_(Jnode&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/./lib/Json.hpp:3058:3
#10 0x670232 in Json::parse_(Jnode&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/./lib/Json.hpp:3015:29
#11 0x6734ff in Json::parse_object_(Jnode&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/./lib/Json.hpp:3112:3
#12 0x670145 in Json::parse_(Jnode&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/./lib/Json.hpp:3014:30
#13 0x6749ac in Json::parse_array_(Jnode&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/./lib/Json.hpp:3058:3
#14 0x670232 in Json::parse_(Jnode&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/./lib/Json.hpp:3015:29
#15 0x6734ff in Json::parse_object_(Jnode&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/./lib/Json.hpp:3112:3
#16 0x670145 in Json::parse_(Jnode&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/./lib/Json.hpp:3014:30
#17 0x66d604 in Json::parse(Streamstr::const_iterator&, Json::ParseTrailing) /home/dan/projects/github.com/ldn-softdev/jtc/./lib/Json.hpp:2961:2
#18 0x70798e in Jtc::parsejson(Streamstr::const_iterator&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/jtc.cpp:1392:12
#19 0x704d88 in run_single_optset(CommonResource&, Streamstr::const_iterator&, Json&, Json&) /home/dan/projects/github.com/ldn-softdev/jtc/jtc.cpp:905:11
#20 0x7007c9 in run_decomposed_optsets(CommonResource&, Streamstr::const_iterator&) /home/dan/projects/github.com/ldn-softdev/jtc/jtc.cpp:888:3
#21 0x6f595f in main /home/dan/projects/github.com/ldn-softdev/jtc/jtc.cpp:814:6
#22 0x7ff4d9941041 in __libc_start_main (/lib64/libc.so.6+0x27041)
SUMMARY: AddressSanitizer: 1920 byte(s) leaked in 12 allocation(s).
Hi D4N,
thanks for reporting this!
it's a GNU implementation of std::map.emplace()
is having this leak (when emplace-constructing a value from r-value reference). MacOS (and presumably Bsd) STL implementation does not have this leak/bug, so it's a bug in the GNU STL implementation only (which I find not the first time).
I'll try working around this issue by dodging std::map.emplace()
call and will do it via entry creating and then moving.
Okay, I've taken a closer look - good thing it's not an implementation error of emplace{}
call as I thought before.
After a deeper analysis it turned out to be a harmless side-effect of the swap
(-s
) operation. Leak indeed was produced but it was harmless: the nesting parts of a JSON tree after swapping with the nested JSON part were meant to be discarded anyways, but instead it was left "lingering in the air".
I'll push a fix soon, together with the fix for the other issue.
Thank you again, D4N for catching and reporting those.