前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《coredump问题原理探究》Linux x86版5.6节C风格数据结构内存布局之复合类型构成的结构体

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

作者头像
血狼debugeeker
发布2018-09-20 14:38:20
5770
发布2018-09-20 14:38:20
举报
文章被收录于专栏:debugeeker的专栏

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1344508

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

先看一个例子:

代码语言:javascript
复制
 #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;
 }

汇编

代码语言:javascript
复制
(gdb) disassemble main
Dump 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.

代码语言:javascript
复制
   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的访问:

代码语言:javascript
复制
   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发现是结构体成员导致,可以通过结构体定义算偏移值来确定是哪个成员出了问题。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2013年04月16日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档