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

Crash due to unexpected free() on cairo_data #1909

Open
twdragon opened this issue Nov 8, 2022 · 1 comment · May be fixed by #1910
Open

Crash due to unexpected free() on cairo_data #1909

twdragon opened this issue Nov 8, 2022 · 1 comment · May be fixed by #1910

Comments

@twdragon
Copy link

twdragon commented Nov 8, 2022

I built Cartographer with Clang 15, activating Polly optimizer and C++17 for my own customized build of ROS1 for Ubuntu 22.04/Mint Linux. However, this build of Cartographer library crashes while working with Cairo submap slices. This issue exists due to unexpected calling free() on the content of the cairo_data field of SubmapSlice structure. Below is the GDB output:

rosrun --prefix "gdb --args" cartographer_ros cartographer_pbstream_map_publisher -pbstream_filename /util/ros/jobot/map/map.pbstream
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /home/twdragon/src/ros/install_ws/devel/lib/cartographer_ros/cartographer_pbstream_map_publisher...
(gdb) run
Starting program: /home/twdragon/src/ros/install_ws/devel/lib/cartographer_ros/cartographer_pbstream_map_publisher -pbstream_filename /util/ros/jobot/map/map.pbstream
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7fffeb56b640 (LWP 47457)]
[New Thread 0x7fffead6a640 (LWP 47458)]
[New Thread 0x7fffe2569640 (LWP 47459)]
[New Thread 0x7fffd1d68640 (LWP 47460)]
[New Thread 0x7fffc9567640 (LWP 47461)]
[New Thread 0x7fffc8d66640 (LWP 47462)]
[New Thread 0x7fffb8565640 (LWP 47463)]
[New Thread 0x7fffaf4e1640 (LWP 47465)]
[New Thread 0x7fffaece0640 (LWP 47466)]
[New Thread 0x7fffae4df640 (LWP 47467)]
[New Thread 0x7fffadcde640 (LWP 47468)]
[ INFO] [1667920379.578857731]: I1108 16:12:59.000000 47453 pbstream_map_publisher_main.cc:51] Loading submap slices from serialized data.
[ INFO] [1667920381.179558315]: I1108 16:13:01.000000 47453 pbstream_map_publisher_main.cc:59] Generating combined map image from submap slices.
free(): invalid pointer

Thread 1 "cartographer_pb" received signal SIGABRT, Aborted.
__pthread_kill_implementation (no_tid=0, signo=6, threadid=140737141872192) at ./nptl/pthread_kill.c:44
44	./nptl/pthread_kill.c: Нет такого файла или каталога.
(gdb) where
#0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=140737141872192) at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (signo=6, threadid=140737141872192) at ./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (threadid=140737141872192, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#3  0x00007ffff26d5476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4  0x00007ffff26bb7f3 in __GI_abort () at ./stdlib/abort.c:79
#5  0x00007ffff271c6f6 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff286eb8c "%s\n") at ../sysdeps/posix/libc_fatal.c:155
#6  0x00007ffff2733d7c in malloc_printerr (str=str@entry=0x7ffff286c764 "free(): invalid pointer") at ./malloc/malloc.c:5664
#7  0x00007ffff2735ac4 in _int_free (av=<optimized out>, p=<optimized out>, have_lock=0) at ./malloc/malloc.c:4439
#8  0x00007ffff27384d3 in __GI___libc_free (mem=<optimized out>) at ./malloc/malloc.c:3391
#9  0x000055555562fe9d in std::__new_allocator<unsigned int>::deallocate (this=0x55555609b9c0, __p=0x555557a6d000, __n=17293379248325154061)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/new_allocator.h:158
#10 0x000055555562fe75 in std::allocator_traits<std::allocator<unsigned int> >::deallocate (__a=..., __p=0x555557a6d000, __n=17293379248325154061)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/alloc_traits.h:496
#11 0x000055555562fe28 in std::_Vector_base<unsigned int, std::allocator<unsigned int> >::_M_deallocate (this=0x55555609b9c0, __p=0x555557a6d000, 
    __n=17293379248325154061) at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_vector.h:387
