我们正在开发一个框架,该框架直接使用mrpt-1.9,而ojit_a又使用OpenCV 2.4。
我们正在编写单元测试,当测试存在(例如,在清理过程中)且出现OpenCV错误时,该测试会出现段错误:cv::String::deallocate()
我试过的
使用valgrind运行
==26159== Conditional jump or move depends on uninitialised value(s)
==26159== at 0x7DB7F5: cv::String::deallocate() (in /home/alex/codez/robot_platform/build/test_slam)
==26159== by 0xAF9FB0: cv::BmpEncoder::~BmpEncoder() (in /home/alex/codez/robot_platform/build/test_slam)
==26159== by 0xAF9FF8: cv::BmpEncoder::~BmpEncoder() (in /home/alex/codez/robot_platform/build/test_slam)
==26159== by 0x935AF65: cv::ImageCodecInitializer::~ImageCodecInitializer() (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.9)
==26159== by 0x807A369: __cxa_finalize (cxa_finalize.c:56)
==26159== by 0x9355B52: ??? (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.9)
==26159== by 0x4010DE6: _dl_fini (dl-fini.c:235)
==26159== by 0x8079FF7: __run_exit_handlers (exit.c:82)
==26159== by 0x807A044: exit (exit.c:104)
==26159== by 0x8060836: (below main) (libc-start.c:325)
==26159==
==26159== Invalid read of size 4
==26159== at 0x7DB7FB: cv::String::deallocate() (in /home/alex/codez/robot_platform/build/test_slam)
==26159== by 0xAF9FB9: cv::BmpEncoder::~BmpEncoder() (in /home/alex/codez/robot_platform/build/test_slam)
==26159== by 0xAF9FF8: cv::BmpEncoder::~BmpEncoder() (in /home/alex/codez/robot_platform/build/test_slam)
==26159== by 0x935AF65: cv::ImageCodecInitializer::~ImageCodecInitializer() (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.9)
==26159== by 0x807A369: __cxa_finalize (cxa_finalize.c:56)
==26159== by 0x9355B52: ??? (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.9)
==26159== by 0x4010DE6: _dl_fini (dl-fini.c:235)
==26159== by 0x8079FF7: __run_exit_handlers (exit.c:82)
==26159== by 0x807A044: exit (exit.c:104)
==26159== by 0x8060836: (below main) (libc-start.c:325)
==26159== Address 0x1a is not stack'd, malloc'd or (recently) free'd
==26159==
==26159==
==26159== Process terminating with default action of signal 11 (SIGSEGV)
==26159== Access not within mapped region at address 0x1A
==26159== at 0x7DB7FB: cv::String::deallocate() (in /home/alex/codez/robot_platform/build/test_slam)
==26159== by 0xAF9FB9: cv::BmpEncoder::~BmpEncoder() (in /home/alex/codez/robot_platform/build/test_slam)
==26159== by 0xAF9FF8: cv::BmpEncoder::~BmpEncoder() (in /home/alex/codez/robot_platform/build/test_slam)
==26159== by 0x935AF65: cv::ImageCodecInitializer::~ImageCodecInitializer() (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.9)
==26159== by 0x807A369: __cxa_finalize (cxa_finalize.c:56)
==26159== by 0x9355B52: ??? (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.9)
==26159== by 0x4010DE6: _dl_fini (dl-fini.c:235)
==26159== by 0x8079FF7: __run_exit_handlers (exit.c:82)
==26159== by 0x807A044: exit (exit.c:104)
==26159== by 0x8060836: (below main) (libc-start.c:325)
==26159== If you believe this happened as a result of a stack
==26159== overflow in your program's main thread (unlikely but
==26159== possible), you can try to increase the size of the
==26159== main thread stack using the --main-stacksize= flag.
==26159== The main thread stack size used in this run was 8388608.
==26159==
==26159== HEAP SUMMARY:
==26159== in use at exit: 286,067 bytes in 1,147 blocks
==26159== total heap usage: 7,469 allocs, 6,322 frees, 1,912,969 bytes allocated
==26159==
==26159== LEAK SUMMARY:
==26159== definitely lost: 0 bytes in 0 blocks
==26159== indirectly lost: 0 bytes in 0 blocks
==26159== possibly lost: 2,299 bytes in 27 blocks
==26159== still reachable: 283,768 bytes in 1,120 blocks
==26159== of which reachable via heuristic:
==26159== newarray : 1,536 bytes in 16 blocks
==26159== suppressed: 0 bytes in 0 blocks
==26159== Rerun with --leak-check=full to see details of leaked memory
==26159==
==26159== For counts of detected and suppressed errors, rerun with: -v
==26159== Use --track-origins=yes to see where uninitialised values come from
==26159== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
可能是我们错误地调用了MRPT函数,或者是MRPT本身存在错误。
用gdb运行它:
我一直在尝试在gdb中对其进行调试,但我只能进行回溯,但不能确定是代码的哪一部分负责。由于它似乎是在主要导出之后发生的,所以确实令人困惑。
更糟糕的是,我们构造(但实际上不做任何事情)的类不包含任何MRPT类或对象,因此我猜测这是在MRPT库中,而不是在我们的框架中。
Thread 1 "debug" received signal SIGSEGV, Segmentation fault.
0x00000000005b569b in cv::String::deallocate() ()
(gdb) bt
#0 0x00000000005b569b in cv::String::deallocate() ()
#1 0x000000000089969a in cv::BmpEncoder::~BmpEncoder() ()
#2 0x00000000008996d9 in cv::BmpEncoder::~BmpEncoder() [clone .localalias.25] ()
#3 0x00007ffff36a4f66 in cv::ImageCodecInitializer::~ImageCodecInitializer() () from /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4
#4 0x00007ffff484136a in __cxa_finalize (d=0x7ffff38d1000) at cxa_finalize.c:56
#5 0x00007ffff369fb53 in ?? () from /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4
#6 0x00007fffffffd8b0 in ?? ()
#7 0x00007ffff7de7de7 in _dl_fini () at dl-fini.c:235
Backtrace stopped: frame did not save the PC
我在
break cv::ImageCodecInitializer::~ImageCodecInitializer
处设置了一个断点而我得到的是:
Thread 1 "debug" hit Breakpoint 3, 0x0000000000888ad0 in cv::ImageCodecInitializer::~ImageCodecInitializer() ()
(gdb) bt
#0 0x0000000000888ad0 in cv::ImageCodecInitializer::~ImageCodecInitializer() ()
#1 0x00007ffff4840ff8 in __run_exit_handlers (status=0, listp=0x7ffff4bcb5f8 <__exit_funcs>, run_list_atexit=run_list_atexit@entry=true) at exit.c:82
#2 0x00007ffff4841045 in __GI_exit (status=<optimised out>) at exit.c:104
#3 0x00007ffff4827837 in __libc_start_main (main=0x5a4536 <main()>, argc=1, argv=0x7fffffffd9d8, init=<optimised out>, fini=<optimised out>, rtld_fini=<optimised out>, stack_end=0x7fffffffd9c8) at ../csu/libc-start.c:325
#4 0x00000000005a4469 in _start ()
搜索opencv-2.4调试
该应用程序是使用调试符号构建的,但系统似乎没有带有调试符号的opencv-2.4,因此我不断收到优化后的警告。
libopencv-apps-dev - opencv_apps Robot OS package - development files
libopencv-apps0d - opencv_apps Robot OS package - runtime files
libopencv-calib3d2.4v5 - computer vision Camera Calibration library
libopencv-contrib-dev - development files for libopencv-contrib
libopencv-contrib2.4v5 - computer vision contrib library
libopencv-core2.4v5 - computer vision core library
libopencv-dev - development files for opencv
libopencv-features2d2.4v5 - computer vision Feature Detection and Descriptor Extraction library
libopencv-flann2.4v5 - computer vision Clustering and Search in Multi-Dimensional spaces library
libopencv-gpu-dev - development files for libopencv-gpu2.4v5
libopencv-gpu2.4v5 - computer vision GPU library
libopencv-highgui2.4v5 - computer vision High-level GUI and Media I/O library
libopencv-imgproc2.4v5 - computer vision Image Processing library
libopencv-legacy-dev - development files for libopencv-legacy
libopencv-legacy2.4v5 - computer vision legacy library
libopencv-ml2.4v5 - computer vision Machine Learning library
libopencv-objdetect2.4v5 - computer vision Object Detection library
libopencv-ocl-dev - development files for libopencv-ocl2.4v5
libopencv-ocl2.4v5 - computer vision OpenCL support library
libopencv-photo2.4v5 - computer vision computational photography library
libopencv-stitching2.4v5 - computer vision image stitching library
libopencv-superres2.4v5 - computer vision Super Resolution library
libopencv-ts2.4v5 - computer vision ts library
libopencv-video2.4v5 - computer vision Video analysis library
libopencv-videostab2.4v5 - computer vision video stabilization library
libopencv2.4-java - Java bindings for the computer vision library
libopencv2.4-jni - Java jni library for the computer vision library
搜索有问题的功能的实际点
我仔细阅读了我们构建的缩小调试可执行文件,以尝试查明问题所在,然后尝试搜索实际功能:
nm -Ca debug | grep "ImageCodecInitializer"
0000000000889290 W cv::ImageCodecInitializer::ImageCodecInitializer()
0000000000889290 W cv::ImageCodecInitializer::ImageCodecInitializer()
0000000000888ad0 W cv::ImageCodecInitializer::~ImageCodecInitializer()
0000000000888ad0 W cv::ImageCodecInitializer::~ImageCodecInitializer()
然后,我试图找到GDB对这些地址要说的内容:
(gdb) info line *0x0000000000889290
No line number information available for address 0x889290 <_ZN2cv21ImageCodecInitializerC2Ev>
但是我不能从那里走到任何地方,所以我在GDB中进行搜索以查找构造此对象的人:
#0 0x00007ffff36a6240 in cv::ImageCodecInitializer::ImageCodecInitializer() () from /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4
#1 0x00007ffff369f8f6 in ?? () from /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4
#2 0x00007ffff7de76ba in call_init (l=<optimised out>, argc=argc@entry=1, argv=argv@entry=0x7fffffffd9d8, env=env@entry=0x7fffffffd9e8) at dl-init.c:72
#3 0x00007ffff7de77cb in call_init (env=0x7fffffffd9e8, argv=0x7fffffffd9d8, argc=1, l=<optimised out>) at dl-init.c:30
#4 _dl_init (main_map=0x7ffff7ffe168, argc=1, argv=0x7fffffffd9d8, env=0x7fffffffd9e8) at dl-init.c:120
#5 0x00007ffff7dd7c6a in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#6 0x0000000000000001 in ?? ()
#7 0x00007fffffffdda0 in ?? ()
#8 0x0000000000000000 in ?? ()
再次优化了。
搜索使用违规功能的库
该函数在
libopencv_highgui.so.2.4
中,因此我猜测其中一个MRPT库正在使用它,因此我去寻找我们正在链接的哪个MRPT库正在使用它,并找到了它:readelf -d debug
Dynamic section at offset 0x2b49bb0 contains 41 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libboost_system.so.1.58.0]
0x0000000000000001 (NEEDED) Shared library: [libboost_filesystem.so.1.58.0]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED) Shared library: [librt.so.1]
0x0000000000000001 (NEEDED) Shared library: [libmrpt-base.so.1.9]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libjpeg.so.8]
0x0000000000000001 (NEEDED) Shared library: [libpng12.so.0]
0x0000000000000001 (NEEDED) Shared library: [libtiff.so.5]
0x0000000000000001 (NEEDED) Shared library: [libjasper.so.1]
0x0000000000000001 (NEEDED) Shared library: [libz.so.1]
0x0000000000000001 (NEEDED) Shared library: [libIlmImf-2_2.so.22]
0x0000000000000001 (NEEDED) Shared library: [libHalf.so.12]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
因此,我发现:
sudo ldconfig -p | grep "libmrpt-base.so.1.9"
libmrpt-base.so.1.9 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmrpt-base.so.1.9
然后:
readelf -d /usr/lib/x86_64-linux-gnu/libmrpt-base.so.1.9
Dynamic section at offset 0xa5aea8 contains 37 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [librt.so.1]
0x0000000000000001 (NEEDED) Shared library: [libcxsparse.so.3.1.4]
0x0000000000000001 (NEEDED) Shared library: [libwx_baseu-3.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libwx_gtk2u_core-3.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libz.so.1]
0x0000000000000001 (NEEDED) Shared library: [libjpeg.so.8]
0x0000000000000001 (NEEDED) Shared library: [libopencv_highgui.so.2.4]
0x0000000000000001 (NEEDED) Shared library: [libopencv_imgproc.so.2.4]
0x0000000000000001 (NEEDED) Shared library: [libopencv_core.so.2.4]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000e (SONAME) Library soname: [libmrpt-base.so.1.9]
我知道这是造成问题的库,因为在我们的项目中,我们使用针对它的静态链接opencv-3.3。
不幸的是,我们正在使用的存储库也没有MRPT的调试符号:
libmrpt-base1.9 - Mobile Robot Programming Toolkit - base library
libmrpt-detectors1.9 - Mobile Robot Programming Toolkit - detectors library
libmrpt-graphs1.9 - Mobile Robot Programming Toolkit - graphs library
libmrpt-graphslam1.9 - Mobile Robot Programming Toolkit - graphslam library
libmrpt-gui1.9 - Mobile Robot Programming Toolkit - gui library
libmrpt-hmtslam1.9 - Mobile Robot Programming Toolkit - hmtslam library
libmrpt-hwdrivers1.9 - Mobile Robot Programming Toolkit - hwdrivers library
libmrpt-kinematics1.9 - Mobile Robot Programming Toolkit - kinematics library
libmrpt-maps1.9 - Mobile Robot Programming Toolkit - maps library
libmrpt-nav1.9 - Mobile Robot Programming Toolkit - nav library
libmrpt-obs1.9 - Mobile Robot Programming Toolkit - obs library
libmrpt-opengl1.9 - Mobile Robot Programming Toolkit - opengl library
libmrpt-slam1.9 - Mobile Robot Programming Toolkit - slam library
libmrpt-tfest1.9 - Mobile Robot Programming Toolkit - tfest library
libmrpt-topography1.9 - Mobile Robot Programming Toolkit - topography library
libmrpt-vision1.9 - Mobile Robot Programming Toolkit - vision library
libmrpt-comms1.9 - Mobile Robot Programming Toolkit - comms library
更糟糕的是:
nm -C libmrpt-base.so
nm: libmrpt-base.so: no symbols
这就是旅程的终点。
我有什么选择?
任何帮助,提示或技巧都将不胜感激。
如果此问题过于本地化,不符合SO标准,请发表评论,我将对其进行更新。
最佳答案
我的第一个猜测是,由于同时使用两个opencv版本,您可能会遇到此问题。
尝试从告诉CMake使用与主项目相同的opencv版本的来源构建mrpt。
mrpt-base不会直接使用highgui中的任何内容(尽管...它与之链接!这应该是固定的,四个肯定的),所以我怀疑该错误与opencv模块中静态变量的初始化有关,并且存在某些问题。链接器...
干杯