Discussion:
value of local variable stored in register
Neeraj kushwaha
2008-02-04 04:53:26 UTC
Permalink
Hi All,

I am trying to find the value of local variable stored in register.
But I am getting wrong value from gdb.
Here what i am trying

#include<stdio.h>

int main()
{
int *a=0;
volatile register int b=0xabcd;
register int c=20;
printf("%x\n",b*c);
*a=0;
return 0;
}


------------------------------
-----------------------
GDB info:

Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
#0 0x080483e1 in main () at 1.c:9
9 *a=0;
(gdb) info local
a = (int *) 0x0
b = 43981
c = 11305136
(gdb) info reg
eax 0x0 0
ecx 0x0 0
edx 0xac80b0 11305136
ebx 0xac6ff4 11300852
esp 0xbfc65a00 0xbfc65a00
ebp 0xbfc65a28 0xbfc65a28
esi 0x973ca0 9911456
edi 0x0 0
eip 0x80483e1 0x80483e1 <main+61>
eflags 0x210282 [ SF IF RF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb)


The value of local variable is shown as c = 11305136, but actual value is 20.

How to get the correct value of variables which are stored in register.

Regards
Neeraj
Rohit Arul Raj
2008-02-04 05:28:15 UTC
Permalink
Hi,

1. You are getting segmentation fault because of trying to write to a
invalid memory location (0x0) through pointer a;
2. It is not always true that if u give the storage class specifier as
"Register", a register will be allocated for the local variable. It
always depends on the compiler.
3. It is possible that for arithmetic operations, the compiler may
move your data to register from memory (operation: b*c & your
arithmetic operations does not support memory operands). In that case
u can look at the assembly generated.

Regards,
Rohit
Post by Neeraj kushwaha
Hi All,
I am trying to find the value of local variable stored in register.
But I am getting wrong value from gdb.
Here what i am trying
#include<stdio.h>
int main()
{
int *a=0;
volatile register int b=0xabcd;
register int c=20;
printf("%x\n",b*c);
*a=0;
return 0;
}
------------------------------
-----------------------
Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
#0 0x080483e1 in main () at 1.c:9
9 *a=0;
(gdb) info local
a = (int *) 0x0
b = 43981
c = 11305136
(gdb) info reg
eax 0x0 0
ecx 0x0 0
edx 0xac80b0 11305136
ebx 0xac6ff4 11300852
esp 0xbfc65a00 0xbfc65a00
ebp 0xbfc65a28 0xbfc65a28
esi 0x973ca0 9911456
edi 0x0 0
eip 0x80483e1 0x80483e1 <main+61>
eflags 0x210282 [ SF IF RF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb)
The value of local variable is shown as c = 11305136, but actual value is 20.
How to get the correct value of variables which are stored in register.
Regards
Neeraj
Neeraj kushwaha
2008-02-04 06:39:34 UTC
Permalink
Hi Rohit,

thanks for the reply.

segmentation occurs due to unreferencing null pointer. (this was done
intensionally)
I am running gdb on core dump.

My main intention to get the value of the local variable stored in register.
From the dwarf dump information i can say it was stored in DW_OP_reg2.

Also if for the arithmetic operations, data is moved to register from
memory, but when the printf function returns all the saved register
value should be restored.

this is the dwarf information extracted from a.out

