【发布时间】:2019-09-25 04:58:15
【问题描述】:
按照question 的建议,我将#include <fenv.h> 和feenableexcept(FE_ALL_EXCEPT & ~FE_INEXACT); 添加到我的主要源代码中,并使用g++ -O0 -Wall -Wextra -Werror -g main.cpp -o main.o 编译它。项目中的所有文件都是使用 make 以这种方式编译的。 feenableexcept 仅被添加到 main。事物通过相同的-O0 和-g 链接在一起。然后我以gdb a.out 运行可执行文件。调试器给了我预期的SIGFPE 但是回溯不提供通常有用的信息。相反,我得到了这样的列表:
Program received signal SIGFPE, Arithmetic exception.
0x00002aaaabe19c0d in _amd_handle_error () from /lib64/libm.so.6
(gdb) bt
#0 0x00002aaaabe19c0d in _amd_handle_error () from /lib64/libm.so.6
#1 0x00002aaaabe19cca in _pow_special () from /lib64/libm.so.6
#2 0x00002aaaabdf6c12 in pow () from /lib64/libm.so.6
#3 0xbfc971b779361ea1 in ?? ()
#4 0x3fe85bf701f137d7 in ?? ()
#5 0x3fe914100cd71275 in ?? ()
#6 0x00007fffffffa420 in ?? ()
#7 0x00007fffffff9960 in ?? ()
#8 0x3fe7c514ca0e522d in ?? ()
#9 0x0000000000000000 in ?? ()
如果我尝试查看框架,我将毫无用处。在这种情况下,函数pow 在出现浮点错误的代码区域中被多次使用。知道我是如何到达pow 是这里缺少的信息。
通常当我使用-O0 和-g 时,我会得到与跟踪相关的函数、文件和行号。如果我使用相同的可执行文件设置断点并从断点回溯,我会得到有用的信息。
Breakpoint 1, SurfaceModel::ProcessGroups (this=0x7fffffff9f30) at source/SurfaceModel.cpp:398
398 vector<Group>::iterator it;
(gdb) bt
#0 SurfaceModel::ProcessGroups (this=0x7fffffff9f30) at source/SurfaceModel.cpp:398
#1 0x00000000006768e6 in MainLoop (logFile=...) at source/main.cpp:94
#2 0x0000000000676337 in main (argc=1, argv=0x7fffffffbe18) at source/main.cpp:41
然后我在代码中添加了*(int*)0=0; 以强制出现段错误,以查看这是否与信号有关。我也在那里得到了有用的信息。
Program received signal SIGSEGV, Segmentation fault.
0x000000000061f42a in SurfaceModel::ClearGroupHeatRates (this=0x7fffffff9f30) at source/SurfaceModel.cpp:456
456 *(int*)0=0; // force a seg fault
(gdb) bt
#0 0x000000000061f42a in SurfaceModel::ClearGroupHeatRates (this=0x7fffffff9f30) at source/SurfaceModel.cpp:456
#1 0x0000000000676ba5 in MainLoop (logFile=...) at source/pilager.cpp:137
#2 0x0000000000676341 in main (argc=1, argv=0x7fffffffbe18) at source/pilager.cpp:41
这似乎只与我对浮点控制所做的事情有关。我正在运行 GDB 7.12,这是用 GCC 5.3.0 编译的。有没有办法使用SIGFPE 保存跟踪信息?
【问题讨论】:
-
您使用的是什么版本的 GLIBC,您在什么平台上?
标签: gdb