《coredump问题原理探究》Linux x86版5.6节C风格数据结构内存布局之复合类型构成的结构体

来源:互联网 发布:阿里云实际应用 编辑:程序博客网 时间:2024/05/20 09:10

由于结构体是不同类型数据结构的集合,那么一个结构体的成员可以是基本数据类型,也可以是另外一个结构体类型。那么复合类型的结构体又有什么特征呢。

先看一个例子:

 #include <stdio.h> struct xuzhina_dump_c05_s3_2_sub {        char a;     short b; };  struct xuzhina_dump_c05_s3_2 {        int c;     long d;     struct xuzhina_dump_c05_s3_2_sub sub; };   int main() {        struct xuzhina_dump_c05_s3_2 test;          scanf( "%c, %hd, %d, %ld", &test.sub.a, &test.sub.b,             &test.c, &test.d );          return test.c + test.d; }

汇编

(gdb) disassemble mainDump of assembler code for function main:   0x08048570 <+0>:     push   %ebp   0x08048571 <+1>:     mov    %esp,%ebp   0x08048573 <+3>:     and    $0xfffffff0,%esp   0x08048576 <+6>:     sub    $0x30,%esp   0x08048579 <+9>:     lea    0x24(%esp),%eax   0x0804857d <+13>:    add    $0x4,%eax   0x08048580 <+16>:    mov    %eax,0x10(%esp)   0x08048584 <+20>:    lea    0x24(%esp),%eax   0x08048588 <+24>:    mov    %eax,0xc(%esp)   0x0804858c <+28>:    lea    0x24(%esp),%eax   0x08048590 <+32>:    add    $0xa,%eax   0x08048593 <+35>:    mov    %eax,0x8(%esp)   0x08048597 <+39>:    lea    0x24(%esp),%eax   0x0804859b <+43>:    add    $0x8,%eax   0x0804859e <+46>:    mov    %eax,0x4(%esp)   0x080485a2 <+50>:    movl   $0x8048664,(%esp)   0x080485a9 <+57>:    call   0x8048440 <scanf@plt>   0x080485ae <+62>:    mov    0x24(%esp),%edx   0x080485b2 <+66>:    mov    0x28(%esp),%eax   0x080485b6 <+70>:    add    %edx,%eax   0x080485b8 <+72>:    jmp    0x80485c2 <main+82>   0x080485ba <+74>:    mov    %eax,(%esp)   0x080485bd <+77>:    call   0x8048460 <_Unwind_Resume@plt>   0x080485c2 <+82>:    leave     0x080485c3 <+83>:    ret    End of assembler dump.

   0x08048597 <+39>:    lea    0x24(%esp),%eax   0x0804859b <+43>:    add    $0x8,%eax   0x0804859e <+46>:    mov    %eax,0x4(%esp)

对test.sub.a的访问,可知,它是直接把test的基地址esp+0x24加上8(c和d的大小总和为8)来访问。

同样对test.sub.b的访问:

   0x0804858c <+28>:    lea    0x24(%esp),%eax   0x08048590 <+32>:    add    $0xa,%eax   0x08048593 <+35>:    mov    %eax,0x8(%esp)

可知,它是直接把test的基地址esp+0x24加上10(0xa)(c和d的大小总和为8,而a是char由于对齐2个字节,所以偏移量为0xa)来访问。

也就是说,对test的成员变量sub的成员访问,完全可以无视sub的存在,不需要再设定sub的基地址。

由上可知,复合结构体和基本数据类型构成的结构体在特征上没什么区别。如果在coredump发现是结构体成员导致,可以通过结构体定义算偏移值来确定是哪个成员出了问题。




原创粉丝点击