<1>< 276> DW_TAG_subprogram
DW_AT_sibling <341>
DW_AT_external yes(1)
DW_AT_name main
DW_AT_decl_file 1
/home/neeraj/SSG/Release2/gdblocal/2.c
DW_AT_decl_line 5
DW_AT_type <199>
DW_AT_low_pc 0x80483a4
DW_AT_high_pc 0x80483f5
DW_AT_frame_base [
0]<lowpc=0x0><highpc=0x4>DW_OP_breg4+4
[ 1]<lowpc=0x4><highpc=0xa>DW_OP_reg1
[ 2]<lowpc=0xa><highpc=0xb>DW_OP_breg4+4
[ 3]<lowpc=0xb><highpc=0xd>DW_OP_breg4+8
[
4]<lowpc=0xd><highpc=0x51>DW_OP_breg5+8
<2>< 305> DW_TAG_variable
DW_AT_name a
DW_AT_decl_file 1
/home/neeraj/SSG/Release2/gdblocal/2.c
DW_AT_decl_line 6
DW_AT_type <341>
DW_AT_location DW_OP_fbreg -16
<2>< 317> DW_TAG_variable
DW_AT_name b
DW_AT_decl_file 1
/home/neeraj/SSG/Release2/gdblocal/2.c
DW_AT_decl_line 7
DW_AT_type <347>
DW_AT_location DW_OP_fbreg -20
<2>< 329> DW_TAG_variable
DW_AT_name c
DW_AT_decl_file 1
/home/neeraj/SSG/Release2/gdblocal/2.c
DW_AT_decl_line 8
DW_AT_type <199>
DW_AT_location DW_OP_reg2
<1>< 341> DW_TAG_pointer_type
DW_AT_byte_size 4
DW_AT_type <199>
<1>< 347> DW_TAG_volatile_type
DW_AT_type <199>

Regards
Neeraj
Post by Rohit Arul Raj
Hi,
1. You are getting segmentation fault because of trying to write to a
invalid memory location (0x0) through pointer a;
2. It is not always true that if u give the storage class specifier as
"Register", a register will be allocated for the local variable. It
always depends on the compiler.
3. It is possible that for arithmetic operations, the compiler may
move your data to register from memory (operation: b*c & your
arithmetic operations does not support memory operands). In that case
u can look at the assembly generated.
Regards,
Rohit
Post by Neeraj kushwaha
Hi All,
I am trying to find the value of local variable stored in register.
But I am getting wrong value from gdb.
Here what i am trying
#include<stdio.h>
int main()
{
int *a=0;
volatile register int b=0xabcd;
register int c=20;
printf("%x\n",b*c);
*a=0;
return 0;
}
------------------------------
-----------------------
Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
#0 0x080483e1 in main () at 1.c:9
9 *a=0;
(gdb) info local
a = (int *) 0x0
b = 43981
c = 11305136
(gdb) info reg
eax 0x0 0
ecx 0x0 0
edx 0xac80b0 11305136
ebx 0xac6ff4 11300852
esp 0xbfc65a00 0xbfc65a00
ebp 0xbfc65a28 0xbfc65a28
esi 0x973ca0 9911456
edi 0x0 0
eip 0x80483e1 0x80483e1 <main+61>
eflags 0x210282 [ SF IF RF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb)
The value of local variable is shown as c = 11305136, but actual value is 20.
How to get the correct value of variables which are stored in register.
Regards
Neeraj
Rohit Arul Raj
2008-02-04 07:02:47 UTC
Permalink
Hi,

Then, the register value is getting corrupted due to the segmentation fault.
Try to set the break-point before the *a = 0 statement, and try to get
the register info and local variable info.

