#include <stdio.h>
int main()
{
int int_var = 5;
int *int_ptr;
int_ptr = &int_var; // put the address of int_var into int_ptr
printf(" int_var = %d\n &int_var = %p\n\n", int_var, &int_var);
printf(" int_ptr = %p\n &int_ptr = %p\n *int_ptr = %d\n\n", int_ptr, &int_ptr, *int_ptr);
*int_ptr = 10;
printf(" int_var = %d\n &int_var = %p\n\n", int_var, &int_var);
printf(" int_ptr = %p\n &int_ptr = %p\n *int_ptr = %d\n\n", int_ptr, &int_ptr, *int_ptr);
}
Fill out the empty space (if unsure, checkout the answers by compiling and running the
code).
$ gcc pointer.c -o pointer $ ./pointer int_var = 5 &int_var = 0x7ffff7dbb72c int_ptr = 0x7ffff7dbb72c &int_ptr = 0x7ffff7dbb730 *int_ptr = 5 int_var = 10 &int_var = 0x7ffff7dbb72c int_ptr = 0x7ffff7dbb72c &int_ptr = 0x7ffff7dbb730 *int_ptr = 10
|
Note: Constant strings like "hello" and "cat", declared as in char * x = "hello"; reside in text section. |
|
Fill out the blanks in the output of this program given below, by selecting one of the following options (note the addresses
are already sorted):
A. 0x400626 B. 0x400794 C. 0x602010 D. 0x1417010 E. 0x7ffee66a3310 F. 0x7ffee66a3320 hello= F (E is allowable) hello2= B &hello2= E (F is allowable) main= A &global= C p= D(Drag your mouse for the answer) |
tar -xvf gdb.tar cp .gdbinit ~ cp gdbx.py ~
gcc -g pointer.c -o pointerAgain, don't forget to add -g option!
$ gdb -q pointer
The option -q specifies "quiet" mode. In this mode, the gdb does not print the
introductory and copyright messages.
(gdb) list
1 #include <stdio.h>
2
3 int main()
4 {
5 int int_var = 5;
6 int *int_ptr;
7
8 int_ptr = &int_var; // put the address of int_var into int_ptr
9
10 printf(" int_var = %d\n &int_var = %p\n\n", int_var, &int_var);
(gdb)
11 printf(" int_ptr = %p\n &int_ptr = %p\n *int_ptr = %d\n\n", int_ptr, &int_ptr, *int_ptr);
12
13 *int_ptr = 10;
14
15 printf(" int_var = %d\n &int_var = %p\n\n", int_var, &int_var);
16 printf(" int_ptr = %p\n &int_ptr = %p\n *int_ptr = %d\n\n", int_ptr, &int_ptr, *int_ptr);
17 }
(gdb) break 10 Breakpoint 1 at 0x400544: file pointer.c, line 10. (gdb) b 15 Breakpoint 2 at 0x400586: file pointer.c, line 15.
(gdb) run
Starting program: /home/choi/it432/lec/l10/pointer
Breakpoint 1, main () at pointer.c:10
10 printf(" int_var = %d\n &int_var = %p\n\n", int_var, &int_var);
Note that due the breakpoint we set, the control is paused right before executing line 10.
(gdb) disassemble main (gdb) disass main Dump of assembler code for function main: 0x000000000040052d <+0>: push %rbp 0x000000000040052e <+1>: mov %rsp,%rbp 0x0000000000400531 <+4>: sub $0x10, %rsp 0x0000000000400535 <+8>: movl $0x5,-0xc(%rbp) 0x000000000040053c <+15>: lea -0xc(%rbp),%rax 0x0000000000400540 <+19>: mov %rax,-0x8(%rbp) => 0x0000000000400544 <+23>: mov -0xc(%rbp),%eax 0x0000000000400547 <+26>: lea -0xc(%rbp),%rdx, ... 0x00000000004005be <+145>: leaveq 0x00000000004005bf <+146>: ret End of assembler dump.
(gdb) print int_var $1 = 5 (gdb) p int_ptr $2 = (int *) 0x7fffffffe394We can also look at registers using print command.
(gdb) p $rip $3 = (void (*)()) 0x400544(gdb) p $rsp $4 = (void *) 0x7fffffffe390 (gdb) p $rbp $5 = (void *) 0x7fffffffe3a0
hd address how-much-to-dump-from-the-adddressFor example, starting from $rsp address you can see 40 bytes of memory (i.e., the first 40 bytes of stack from the top) as follows.
(gdb) hd $rsp 40
0x7fffffffe390: 80 E4 FF FF . . . .
0x7fffffffe394: 05 00 00 00 . . . . // int_var is shown in this line
0x7fffffffe398: 94 E3 FF FF . . . . // int_ptr resides here
0x7fffffffe39c: FF 7F 00 00 . . . . // int_ptr (8 bytes in total)
0x7fffffffe3a0: 00 00 00 00 . . . .
0x7fffffffe3a4: 00 00 00 00 . . . .
0x7fffffffe3a8: 45 6F A3 F7 E o . .
0x7fffffffe3ac: FF 7F 00 00 . . . .
0x7fffffffe3b0: 00 00 00 00 . . . .
0x7fffffffe3b4: 00 00 00 00 . . . .
Recall that the stack contains all the local variables of the current function. In particular,
int_var and int_ptr are seen in this dump.
Breakpoint 3, main () at pointer.c:10
10 printf(" int_var = %d\n &int_var = %p\n\n", int_var, &int_var);
(gdb) c
Continuing.
int_var = 5
&int_var = 0x7fffffffe394
int_ptr = 0x7fffffffe394
&int_ptr = 0x7fffffffe398
*int_ptr = 5
Breakpoint 4, main () at pointer.c:15
15 printf(" int_var = %d\n &int_var = %p\n\n", int_var, &int_var);
13 *int_ptr = 10;The aobve statement (line 13) will change the integer object int_ptr points to so as to have value 10. You can check this by inspecting the memory dump below:
(gdb) hd $rsp 40 0x7fffffffe390: 80 E4 FF FF . . . . 0x7fffffffe394: 0A 00 00 00 . . . . 0x7fffffffe398: 94 E3 FF FF . . . . 0x7fffffffe39c: FF 7F 00 00 . . . . 0x7fffffffe3a0: 00 00 00 00 . . . . 0x7fffffffe3a4: 00 00 00 00 . . . . 0x7fffffffe3a8: 45 6F A3 F7 E o . . 0x7fffffffe3ac: FF 7F 00 00 . . . . 0x7fffffffe3b0: 00 00 00 00 . . . . 0x7fffffffe3b4: 00 00 00 00 . . . .
(gdb) c Continuing. int_var = 10 &int_var = 0x7fffffffe394 int_ptr = 0x7fffffffe394 &int_ptr = 0x7fffffffe398 *int_ptr = 10 [Inferior 1 (process 88980) exited with code 0105]
int *int_ptr;
&int_var;
*int_ptr = 10;