why gdb show wrong variable value? [duplicate] - c

This question already has answers here:
gdb prints wrong values when modifying arguments
(3 answers)
Closed 6 years ago.
I have simple program:
#include <stdio.h>
void func(int i) {
i = 1;
printf("%d\n", i);
}
int main(int argc, char *argv[]){
func(0);
return 0;
}
and now:
gcc test.c -g -o test
gdb test
(gdb) b main
Breakpoint 1 at 0x400543: file test.c, line 9.
(gdb) run
Starting program: /tmp/test
Breakpoint 1, main (argc=1, argv=0x7fffffffe458) at test.c:9
9 func(0);
(gdb) s
func (i=0) at test.c:4
4 i =1;
(gdb) p i
$1 = 0
(gdb) n
5 printf("%d\n", i);
(gdb) p i
$2 = 0
(gdb)
Program works fine, shows "1", but why gdb shows me "0" value?
Debian wheezy.
I observed that on gcc-4.7, gcc-4.6.
On gcc-4.4 all is ok.

This is a bug that is fixed if you compile with -fvar-tracking. Your question is a tighter version of this SO question, which references a bug report on GCC 4.8.0 suggesting the above compile flag.

Related

Why the function address is different before and after I run the code? [duplicate]

This question already has answers here:
Function address is different in nm output and gdb
(2 answers)
Closed 4 months ago.
the source code is here
#include <stdio.h>
int gcd(a, b) {
if (b == 0) return a;
return gcd(b, a % b);
}
int main(int argc, char **argv) {
int a = atoi(argv[1]);
int b = atoi(argv[2]);
int res = gcd(a, b);
printf("%d\n", res);
return 0;
}
and compiled with gcc -O0 gcd.c -o gcd -g
Before I run gcd, the gcd() address is 0x1169.
After I run it, the address of the same function becomes to 0x555555555169.
$ gdb -q gcd
Reading symbols from gcd...
(gdb) p gcd
$1 = {int (int, int)} 0x1169 <gcd>
(gdb) run 42 24
Starting program: ~/Workstation/gcd 42 24
6
[Inferior 1 (process 104126) exited normally]
(gdb) p gcd
$2 = {int (int, int)} 0x555555555169 <gcd>
Why there're such a difference between before and after running the code?
This is due to Address Space Layout Randomization. In short, it means that modules/libs/executables will be at a different address each time being loaded.

Address of Static Variables Changing at Runtime

I'm trying to figure out why the address of a static uint64_t arr[] changes when it's defined in the global scope inside the main executable.
It changes from 0x201060 (defined by the linker?) to 0x555555755060 at runtime, and I have no idea why.
Why does this happen, and is there a way I can prevent this behavior?
I have a precompiled binary that does not exhibit this behavior, and I am trying to emulate it.
$ gdb a.out # compiled from test.c
GNU gdb (GDB) 8.0.1...
Reading symbols from a.out...done.
(gdb) x/x arr
0x201060 <arr>: 0x00000024
(gdb) b main
Breakpoint 1 at 0x6e9: file test.c, line 116.
(gdb) run
Starting program: ...
Breakpoint 1, main (argc=1, argv=0x7fffffffdb28) at test.c:116
116 if(argc != 2) {
(gdb) x/x arr
0x555555755060 <arr>: 0x00000024
test.c was compiled with the following options: -g -fno-stack-protector -z execstack.
I compiled and ran test.c without ASLR (sudo bash -c 'echo 0 > /proc/sys/kernel/randomize_va_space'), but the result was the same.
The relevant parts of test.c are:
#include <stdint.h>
extern int func(uint64_t[]);
static uint64_t arr[] = {
0x00000024, 0x00201060,
0x00201080, 0x00000000,
0x00000008, 0x002010e0,
0x002010a0, 0x00000000,
0x00000032, 0x002010c0,
...
0x00201100, 0x00000000
};
int main(int argc, char** argv) {
func(arr);
return 0;
}
I figured it out :)
It turns out my gcc was outputting PIE executables by default, and passing -no-pie did what I needed. I made the array static in an attempt to keep the address the same, but I suppose that static only keeps the address the same during runtime.
Thank you to Mark Plotnick for your suggestion in the comments!

__strcpy_sse2_unaligned with -fno-builtin

I was debugging my program, then the last line happened, how can I fix it? I used the -fno-builtin to have a look at the strcpy() but it shows that the __strcpy_sse2_unaligned is getting called.
root#19:~/booksrc# gcc -fno-builtin -g char_array2.c
root#19:~/booksrc# gdb -q ./a.out
Reading symbols from ./a.out...done.
(gdb) list
1 #include <stdio.h>
2 #include <string.h>
3
4 int main() {
5 char str_a[20];
6
7 strcpy(str_a, "Hello World!\n");
8 printf(str_a);
9 }
(gdb) break 6
Breakpoint 1 at 0x708: file char_array2.c, line 6.
(gdb) break strcpy
Breakpoint 2 at 0x5a0
(gdb) break 8
Breakpoint 3 at 0x71b: file char_array2.c, line 8.
(gdb) run
Starting program: /root/booksrc/a.out
Breakpoint 1, main () at char_array2.c:7
7 strcpy(str_a, "Hello World!\n");
(gdb) cont
Continuing.
Breakpoint 2, __strcpy_sse2_unaligned ()
at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:47
47 ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S: No such file or directory.
__strcpy_sse2_unaligned is the implementation of strcpy which is used on your machine. glibc automatically chooses an optimized implementation based on CPU characteristics, using an IFUNC resolver.
This does not have to do anything with GCC and GCC built-ins. GCC emits a call to strcpy. It is just that glibc happens to call the function which it __strcpy_sse2_unaligned.

Why does gdb not break on strcpy? [duplicate]

This question already has answers here:
Can't step into string.h function with GDB
(3 answers)
Closed 6 years ago.
Please look at the command line below. I set two breakpoints: one on strcpy and the other on printf. Why did it skip breakpoint 1?
root#ninja:~/Desktop/Programs# gcc -g -o exp exp.c
root#ninja:~/Desktop/Programs# gdb -q exp
Reading symbols from /root/Desktop/Programs/exp...done.
(gdb) list
1 #include <stdio.h>
2 #include <string.h>
3
4 int main() {
5 char str_a[20];
6
7 strcpy(str_a, "Hello world!\n");
8 printf(str_a);
9 }
(gdb) break strcpy
Function "strcpy" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (strcpy) pending.
(gdb) break printf
Breakpoint 2 at 0x8048300
(gdb) run
Starting program: /root/Desktop/Programs/exp
Breakpoint 2, 0xb7eabf54 in printf () from /lib/i386-linux-gnu/i686/cmov/libc.so.6
(gdb) i r eip
eip 0xb7eabf54 0xb7eabf54 <printf+4>
(gdb) cont
Continuing.
Hello world!
[Inferior 1 (process 3726) exited with code 015]
The first breakpoint is pending.
(gdb) break strcpy
Function "strcpy" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (strcpy) pending. <<here
try: (gdb) break 7
7 being the line number.

How to debug using gdb?

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

Resources