2016-07-31 219 views
0

我试图调试在库中引发的SIGFPE信号,我没有它的源代码。我正在使用gdb和asm布局来查看正在发生的事情。在追踪SIGFPE /算术异常时陷入困境

这些都是异常之前的说明:

0xcd3fffa <_ZN8name_space11ClassName1MethodNameEdddd+830>  fstpl -0x68(%ebp)          
B+ 0xcd3fffd <_ZN8name_space11ClassName1MethodNameEdddd+833>  fldl -0x58(%ebp)          
    0xcd40000 <_ZN8name_space11ClassName1MethodNameEdddd+836>  fstpl 0x4(%esp)          
    0xcd40004 <_ZN8name_space11ClassName1MethodNameEdddd+840>  mov 0x8(%ebp),%eax         
    0xcd40007 <_ZN8name_space11ClassName1MethodNameEdddd+843>  mov %eax,(%esp)          
    >0xcd4000a <_ZN8name_space11ClassName1MethodNameEdddd+846>  call 0xcd408c0 <_ZN8name_space11ClassName1AnotherMethodNameEd> 
    0xcd4000f <_ZN8name_space11ClassName1MethodNameEdddd+851>  mov 0x8(%ebp),%eax 

当我键入ni从指令去在0xcd4000a到一个在0xcd4000f我收到以下错误

Program received signal SIGFPE, Arithmetic exception. 
0x0cd408e8 in name_space::ClassName::AnotherMethodName(double)() at /Path/to/ClassName.h:69 

我不是熟悉装配,但我期待指针0xcd408c0指示AnotherMethodName开始。但指令指针已跳至0xcd408e8地址。其中还有AnotherMethodName()方法。

0xcd408e4 <_ZN8name_space11ClassName1AnotherMethodNameEd+36> fldz               
    0xcd408e6 <_ZN8name_space11ClassName1AnotherMethodNameEd+38> fdivrp %st,%st(1)            
    >0xcd408e8 <_ZN8name_space11ClassName1AnotherMethodNameEd+40> fldz               
    0xcd408ea <_ZN8name_space11ClassName1AnotherMethodNameEd+42> fucomip %st(1),%st 

0xcd408e8的指令后,它跳转到我的异常处理程序。

我已经搜索了很多甚至到了这一点。但目前我不知道该如何继续。

我也检查了浮点寄存器,它们似乎没有包含任何奇怪的值。

什么引发这个异常?

+0

在函数调用点键入'ni'将运行该函数并在返回时停止(如果遇到断点或异常,它可能会停止)。有一个不同的命令“stepi”,即使它是一个函数调用,它也只能运行一条指令。 –

+0

@MarkPlotnick是的,马克。你是对的。发布后,我意识到我必须使用'stepi'或'si'来运行一条指令。谢谢! – Ali

回答

2

不能为fldz,因为它只是设置寄存器为0

唯一的例外发生在fdivrp %st,%st(1)

你说你检查“奇怪”的价值观。但是以上必须是一个零除。你也检查st为零吗?必须为零。没有奇怪的,只是零。

FDIVRP到ST(i),ST(0)除以ST(0),通过ST(我),结果存储到ST(i),并弹出寄存器堆栈

编辑:不知道发生了什么事那里。用你的第三方软件检查你的参数。您可能已经传递了一些零值,例如项目数量,可能是因为库不喜欢的未初始化变量。 (对不起所有的猜测!)

+0

是的,你是对的。 '0xcd408e4'处的'fldz'将'st(0)'设置为零。然后'fdivrp%st,%st(1)'用'st(0)'分隔'st(1)'。这确实是一个零分!但是''fldz'在'0xcd408e8'后出现异常。你知道为什么吗? – Ali

+0

不确定,但PC在检测到ZERODIV之前可能已经经历了该指令。 –