Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

core file memory analysis verification

Tags:

c

gdb

coredump

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@"
like image 299
Unhandled Exception Avatar asked Feb 14 '20 19:02

Unhandled Exception


People also ask

How do I analyze my memory files?

This Microsoft-created development tool is the best way to analyze your memory files, but you can also use the older NirSoft BlueScreenView as an alternative, following the steps below. These steps assume your PC is working well enough to install and use WinDbg.

Is Coredump analysis the best practice to find memory leak?

Note: I agree coredump analysis is not best practice to find memory leak. Memory leak can be find with different static and dynamic tools like valgrind etc. I like the Unix way of thinking, but I would have to say that it should be possible to figure out what kinds of allocations are currently active in the core file...

How to evaluate memory leaks in C++?

1 - Memory leaks can be evaluated with a core dump. I have taken a sample c++ example:

How to analyze memory dump files?

These dump files (using the DMP file format) are saved automatically in either the root C: , C:minidump, or C:[&Windows&]minidump folders. To help you analyze them, you can install Microsoft’s debugging app WinDbg from the Microsoft Store. This helps you analyze the memory dump files and locate the stop code information.


1 Answers

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.

like image 182
dbush Avatar answered Oct 05 '22 17:10

dbush