#12 0x000055555562fd87 in std::_Vector_base<unsigned int, std::allocator<unsigned int> >::~_Vector_base (this=0x55555609b9c0)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_vector.h:366
#13 0x000055555562fd06 in std::vector<unsigned int, std::allocator<unsigned int> >::~vector (this=0x55555609b9c0)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_vector.h:733
#14 0x000055555562fcad in cartographer::io::SubmapSlice::~SubmapSlice (this=0x55555609b950) at /util/include/cartographer/io/submap_painter.h:42
#15 0x000055555562fc89 in std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice>::~pair (this=0x55555609b930)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_iterator.h:2547
#16 0x000055555562fc69 in std::__new_allocator<std::_Rb_tree_node<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> > >::destroy<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> > (this=0x7fffffffd2d8, __p=0x55555609b930)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/new_allocator.h:181
#17 0x000055555562fc0d in std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> > > >::destroy<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> > (__a=..., __p=0x55555609b930)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/alloc_traits.h:535
#18 0x000055555562fb9c in std::_Rb_tree<cartographer::mapping::SubmapId, std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice>, std::_Select1st<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> >, std::less<cartographer::mapping::SubmapId>, std::allocator<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> > >::_M_destroy_node (this=0x7fffffffd2d8, __p=0x55555609b910)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_tree.h:623
#19 0x000055555562fb41 in std::_Rb_tree<cartographer::mapping::SubmapId, std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice>, std::_Select1st<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> >, std::less<cartographer::mapping::SubmapId>, std::allocator<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> > >::_M_drop_node (this=0x7fffffffd2d8, __p=0x55555609b910)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_tree.h:631
#20 0x000055555562fa82 in std::_Rb_tree<cartographer::mapping::SubmapId, std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice>, std::_Select1st<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> >, std::less<cartographer::mapping::SubmapId>, std::allocator<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> > >::_M_erase (this=0x7fffffffd2d8, __x=0x55555609b910)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_tree.h:1937
#21 0x000055555562fa68 in std::_Rb_tree<cartographer::mapping::SubmapId, std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice>, std::_Select1st<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> >, std::less<cartographer::mapping::SubmapId>, std::allocator<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> > >::_M_erase (this=0x7fffffffd2d8, __x=0x555555cc26b0)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_tree.h:1935
#22 0x000055555562fa68 in std::_Rb_tree<cartographer::mapping::SubmapId, std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice>, std::_Select1st<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> >, std::less<cartographer::mapping::SubmapId>, std::allocator<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> > >::_M_erase (this=0x7fffffffd2d8, __x=0x555555cc21d0)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_tree.h:1935
#23 0x000055555562fa68 in std::_Rb_tree<cartographer::mapping::SubmapId, std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice>, std::_Select1st<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> >, std::less<cartographer::mapping::SubmapId>, std::allocator<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> > >::_M_erase (this=0x7fffffffd2d8, __x=0x55555609b190)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_tree.h:1935
#24 0x000055555562fa68 in std::_Rb_tree<cartographer::mapping::SubmapId, std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice>, std::_Select1st<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> >, std::less<cartographer::mapping::SubmapId>, std::allocator<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> > >::_M_erase (this=0x7fffffffd2d8, __x=0x55555ac7ccd0)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_tree.h:1935
#25 0x000055555562fa68 in std::_Rb_tree<cartographer::mapping::SubmapId, std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice>, std::_Select1st<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> >, std::less<cartographer::mapping::SubmapId>, std::allocator<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> > >::_M_erase (this=0x7fffffffd2d8, __x=0x55555ac7bdd0)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_tree.h:1935
#26 0x000055555562fa68 in std::_Rb_tree<cartographer::mapping::SubmapId, std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice>, std::_Select1st<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> >, std::less<cartographer::mapping::SubmapId>, std::allocator<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> > >::_M_erase (this=0x7fffffffd2d8, __x=0x55555ac7a160)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_tree.h:1935
#27 0x000055555562fa68 in std::_Rb_tree<cartographer::mapping::SubmapId, std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice>, std::_Select1st<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> >, std::less<cartographer::mapping::SubmapId>, std::allocator<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> > >::_M_erase (this=0x7fffffffd2d8, __x=0x555555ce4b80)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_tree.h:1935
#28 0x000055555562fa68 in std::_Rb_tree<cartographer::mapping::SubmapId, std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice>, std::_Select1st<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> >, std::less<cartographer::mapping::SubmapId>, std::allocator<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> > >::_M_erase (this=0x7fffffffd2d8, __x=0x555555cf7b60)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_tree.h:1935
#29 0x000055555562fa68 in std::_Rb_tree<cartographer::mapping::SubmapId, std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice>, std::_Select1st<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> >, std::less<cartographer::mapping::SubmapId>, std::allocator<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> > >::_M_erase (this=0x7fffffffd2d8, __x=0x555555cdf100)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_tree.h:1935
#30 0x000055555562fa68 in std::_Rb_tree<cartographer::mapping::SubmapId, std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice>, std::_Select1st<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> >, std::less<cartographer::mapping::SubmapId>, std::allocator<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> > >::_M_erase (this=0x7fffffffd2d8, __x=0x555555ce64b0)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_tree.h:1935
#31 0x000055555562fa68 in std::_Rb_tree<cartographer::mapping::SubmapId, std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice>, std::_Select1st<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> >, std::less<cartographer::mapping::SubmapId>, std::allocator<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> > >::_M_erase (this=0x7fffffffd2d8, __x=0x5555560fc390)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_tree.h:1935
#32 0x000055555562fa05 in std::_Rb_tree<cartographer::mapping::SubmapId, std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice>, std::_Select1st<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> >, std::less<cartographer::mapping::SubmapId>, std::allocator<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> > >::~_Rb_tree (this=0x7fffffffd2d8)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_tree.h:984
#33 0x000055555562ee25 in std::map<cartographer::mapping::SubmapId, cartographer::io::SubmapSlice, std::less<cartographer::mapping::SubmapId>, std::allocator<std::pair<cartographer::mapping::SubmapId const, cartographer::io::SubmapSlice> > >::~map (this=0x7fffffffd2d8)
    at /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_map.h:312
