An application is generating a core file.
Here is the core info.
The error stack was obtained and the objective is to check the data content within the myStruct variable as this is what gets passed into myFunction when the core occurs.
(gdb) where
#0 0x000000000041bba1 in myFunction (myStruct=0x7ffff9dd0c20) at myTest.c:344
:
:
:
From the above I obtained the address of myStruct at 0x7ffff9dd0c20 and dumped out 200 words.
(gdb) x/200x 0x7ffff9dd0c20
0x7ffff9dd0c20: 0x01938640 0x00000000 0x00001c34 0x000002c8
0x7ffff9dd0c30: 0x00000400 0x00000000 0x01939760 0x00000000
0x7ffff9dd0c40: 0x00000014 0x00000000 0x00000000 0x00000000
0x7ffff9dd0c50: 0x00000000 0x0005000c 0x00000000 0x000d0000
0x7ffff9dd0c60: 0x00000004 0x00000000 0x00000000 0x00000000
0x7ffff9dd0c70: 0x00000000 0x00000000 0x00040000 0x00000000
0x7ffff9dd0c80: 0x0001000c 0x00000000 0x00000000 0x00000000
0x7ffff9dd0c90: 0x00000000 0x00000000 0x00000009 0x00000000
0x7ffff9dd0ca0: 0x00000000 0x00000000 0x410d999a 0x418d999a
0x7ffff9dd0cb0: 0x40b80000 0x41380000 0x000010cc 0x00000000
0x7ffff9dd0cc0: 0x0192edd0 0x00000000 0x00000a30 0x00000158
:
:
:
Now I want to verify I am reading the output of the data correctly.
Here is the structure information .
typedef struct
{
char *a;
unsigned int b;
unsigned int c;
int d;
} structA;
typedef struct
{
structA e;
char *f;
} myStruct; <----------This is what gets passed in and what I am trying to examine.
Working on Linux, a program was run to verify datatype size.
Size of char* : 8
Size of int : 4
Knowing the address is 0x7ffff9dd0c20 and the structure is myStruct, I assume I start with analyzing structA since it is first.
Since char *a is the first part of structA and a char * is 2 words do I look at this :
0x01938640 0x00000000
Next there are essentially 3 ints (2 unsigned int and 1 int) which I viewed as these from the output :
0x00001c34
0x000002c8
0x00000400
This takes me back into structB and to the char *f attribute which should be 2 words.
Does that meaan this this the proper address :
0x00000000 0x01939760
I copied the memory info here again to make it easier to reference.
(gdb) x/200x 0x7ffff9dd0c20
0x7ffff9dd0c20: 0x01938640 0x00000000 0x00001c34 0x000002c8
0x7ffff9dd0c30: 0x00000400 0x00000000 0x01939760 0x00000000
0x7ffff9dd0c40: 0x00000014 0x00000000 0x00000000 0x00000000
0x7ffff9dd0c50: 0x00000000 0x0005000c 0x00000000 0x000d0000
0x7ffff9dd0c60: 0x00000004 0x00000000 0x00000000 0x00000000
0x7ffff9dd0c70: 0x00000000 0x00000000 0x00040000 0x00000000
0x7ffff9dd0c80: 0x0001000c 0x00000000 0x00000000 0x00000000
0x7ffff9dd0c90: 0x00000000 0x00000000 0x00000009 0x00000000
0x7ffff9dd0ca0: 0x00000000 0x00000000 0x410d999a 0x418d999a
0x7ffff9dd0cb0: 0x40b80000 0x41380000 0x000010cc 0x00000000
0x7ffff9dd0cc0: 0x0192edd0 0x00000000 0x00000a30 0x00000158
Is that the proper way to examine and parse out the data?
Here is the definition of one more structure.
typedef struct
{
short w;
unsigned long x;
short y;
short z;
} otherStruct;
This is what is expected to be stored in f.
char *f;
Within gdb, I tried the following :
p (otherStruct *)0x1939760
and it prints out :
$12 = (otherStruct *) 0x1939760
The strange part is when I originally printed out the data, it showed *f as the following which doesn't look anything like the structure :
f = 0x1939760 "\315\314\274@"
You're reading the data the hard way. gdb knows the struct definitions, so you can tell it to print the structure directly using the p
command.
For example, given this code using your structs:
int main()
{
myStruct s = { { "aaa", 4, 5, 6 }, "bbb" };
printf("hello\n");
}
Running the code under gdb:
(gdb) start
Temporary breakpoint 1 at 0x400535: file x1.c, line 19.
Starting program: /home/dbush/./x1
Temporary breakpoint 1, main () at x1.c:19
19 myStruct s = { { "aaa", 4, 5, 6 }, "bbb" };
Missing separate debuginfos, use: debuginfo-install glibc-2.17-292.el7.x86_64
(gdb) step
20 printf("hello\n");
(gdb) p s
$1 = {e = {a = 0x400600 "aaa", b = 4, c = 5, d = 6}, f = 0x400604 "bbb"}
(gdb)
With regard to the field f
actually containing a otherStruct *
, you can print what this contains by casting f
and dereferencing the result:
p *(otherStruct *)myStruct->f
That being said, you failed to take into account padding within the structures. Because structA
contains a char *
which is 8 bytes in size, the stuct must be aligned on an 8 byte boundary. Looking at the layout, this means 4 bytes of padding are at the end of the struct.
So the 6th 32-bit word in your dump (0x00000000) is actually that padding. So the bytes making up f
are actually 0x01939760 0x00000000
.
Looking at the dump of the sample code above:
(gdb) p s
$1 = {e = {a = 0x400600 "aaa", b = 4, c = 5, d = 6}, f = 0x400604 "bbb"}
(gdb) p &s
$5 = (myStruct *) 0x7fffffffde50
(gdb) x/20x 0x7fffffffde50
0x7fffffffde50: 0x00400600 0x00000000 0x00000004 0x00000005
0x7fffffffde60: 0x00000006 0x00007fff 0x00400604 0x00000000
0x7fffffffde70: 0x00000000 0x00000000 0xf7a2f505 0x00007fff
0x7fffffffde80: 0x00000000 0x00000000 0xffffdf58 0x00007fff
0x7fffffffde90: 0x00000000 0x00000001 0x0040052d 0x00000000
You can see that the values in the fields of e
match up with the raw dump.
Next you see the padding bytes which in this case have the value 0x00007fff
. The next 8 bytes after that match the value of f
.
User contributions licensed under CC BY-SA 3.0