Regards,
Rohit
Post by Neeraj kushwaha
Hi Rohit,
thanks for the reply.
segmentation occurs due to unreferencing null pointer. (this was done
intensionally)
I am running gdb on core dump.
My main intention to get the value of the local variable stored in register.
From the dwarf dump information i can say it was stored in DW_OP_reg2.
Also if for the arithmetic operations, data is moved to register from
memory, but when the printf function returns all the saved register
value should be restored.
this is the dwarf information extracted from a.out
<1>< 276> DW_TAG_subprogram
DW_AT_sibling <341>
DW_AT_external yes(1)
DW_AT_name main
DW_AT_decl_file 1
/home/neeraj/SSG/Release2/gdblocal/2.c
DW_AT_decl_line 5
DW_AT_type <199>
DW_AT_low_pc 0x80483a4
DW_AT_high_pc 0x80483f5
DW_AT_frame_base [
0]<lowpc=0x0><highpc=0x4>DW_OP_breg4+4
[ 1]<lowpc=0x4><highpc=0xa>DW_OP_reg1
[ 2]<lowpc=0xa><highpc=0xb>DW_OP_breg4+4
[ 3]<lowpc=0xb><highpc=0xd>DW_OP_breg4+8
[
4]<lowpc=0xd><highpc=0x51>DW_OP_breg5+8
<2>< 305> DW_TAG_variable
DW_AT_name a
DW_AT_decl_file 1
/home/neeraj/SSG/Release2/gdblocal/2.c
DW_AT_decl_line 6
DW_AT_type <341>
DW_AT_location DW_OP_fbreg -16
<2>< 317> DW_TAG_variable
DW_AT_name b
DW_AT_decl_file 1
/home/neeraj/SSG/Release2/gdblocal/2.c
DW_AT_decl_line 7
DW_AT_type <347>
DW_AT_location DW_OP_fbreg -20
<2>< 329> DW_TAG_variable
DW_AT_name c
DW_AT_decl_file 1
/home/neeraj/SSG/Release2/gdblocal/2.c
DW_AT_decl_line 8
DW_AT_type <199>
DW_AT_location DW_OP_reg2
<1>< 341> DW_TAG_pointer_type
DW_AT_byte_size 4
DW_AT_type <199>
<1>< 347> DW_TAG_volatile_type
DW_AT_type <199>
Regards
Neeraj
Post by Rohit Arul Raj
Hi,
1. You are getting segmentation fault because of trying to write to a
invalid memory location (0x0) through pointer a;
2. It is not always true that if u give the storage class specifier as
"Register", a register will be allocated for the local variable. It
always depends on the compiler.
3. It is possible that for arithmetic operations, the compiler may
move your data to register from memory (operation: b*c & your
arithmetic operations does not support memory operands). In that case
u can look at the assembly generated.
Regards,
Rohit
Post by Neeraj kushwaha
Hi All,
I am trying to find the value of local variable stored in register.
But I am getting wrong value from gdb.
Here what i am trying
#include<stdio.h>
int main()
{
int *a=0;
volatile register int b=0xabcd;
register int c=20;
printf("%x\n",b*c);
*a=0;
return 0;
}
------------------------------
-----------------------
Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
#0 0x080483e1 in main () at 1.c:9
9 *a=0;
(gdb) info local
a = (int *) 0x0
b = 43981
c = 11305136
(gdb) info reg
eax 0x0 0
ecx 0x0 0
edx 0xac80b0 11305136
ebx 0xac6ff4 11300852
esp 0xbfc65a00 0xbfc65a00
ebp 0xbfc65a28 0xbfc65a28
esi 0x973ca0 9911456
edi 0x0 0
eip 0x80483e1 0x80483e1 <main+61>
eflags 0x210282 [ SF IF RF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb)
The value of local variable is shown as c = 11305136, but actual value is 20.
How to get the correct value of variables which are stored in register.
Regards
Neeraj
Rohit Arul Raj
2008-02-04 07:42:24 UTC
Permalink
Hi,

Since the live range of value 'c' is dead after printf, the compiler
may be discarding it.
Try to use something like b = c + 200; after printf statement, so that
we extend the live range of variable 'c'.

Regards,
Rohit
Post by Rohit Arul Raj
Hi,
Then, the register value is getting corrupted due to the segmentation fault.
Try to set the break-point before the *a = 0 statement, and try to get
the register info and local variable info.
Regards,
Rohit
Post by Neeraj kushwaha
Hi Rohit,
thanks for the reply.
segmentation occurs due to unreferencing null pointer. (this was done
intensionally)
I am running gdb on core dump.
My main intention to get the value of the local variable stored in register.
From the dwarf dump information i can say it was stored in DW_OP_reg2.
Also if for the arithmetic operations, data is moved to register from
memory, but when the printf function returns all the saved register
value should be restored.
this is the dwarf information extracted from a.out
<1>< 276> DW_TAG_subprogram
DW_AT_sibling <341>
DW_AT_external yes(1)
DW_AT_name main
DW_AT_decl_file 1
/home/neeraj/SSG/Release2/gdblocal/2.c
DW_AT_decl_line 5
DW_AT_type <199>
DW_AT_low_pc 0x80483a4
DW_AT_high_pc 0x80483f5
DW_AT_frame_base [
0]<lowpc=0x0><highpc=0x4>DW_OP_breg4+4
[ 1]<lowpc=0x4><highpc=0xa>DW_OP_reg1
[ 2]<lowpc=0xa><highpc=0xb>DW_OP_breg4+4
[ 3]<lowpc=0xb><highpc=0xd>DW_OP_breg4+8
[
4]<lowpc=0xd><highpc=0x51>DW_OP_breg5+8
<2>< 305> DW_TAG_variable
DW_AT_name a
DW_AT_decl_file 1
/home/neeraj/SSG/Release2/gdblocal/2.c
DW_AT_decl_line 6
DW_AT_type <341>
DW_AT_location DW_OP_fbreg -16
<2>< 317> DW_TAG_variable
DW_AT_name b
DW_AT_decl_file 1
/home/neeraj/SSG/Release2/gdblocal/2.c
DW_AT_decl_line 7
DW_AT_type <347>
DW_AT_location DW_OP_fbreg -20
<2>< 329> DW_TAG_variable
DW_AT_name c
DW_AT_decl_file 1
/home/neeraj/SSG/Release2/gdblocal/2.c
DW_AT_decl_line 8
DW_AT_type <199>
DW_AT_location DW_OP_reg2
<1>< 341> DW_TAG_pointer_type
DW_AT_byte_size 4
DW_AT_type <199>
<1>< 347> DW_TAG_volatile_type
DW_AT_type <199>
Regards
Neeraj
Post by Rohit Arul Raj
Hi,
1. You are getting segmentation fault because of trying to write to a
invalid memory location (0x0) through pointer a;
2. It is not always true that if u give the storage class specifier as
"Register", a register will be allocated for the local variable. It
always depends on the compiler.
3. It is possible that for arithmetic operations, the compiler may
move your data to register from memory (operation: b*c & your
arithmetic operations does not support memory operands). In that case
u can look at the assembly generated.
Regards,
Rohit
Post by Neeraj kushwaha
Hi All,
I am trying to find the value of local variable stored in register.
But I am getting wrong value from gdb.
Here what i am trying
#include<stdio.h>
int main()
{
int *a=0;
volatile register int b=0xabcd;
register int c=20;
printf("%x\n",b*c);
*a=0;
return 0;
}
------------------------------
-----------------------
Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
#0 0x080483e1 in main () at 1.c:9
9 *a=0;
(gdb) info local
a = (int *) 0x0
b = 43981
c = 11305136
(gdb) info reg
eax 0x0 0
ecx 0x0 0
edx 0xac80b0 11305136
ebx 0xac6ff4 11300852
esp 0xbfc65a00 0xbfc65a00
ebp 0xbfc65a28 0xbfc65a28
esi 0x973ca0 9911456
edi 0x0 0
eip 0x80483e1 0x80483e1 <main+61>
eflags 0x210282 [ SF IF RF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb)
The value of local variable is shown as c = 11305136, but actual value is 20.
How to get the correct value of variables which are stored in register.
Regards
Neeraj
Eli Zaretskii
2008-02-04 20:31:31 UTC
Permalink
Date: Mon, 4 Feb 2008 10:23:26 +0530
The value of local variable is shown as c = 11305136, but actual value is 20.
How to get the correct value of variables which are stored in register.
(gdb) info address c