#34 0x000055555562d1c7 in cartographer_ros::(anonymous namespace)::LoadOccupancyGridMsg (pbstream_filename="/util/ros/jobot/map/map.pbstream", 
    resolution=0.050000000000000003)
    at /home/twdragon/src/ros/install_ws/src/cartographer_ros/cartographer_ros/cartographer_ros/pbstream_map_publisher_main.cc:64
#35 0x000055555562cb1e in cartographer_ros::(anonymous namespace)::Run (pbstream_filename="/util/ros/jobot/map/map.pbstream", map_topic="map", 
    map_frame_id="map", resolution=0.050000000000000003)
    at /home/twdragon/src/ros/install_ws/src/cartographer_ros/cartographer_ros/cartographer_ros/pbstream_map_publisher_main.cc:69
#36 0x000055555562ca51 in main (argc=1, argv=0x7fffffffd9a8)
    at /home/twdragon/src/ros/install_ws/src/cartographer_ros/cartographer_ros/cartographer_ros/pbstream_map_publisher_main.cc:97

Here is the cause:

#14 0x000055555562fcad in cartographer::io::SubmapSlice::~SubmapSlice (this=0x55555609b950) at /util/include/cartographer/io/submap_painter.h:42

The program crashes because the default destructor of SubmapSlice structure tries to clear cairo_data field calling free() on each element.

Does anyone know a workaround? And another question: does this issue come from Cairo API?

@twdragon
Copy link
Author

I investigated the reasons of such behaviour. There is an implicit construction of the SubmapSlice object within std::map in cartographer::io::DeserializeAndFillSubmapSlices(ProtoStreamDeserializer*, std::map<::cartographer::mapping::SubmapId, SubmapSlice>*, mapping::ValueConversionTables* . In C++17 it leads to the creation of an uninitialized SubmapSlice struct by the end of the container's internal storage. I am trying now to find a workaround for this issue.

twdragon added a commit to twdragon/cartographer that referenced this issue Nov 11, 2022
	- Added a workaround for misaligned SubmapSlice
	  structure between cartographer and cartographer_ros
	  built using different compilers or compile contexts
	- Rearranged SubmapSlice field order after static
	  analysis performed with clangd
	- Added commented non-portable workaround with
	  \#pragma pack
	- Closes cartographer-project#1909
twdragon added a commit to twdragon/cartographer that referenced this issue Nov 11, 2022
	- Added a workaround for misaligned SubmapSlice
	  structure between cartographer and cartographer_ros
	  built using different compilers or compile contexts
	- Rearranged SubmapSlice field order after static
	  analysis performed with clangd
	- Added commented non-portable workaround with
	  \#pragma pack
	- Closes cartographer-project#1909

Signed-off-by: Andrey Vukolov <andrey.vukolov@elettra.eu>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant