The square root of 3, as estimated by Wolfram Alpha:
1.7320508075688772935274463415058723669428052538103806280558...
When I do sqrt(3) in C, it evaluates to 0. Why?
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\n", sqrt(3));
return 0;
}
Compile:
gcc -O0 -g -Wall -pedantic -ansi -lm -o test test.c
Run debugger:
gdb test
Enter this at console:
(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\n", sqrt(3));
(gdb) print sqrt(3)
$1 = 0
(gdb) s
sqrt(3): 1.732051
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>).
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.
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\n", sqrt(3));
(gdb) p sqrt
$1 = {<text variable, no debug info>} 0x7ffff7b7fb50 <__sqrt>
Note: "no debug info"
(gdb) p sqrt(3)
$2 = 0
(gdb) p sqrt(3.0)
$3 = 0
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>
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
One can reasonably argue this is a bug in GDB. Feel free to create one in GDB bugzilla.
I predict that you didn't do #include <math.h>
Without a function declaration, C will default the return value of a function to int. A floating point number might come back as 0 depending on the size of your int. C will also not know how to convert the function argument. It will default to passing the argument as whatever type it happens to be. If you pass an integer to sqrt() it will not be converted to a double, but the sqrt() function will interpret the bit pattern as double.
To call a function without debug info, you must explicitly tell gdb the type for the return and arguments, using a function pointer cast. So, for your example:
(gdb) print ((double (*) (double)) sqrt) (3)
$1 = 1.7320508075688772
#include <stdio.h>
#include <math.h>
int main()
{
printf("sqrt(3): %f\n", sqrt(3));
return 0;
}
Output:
josh#josh-ubuntu:~/scratch$ ./a.out
sqrt(3): 1.732051
Maybe calling sqrt is not supported ! Maybe because it's a libc function. I don't know the deep reason why, but the following test shows an interesting behaviour:
double mysqrt(double x) { return sqrt(x) };
Then in a gdb session:
(gdb) p mysqrt(3)
$1 = 1.7320508075688772
(gdb) p sqrt(3)
$2 = -1209775368
Related
I was writing my own ncurses library and suddenly I found in GDB that snprintf() returned length larger than I specified. Is this defined behaviour or some mistake of mine ? The (reproducible) snippet code is this:
niko: snippets $ cat snprintf.c
#include <unistd.h>
#include <stdio.h>
char *example_string="This is a very long label. It was created to test alignment functions of VERTICAL and HORIZONTAL layout";
void snprintf_test(void) {
char tmp[72];
char fmt[32];
int len;
unsigned short x=20,y=30;
snprintf(fmt,sizeof(fmt),"\033[%%d;%%dH\033[0m\033[48;5;%%dm%%%ds",48);
len=snprintf(tmp,sizeof(tmp),fmt,y,x,0,example_string);
write(STDOUT_FILENO,tmp,len);
}
int main(void) {
snprintf_test();
}
niko: snippets $
Now we compile with debugging info and run:
niko: snippets $ gcc -g -o snprintf snprintf.c
niko: snippets $ gdb ./snprintf -ex "break snprintf_test" -ex run
.....
Reading symbols from ./snprintf...done.
Breakpoint 1 at 0x40058e: file snprintf.c, line 10.
Starting program: /home/deptrack/depserv/snippets/snprintf
Breakpoint 1, snprintf_test () at snprintf.c:10
10 unsigned short x=20,y=30;
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.22-16.fc23.x86_64
(gdb) s
12 snprintf(fmt,sizeof(fmt),"\033[%%d;%%dH\033[0m\033[48;5;%%dm%%%ds",48);
(gdb) print sizeof(fmt)
$1 = 32
(gdb) print sizeof(tmp)
$2 = 72
(gdb) s
13 len=snprintf(tmp,sizeof(tmp),fmt,y,x,0,example_string);
(gdb) print fmt
$3 = "\033[%d;%dH\033[0m\033[48;5;%dm%48s\000\000\000\000\000"
(gdb) print example_string
$4 = 0x4006c0 "This is a very long label. It was created to test alignment functions of VERTICAL and HORIZONTAL layout"
(gdb) s
14 write(STDOUT_FILENO,tmp,len);
(gdb) print len
$5 = 124
(gdb) print sizeof(tmp)
$6 = 72
(gdb)
The program outputs garbage at the end of the string. As you can see, the len variable returned from snprintf() is indicating that function has printed more than the allowed size of 72. Is this a bug or my mistake? If this behaviour is defined, then why snprintf() docs say it will print at most n characters. Very misleading and bug prone statement. I will have to write my own snprintf() to solve this problem.
Actually (from "man snprintf"):
If the output was
truncated due to this limit then the return value is the number of
characters (excluding the terminating null byte) which would have been
written to the final string if enough space had been available.
I am learning assembly language.
I am using gdb to learn about how to get information from the C code that is written.
I am trying to see the rip register at the beginning of each line and see how
many bytes of machine code are in each of the C statements in this program?
Can anyone show me the commands in gdb to find these?
#include <stdio.h>
int main(void) {
register int wye;
int *ptr;
int ex;
ptr = &ex;
ex = 305441741;
wye = -1;
printf("Enter an integer: ");
scanf("%i", ptr);
wye += *ptr;
printf("The result is %i\n", wye);
return 0;
}
Short example of stuff you can do to see some things about your program. $ is the shell prompt and gdb> is the gdb prompt, so don't type those:
$ gdb myprogram
... info about gdb and myprogram
gdb> disas main
... disassembly of the main function
gdb> break main
... sets a breakpoint in main; you see a message about this probably calling it breakpoint 1
gdb> run
... program starts and stops immediately at the start of main
gdb> i r
... lots of info about register contents
gdb> p $rip
... current instruction pointer (assuming x86_64)
gdb> s
... program runs for one source line.
gdb> p $rip
... ip has advanced a bit.
Is it possible to get the value of unused variable using GDB? Is there some configuration for GCC so that the garbage value of the unused variable will be shown not 'optimized out'?
c file:
#include<stdio.h>
void main()
{
int x;
int y;
printf("value of x: %d",x);
}
In the gdb I want to get the garbage value of variable y.
(gdb) run
Starting program: /home/charmae/workspace/AVT/a.out
Breakpoint 1, main () at file4.c:7
7 printf("value of x: %d",x);
(gdb) info locals
x = 2789364
(gdb) p y
$1 = <optimized out>
(gdb) p x
$2 = 2789364
It has nothing to do with GDB. The entity that optimized that variable out is the compiler (probably GCC in your case). You might force it to keep it by declaring the variable as volatile
A better question is - why are you trying to do?
It's nothing to do with gcc. Either the compiler has compiled code to maintain the value, or it hasn't.
You might add an y=y; statement. That would force y to be used, and with gcc -O0 -g keep track of it (at least on my Linux/Debian/Sid/AMD64 with gcc 4.6.2 and gdb 7.3.50)
The square root of 3, as estimated by Wolfram Alpha:
1.7320508075688772935274463415058723669428052538103806280558...
When I do sqrt(3) in C, it evaluates to 0. Why?
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\n", sqrt(3));
return 0;
}
Compile:
gcc -O0 -g -Wall -pedantic -ansi -lm -o test test.c
Run debugger:
gdb test
Enter this at console:
(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\n", sqrt(3));
(gdb) print sqrt(3)
$1 = 0
(gdb) s
sqrt(3): 1.732051
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>).
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.
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\n", sqrt(3));
(gdb) p sqrt
$1 = {<text variable, no debug info>} 0x7ffff7b7fb50 <__sqrt>
Note: "no debug info"
(gdb) p sqrt(3)
$2 = 0
(gdb) p sqrt(3.0)
$3 = 0
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>
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
One can reasonably argue this is a bug in GDB. Feel free to create one in GDB bugzilla.
I predict that you didn't do #include <math.h>
Without a function declaration, C will default the return value of a function to int. A floating point number might come back as 0 depending on the size of your int. C will also not know how to convert the function argument. It will default to passing the argument as whatever type it happens to be. If you pass an integer to sqrt() it will not be converted to a double, but the sqrt() function will interpret the bit pattern as double.
To call a function without debug info, you must explicitly tell gdb the type for the return and arguments, using a function pointer cast. So, for your example:
(gdb) print ((double (*) (double)) sqrt) (3)
$1 = 1.7320508075688772
#include <stdio.h>
#include <math.h>
int main()
{
printf("sqrt(3): %f\n", sqrt(3));
return 0;
}
Output:
josh#josh-ubuntu:~/scratch$ ./a.out
sqrt(3): 1.732051
Maybe calling sqrt is not supported ! Maybe because it's a libc function. I don't know the deep reason why, but the following test shows an interesting behaviour:
double mysqrt(double x) { return sqrt(x) };
Then in a gdb session:
(gdb) p mysqrt(3)
$1 = 1.7320508075688772
(gdb) p sqrt(3)
$2 = -1209775368
I am trying to add a breakpoint in my program using
b {line number}
but I am always getting an error that says:
No symbol table is loaded. Use the "file" command.
What should I do?
Here is a quick start tutorial for gdb:
/* test.c */
/* Sample program to debug. */
#include <stdio.h>
#include <stdlib.h>
int
main (int argc, char **argv)
{
if (argc != 3)
return 1;
int a = atoi (argv[1]);
int b = atoi (argv[2]);
int c = a + b;
printf ("%d\n", c);
return 0;
}
Compile with the -g3 option. g3 includes extra information, such as all the macro definitions present in the program.
gcc -g3 -o test test.c
Load the executable, which now contain the debugging symbols, into gdb:
gdb --annotate=3 test.exe
Now you should find yourself at the gdb prompt. There you can issue commands to gdb.
Say you like to place a breakpoint at line 11 and step through the execution, printing the values of the local variables - the following commands sequences will help you do this:
(gdb) break test.c:11
Breakpoint 1 at 0x401329: file test.c, line 11.
(gdb) set args 10 20
(gdb) run
Starting program: c:\Documents and Settings\VMathew\Desktop/test.exe 10 20
[New thread 3824.0x8e8]
Breakpoint 1, main (argc=3, argv=0x3d5a90) at test.c:11
(gdb) n
(gdb) print a
$1 = 10
(gdb) n
(gdb) print b
$2 = 20
(gdb) n
(gdb) print c
$3 = 30
(gdb) c
Continuing.
30
Program exited normally.
(gdb)
In short, the following commands are all you need to get started using gdb:
break file:lineno - sets a breakpoint in the file at lineno.
set args - sets the command line arguments.
run - executes the debugged program with the given command line arguments.
next (n) and step (s) - step program and step program until it
reaches a different source line, respectively.
print - prints a local variable
bt - print backtrace of all stack frames
c - continue execution.
Type help at the (gdb) prompt to get a list and description of all valid commands.
Start gdb with the executable as a parameter, so that it knows which program you want to debug:
gdb ./myprogram
Then you should be able to set breakpoints. For example:
b myfile.cpp:25
b some_function
Make sure you used the -g option when compiling.
You need to tell gdb the name of your executable file, either when you run gdb or using the file command:
$ gdb a.out
or
(gdb) file a.out
You need to use -g or -ggdb option at compile time of your program.
E.g., gcc -ggdb file_name.c ; gdb ./a.out