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

《coredump问题原理探究》Linux x86版5.9节C风格数据结构内存布局之联合体

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

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

在C语言中,联合体(union)有点像结构体那样,把不同类型的数据组织起来,但和结构体不大一样,在结构体各成员有各自的内存空间,一个结构体对象的总长度是各成员长度之和。而在联合体中,各成员共享一段内存空间,一个联合体对象的长度等于各成员中最长的长度。

由上面描述可知,联合体应该具备多面性,即在汇编层面上,有时候会显示结构体的特征,或数组特征,或其它基本数据类型特征。

先看一下例子:

代码语言:javascript
复制
1	 #include <stdio.h>
  2	 union xuzhina_dump_c05_s4
  3	 {
  4	     int i;
  5	     char hello[4];
  6	 };
  7 
  8	 int main()
  9	 {
 10	     union xuzhina_dump_c05_s4 test;
 11	     test.i = 0x656463;
 12	     for ( int i = 0; i < 4; i++ )
 13	     {
 14	         printf( "%c", test.hello[i] );
 15	     }
 16	 
 17	     printf( "\n" );
 18	     return 0;
 19	 }

汇编代码:

代码语言: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    $0x20,%esp
   0x08048579 <+9>:     movl   $0x656463,0x18(%esp)
   0x08048581 <+17>:    movl   $0x0,0x1c(%esp)
   0x08048589 <+25>:    jmp    0x80485a8 <main+56>
   0x0804858b <+27>:    lea    0x18(%esp),%edx
   0x0804858f <+31>:    mov    0x1c(%esp),%eax
   0x08048593 <+35>:    add    %edx,%eax
   0x08048595 <+37>:    movzbl (%eax),%eax
   0x08048598 <+40>:    movsbl %al,%eax
   0x0804859b <+43>:    mov    %eax,(%esp)
   0x0804859e <+46>:    call   0x8048430 <putchar@plt>
   0x080485a3 <+51>:    addl   $0x1,0x1c(%esp)
   0x080485a8 <+56>:    cmpl   $0x3,0x1c(%esp)
   0x080485ad <+61>:    setle  %al
   0x080485b0 <+64>:    test   %al,%al
   0x080485b2 <+66>:    jne    0x804858b <main+27>
   0x080485b4 <+68>:    movl   $0xa,(%esp)
   0x080485bb <+75>:    call   0x8048430 <putchar@plt>
   0x080485c0 <+80>:    mov    $0x0,%eax
   0x080485c5 <+85>:    jmp    0x80485cf <main+95>
   0x080485c7 <+87>:    mov    %eax,(%esp)
   0x080485ca <+90>:    call   0x8048460 <_Unwind_Resume@plt>
   0x080485cf <+95>:    leave  
   0x080485d0 <+96>:    ret    
End of assembler dump.

从上面汇编代码来看,unionxuzhina_dump_c05_s4确实以int和char数组进行访问。见下面这两组指令

代码语言:javascript
复制
   0x08048579 <+9>:     movl   $0x656463,0x18(%esp)

   0x0804858b <+27>:    lea    0x18(%esp),%edx
   0x0804858f <+31>:    mov    0x1c(%esp),%eax
   0x08048593 <+35>:    add    %edx,%eax
   0x08048595 <+37>:    movzbl (%eax),%eax

由上面的探讨,union成员类型最好避免是指针类型。因为指针容易被覆盖,会发生“Accessviolation”的错误。假设指针是函数指针,则会出现上一节的coredump。

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

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

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

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

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