本文介绍了为什么 gdb 将 sqrt(3) 评估为 0?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

3 的平方根,由 Wolfram Alpha 估计:

The square root of 3, as estimated by Wolfram Alpha:

1.7320508075688772935274463415058723669428052538103806280558...

当我在 C 中执行 sqrt(3) 时,它的计算结果为 0.为什么?

When I do sqrt(3) in C, it evaluates to 0. Why?

EDIT4:以下是在 GDB 中重现此问题的方法.创建 test.c 如下:

EDIT4: here's how you can reproduce this issue in GDB. Create test.c as follows:

#include <stdio.h>
#include <math.h>

int main()
{
  printf("sqrt(3): %f
", sqrt(3));
  return 0;
}

编译:

gcc -O0 -g -Wall -pedantic -ansi -lm -o test test.c

运行调试器:

gdb test

在控制台输入:

(gdb) break test.c:6
Breakpoint 1 at 0x400578: file test.c, line 6.
(gdb) r
Starting program: /home/pdedecker/Desktop/test
Breakpoint 1, main () at test.c:6
6         printf("sqrt(3): %f
", sqrt(3));
(gdb) print sqrt(3)
$1 = 0
(gdb) s
sqrt(3): 1.732051

我的 GDB 版本是 GNU gdb (GDB) SUSE (7.1-3.12).

My GDB version is GNU gdb (GDB) SUSE (7.1-3.12).

推荐答案

问题不在于缺少函数声明(这不是缺少,因为您确实包含了 ).

The problem is not the missing function declaration (which isn't missing, since you did include <math.h>).

问题是缺少您实际使用的 sqrt 的调试信息.没有这些调试信息,GDB 不知道要传递给 sqrt() 的参数类型以及它返回的内容.

The problem is missing debug info for the sqrt you are actually using. Without that debug info, GDB has no clue what parameter type to pass to sqrt(), and what it returns.

您可以通过安装 libc-debuginfo 包来获取许多 Linux 发行版上所需的调试信息.这是我在这样的系统上看到的:

You can get the required debug info on many Linux distributions by installing libc-debuginfo package. Here is what I see on such a system:

gdb -q ./a.out
Reading symbols from /tmp/a.out...done.
(gdb) b main
Breakpoint 1 at 0x400558: file t.c, line 6.
(gdb) r

Breakpoint 1, main () at t.c:6
6     printf("sqrt(3): %f
", sqrt(3));
(gdb) p sqrt
$1 = {<text variable, no debug info>} 0x7ffff7b7fb50 <__sqrt>

注意:没有调试信息"

(gdb) p sqrt(3)
$2 = 0
(gdb) p sqrt(3.0)
$3 = 0

注意:符合您的行为.哪些 sqrt 函数有调试信息?

Note: matches your behavior.What sqrt functions do have debug info?

(gdb) info func sqrt
All functions matching regular expression "sqrt":

File ../sysdeps/x86_64/fpu/e_sqrt.c:
double __ieee754_sqrt(double);

File s_csqrt.c:
complex double __csqrt(complex double);

File ../sysdeps/x86_64/fpu/e_sqrtf.c:
float __ieee754_sqrtf(float);

File w_sqrtf.c:
float __sqrtf(float);

File s_csqrtf.c:
complex float __csqrtf(complex float);

File ../sysdeps/i386/fpu/e_sqrtl.c:
long double __ieee754_sqrtl(long double);

File w_sqrtl.c:
long double __sqrtl(long double);

File s_csqrtl.c:
complex long double __csqrtl(complex long double);

File ../sysdeps/ieee754/dbl-64/mpsqrt.c:
void __mpsqrt(mp_no *, mp_no *, int);

File w_sqrt.c:
double __sqrt(double);

(gdb) p __sqrt
$4 = {double (double)} 0x7ffff7b7fb50 <__sqrt>

注意:__sqrtsqrt在同一个地址,但是GDB知道它的类型!

Note: __sqrt is at the same address as sqrt, but GDB knows its type!

(gdb) p __sqrt(3)
$5 = 1.7320508075688772
(gdb) p __sqrt(3.0)
$6 = 1.7320508075688772

可以合理地认为这是 GDB 中的一个错误.随意在 GDB bugzilla 中创建一个.

One can reasonably argue this is a bug in GDB. Feel free to create one in GDB bugzilla.

这篇关于为什么 gdb 将 sqrt(3) 评估为 0?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 12:26