This will show where the variable c is stored. If it says it's in a
register, print the value of that register.
Jim Blandy
2008-02-05 19:42:32 UTC
Permalink
Post by Eli Zaretskii
(gdb) info address c
This will show where the variable c is stored. If it says it's in a
register, print the value of that register.
The output of 'info address' isn't very helpful if c has a non-trivial
DWARF location expression. I've been intending to fix this for quite
some time now, but have never gotten around to it. :(
Eli Zaretskii
2008-02-05 20:35:16 UTC
Permalink
Date: Tue, 5 Feb 2008 11:42:32 -0800
Post by Eli Zaretskii
(gdb) info address c
This will show where the variable c is stored. If it says it's in a
register, print the value of that register.
The output of 'info address' isn't very helpful if c has a non-trivial
DWARF location expression.
Can you show an example?

Also, is this problem relevant to the case in point (the OP presented
a test program)?
Jim Blandy
2008-02-06 00:26:46 UTC
Permalink
Post by Eli Zaretskii
Post by Jim Blandy
The output of 'info address' isn't very helpful if c has a non-trivial
DWARF location expression.
Can you show an example?
Also, is this problem relevant to the case in point (the OP presented
a test program)?
Even simple programs can have this trouble. In the example below, GDB
can't print the address of parameter 'x', even though its home is a
fixed offset from the base address of the frame.

$ cat recur.c
#include <stdio.h>

int
recur (int x)
{
if (x > 0)
return 2 * recur (x - 2);
else
return 1;
}

int
main (int argc, char **argv)
{
printf ("%d\n", recur (7));
}
$ gcc -g recur.c -o recur
$ ~/gdb/pub/nat/gdb/gdb recur
GNU gdb 6.7.50.20080111-cvs
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
(gdb) break recur
Breakpoint 1 at 0x804838a: file recur.c, line 6.
(gdb) run
Starting program: /home/jimb/play/recur

Breakpoint 1, recur (x=7) at recur.c:6
6 if (x > 0)
(gdb) info address x
Symbol "x" is a variable with complex or multiple locations (DWARF2).
(gdb) shell readelf -wi recur
The section .debug_info contains:

Compilation Unit @ offset 0x0:
Length: 369
Version: 2
Abbrev Offset: 0
Pointer Size: 4
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
DW_AT_stmt_list : 0
DW_AT_high_pc : 0x80483e7
DW_AT_low_pc : 0x8048384
DW_AT_producer : GNU C 4.1.2 20070626 (Red Hat 4.1.2-13)
DW_AT_language : 1 (ANSI C)
DW_AT_name : recur.c
DW_AT_comp_dir : /home/jimb/play
...
<1><10b>: Abbrev Number: 5 (DW_TAG_subprogram)
DW_AT_sibling : <137>
DW_AT_external : 1
DW_AT_name : recur
DW_AT_decl_file : 1
DW_AT_decl_line : 5
DW_AT_prototyped : 1
DW_AT_type : <b8>
DW_AT_low_pc : 0x8048384
DW_AT_high_pc : 0x80483b1
DW_AT_frame_base : 0 (location list)
<2><12a>: Abbrev Number: 6 (DW_TAG_formal_parameter)
DW_AT_name : x
DW_AT_decl_file : 1
DW_AT_decl_line : 4
DW_AT_type : <b8>
DW_AT_location : 2 byte block: 91 0 (DW_OP_fbreg: 0)
...
(gdb)
Eli Zaretskii
2008-02-06 04:17:45 UTC
Permalink
Date: Tue, 5 Feb 2008 16:26:46 -0800
(gdb) info address x
Symbol "x" is a variable with complex or multiple locations (DWARF2).
That's a bad misfeature. How about displaying all the possible
locations, if we cannot say which one is used at the time the command
is issued?
Jim Blandy
2008-02-06 06:26:10 UTC
Permalink
Post by Eli Zaretskii
Post by Jim Blandy
(gdb) info address x
Symbol "x" is a variable with complex or multiple locations (DWARF2).
That's a bad misfeature. How about displaying all the possible
locations, if we cannot say which one is used at the time the command
is issued?
I agree. Yes, that's reasonable. It entails filling in
loclist_describe_location and locexpr_describe_location.

Loading...