点云库应用程序难以调试,可能是由于线程

Point cloud library apps difficult to debug, possibly due to threading?

本文关键字:于线程 线程 应用程序 调试      更新时间:2023-10-16

我正在使用cmake的点云库进行编译,并且我已经在调试模式下构建了它,但是我的程序没有按照我期望的方式隔离故障或中止。

具体来说,我得到这样的消息:

(gdb) run bunny
Starting program: debug/our_cvfh bunny
libc++abi.dylib: terminating
[New Thread 0x170b of process 80178]
Program received signal SIGABRT, Aborted.
0x00007fff88c6f866 in ?? ()
(gdb) bt
#0  0x00007fff88c6f866 in ?? ()
#1  0x00007fff8bb5235c in ?? ()
#2  0x0000000000000000 in ?? ()
(gdb) break rec/registered_views_source.h:305
Cannot access memory at address 0x961d60

在这种情况下,我知道错误在哪里,但我希望能够回溯它,看看在这种情况下是谁调用了函数。

是PCL创建另一个线程,这就是为什么我不能回溯?我现在没有做任何可视化,所以我不明白为什么它会使用线程。

我还尝试在调试目录中运行程序,而不是从源根目录中运行。下面是另一个不工作的例子:

$ gdb our_cvfh
GNU gdb (GDB) 7.7
Copyright (C) 2014 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-apple-darwin13.1.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://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 our_cvfh...done.
run (gdb) run
Starting program: /Users/jwoods/Projects/lidargl/fpfh/debug/our_cvfh
[New Thread 0x170b of process 33571]
Program received signal SIGSEGV, Segmentation fault.
0x000000010016cdec in ?? ()
(gdb) bt
#0  0x000000010016cdec in ?? ()
#1  0x00007fff5fbfbd08 in ?? ()
#2  0x00007fff5fbfbcc0 in ?? ()
#3  0x00007fff5fbfbcc8 in ?? ()
#4  0x00007fff5fbfbcc8 in ?? ()
#5  0x00007fff5fbfbcc8 in ?? ()
#6  0xffffffffffffffff in ?? ()
#7  0x00007fff5fbfbcc8 in ?? ()
#8  0x00007fff5fbfbcc8 in ?? ()
#9  0x00007fff5fbfbcc0 in ?? ()
#10 0x00007fff5fbfbcc0 in ?? ()
#11 0x00007fff5fbfbcc8 in ?? ()
#12 0x00007fff5fbfbcc8 in ?? ()
#13 0x00007fff5fbfbcc8 in ?? ()
#14 0x00007fff5fbff4a8 in ?? ()
#15 0x00007fff5fbff4d8 in ?? ()
#16 0x00007fff5fbff420 in ?? ()
#17 0x00007fff5fbff4d8 in ?? ()
#18 0x0000000000000000 in ?? ()
(gdb)

gdb工作得很好,当我不使用CMake,所以我的猜测是它有一些与CMake。这对其他人来说似乎没有问题,这告诉我,这也可能与我在Mac OS x上使用CMake有关。

如何获得正常的GDB行为?

我可以运行dsymutil my_output_binary以生成调试符号(在make之后)。这是一种变通方法。我希望它能自动完成,我不知道为什么不能。dsymutil策略适用于大多数分段故障,但不适用于SIGABRT的某些情况。下面是输出:

Calling compute <--- normal std::cerr output of my program, single-threaded
Assertion failed: (index >= 0 && index < size()), function operator[], file /usr/local/Cellar/eigen/3.2.1/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h, line 378.
[New Thread 0x170b of process 64108]
Program received signal SIGABRT, Aborted.
0x00007fff84999866 in ?? ()
(gdb) bt
#0  0x00007fff84999866 in ?? ()
#1  0x00007fff862c335c in ?? ()
#2  0x0000000000000000 in ?? ()
(gdb) info threads
  Id   Target Id         Frame
  2    Thread 0x170b of process 64108 0x00007fff8499a662 in ?? ()
* 1    Thread 0x1503 of process 64108 0x00007fff84999866 in ?? ()
(gdb)

请注意,我的程序本身并不是多线程的,但它似乎使用了一个创建线程的库——或者至少这是我从gdb输出中收集到的。

我已经尝试禁用PCL使用的Eigen线程。

有趣的是,lldb能够生成回溯,但我很好奇为什么GDB不能。

除了简单地使用LLDB代替GDB之外,我还没有弄清楚如何调试线程。

然而,我已经想出了如何自动产生调试符号!万岁。

你需要三个文件:

  • UseCompVer.cmake
  • AddOptions.cmake
  • UseDebugSymbols.cmake

把这些放到项目的cmake/Modules/目录中。

CMakeLists.txt中,在项目声明之后需要以下行:

set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules/")
if (APPLE) # this if statement is optional, but you definitely need the include()
  include(UseDebugSymbols)
endif (APPLE)

将在适当的位置查找。

我应该注意到,我同时对我的项目做了另一个更改,这可能对你也有用。在add_executable行中,就在目标名称之后,我添加了MACOSX_BUNDLE。这个标志将导致它被编译为.app而不是普通的二进制文件。下面是我项目中的一个例子:

add_executable(pose MACOSX_BUNDLE pose.cpp rec/global_nn_recognizer_cvfh.cpp rec/global_nn_recognizer_cvfh.hpp rec/render_views_tesselated_sphere.cpp)