Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<ab.json ./jtc -w'<phone>l:' -w'<phone>l:[-1:]' -s / -w'<phone>l:' -l leaks memory #28

Closed
D4N opened this issue Jun 9, 2020 · 2 comments
Labels
bug Something isn't working

Comments

@D4N
Copy link
Contributor

D4N commented Jun 9, 2020

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).
@ldn-softdev
Copy link
Owner

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.

@ldn-softdev ldn-softdev added the work-around work around some underlying issue/bug label Jun 10, 2020
@ldn-softdev
Copy link
Owner

ldn-softdev commented Jun 10, 2020

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.

@ldn-softdev ldn-softdev added bug Something isn't working and removed work-around work around some underlying issue/bug labels Jun 10, 2020
ldn-softdev pushed a commit that referenced this issue Jun 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants