内存损坏问题的示例及分析

原文以示例代码系统的讲述了三种内存损坏的情况: 全局内存、栈损坏及堆损坏, 以及它们产生的原因。粗略整理如下。

Global Memory Corruption

即全局变量的内存使用出了问题,主要还是越界。如下代码:

#include <stdio.h>
#define MAX 6
int arrdata[MAX];
int endval;
int main()
{
   int i = 0;
   endval = 12;
   for (i = MAX; (endval) && (i >= 0) ; i--, endval--)
   {
      arrdata[i] = endval * endval;
   }

   printf("Values are \n");
   for (i = 0; i < MAX; i++)
   {
      printf("\t %d\n", arrdata[i]);
   }
   return 0;
}

编译执行,输出的结果是:

Values are
19044
19321
19600
19881
20164
20449

走查代码,你可以发现第一个循环里i的初值是MAX, 应该是MAX-1。 正是这个越界,改写了endval的值。

那个全局变量在内存里是邻居(译注:在我的Mac OS上的输出结果):

(gdb) p &endval
$2 = (int *) 0x100001038
(gdb) p &arrdata
$3 = (int (*)[6]) 0x100001020

所以arrdat[MAX]的赋值操作,实际变成了对endval的赋值。

这样的破坏操作可以概括为两种:

  • 数组越界,向上或向下(负值).
  • 通过指针访问了错误的地址。

Stack Corruption

在*nix系的系统里,Stack会用来存储局部变量, 函数参数以及返回值。栈损坏常常导致未知的行为及崩溃。

栈损坏有两种情况:

  • 内存越界操作。
  • 栈溢出(stack overflow)。

内存越界

越界的情况和之前相似,只是发生在了栈存储的数据上。比如下面的代码 :

#include <stdio.h>
#include <string.h>
#define LEN 6

void cpyPrint(char *str)
{
   char aBuf[LEN];
   strcpy(aBuf, str);

   printf("String is %s\n", aBuf);
}

int main()
{
   char *aStr = "MyLinux";

   cpyPrint(aStr);

   return 0;
}

编译执行就会崩溃。下面是在我的Mac OS上的结果:

(gdb) r
Starting program: /Volumes/Development/Project/Testing/stackcorrupt
Reading symbols for shared libraries +.............................. done

Program received signal SIGABRT, Aborted.
0x00007fff88815d46 in __kill ()
(gdb) bt
#0  0x00007fff88815d46 in __kill ()
#1  0x00007fff8602d053 in __abort ()
#2  0x00007fff85fee74d in __chk_fail ()
#3  0x00007fff85feea1f in __strcpy_chk ()
#4  0x0000000100000ea6 in cpyPrint (str=0x100000f3e "MyLinux") at stackcorrupt.c:8
#5  0x0000000100000ef3 in main () at stackcorrupt.c:17

原因在cpyPrint函数中的局部变量大小为6,却要放进去8个字符(包括一个结束符)。

栈溢出

下面是栈溢出问题的示例代码:

#include <stdio.h>
int recur(long int var)
{
   if (var > 0)
   {
       recur (var--);
   }

   printf("the var is %ld\n", var);
   return var;
}

int main()
{
   recur (3000);
   return 0;
}

这段代码什么时候崩,还要看在运行的系统里的栈大小的设置,可以使用下面的指令直接查到:

$ulimit -s

默认情况下会是8192 (KBytes)。

Heap Corruption

出现堆错误,会报臭名昭著的Segment Fault错误。产生的原因有三种:

  • 尝试向已经释放的内存写入数据。
  • 越界操作 (的确是最常见的原因)。
  • 尝试向尚未分配的内存写入数据。

下面是一个示例:

#include <stdio.h>
#include <stdlib.h>
int main()
{
   int *pData = NULL;
   int num = 12;
   pData = (int*) malloc (num * sizeof (int));
   //...do stuff use the memory
   free(pData);

   pData[0] = -1;
   pData = (int*) malloc (num * sizeof (int));
   //...do stuff use the memory
   free(pData);
   return 0;
}

要想排查内存问题,首选工具自然是Valgrind了,不多做介绍了。

原因链接: http://mylinuxbook.com/memory-corruption-in-linux-programming/

时间: 2024-10-29 19:09:58

内存损坏问题的示例及分析的相关文章

内存损坏问题的演示样例及分析

原文以演示样例代码系统的讲述了三种内存损坏的情况: 全局内存.栈损坏及堆损坏, 以及它们产生的原因. 粗略整理例如以下. Global Memory Corruption 即全局变量的内存使用出了问题,主要还是越界. 例如以下代码: #include <stdio.h> #define MAX 6 int arrdata[MAX]; int endval; int main() { int i = 0; endval = 12; for (i = MAX; (endval) &&

CVE-2013-3346Adobe Reader和Acrobat 内存损坏漏洞分析

[CNNVD]Adobe Reader和Acrobat 内存损坏漏洞(CNNVD-201308-479) Adobe Reader和Acrobat都是美国奥多比(Adobe)公司的产品.Adobe Reader是一款免费的PDF文件阅读器,Acrobat是一款PDF文件编辑和转换工具.         Adobe Reader和Acrobat中存在安全漏洞.攻击者可利用该漏洞执行任意代码或造成拒绝服务(内存损坏).以下版本受到影响:Adobe Reader和Acrobat 9.5.5之前的9.x

进程内存和内存损坏

本教程的这一部分的先决条件是对ARM汇编的基本了解(在第一个教程系列" ARM汇编基础 "中有介绍).在本章中,您将了解32位Linux环境中进程的内存布局.之后,您将学习堆栈和堆相关的内存损坏的基本原理,以及它们在调试器中的样子. 缓冲区溢出 堆栈溢出 堆溢出 摇摇欲坠的指针 格式字符串 本教程中使用的示例是在ARMv6 32位处理器上编译的.如果您无法访问ARM设备,则可以按照以下教程创建自己的实验室并在VM中模拟Raspberry Pi发行版:使用QEMU模拟Raspberry

Netty中分隔符解码器代码示例与分析

[toc] Netty中分隔符解码器代码示例与分析 通过特别解码器的使用,可以解决Netty中TCP的粘包问题,上一篇<Netty中LineBasedFrameDecoder解码器使用与分析:解决TCP粘包问题>通过行解码器的使用来解决TCP粘包问题,这意味着Netty的服务端和客户端在每次发送请求消息前,都需要在消息的尾部拼接换行符. 除了使用行解码器外,Netty还提供了通用的分隔符解码器,即可以自定义消息的分隔符,那就是DelimiterBasedFrameDecoder分隔符解码器.

【嵌入式开发】裸机引导操作系统和ARM 内存操作 ( DRAM SRAM 类型 简介 | Logical Bank | 内存地址空间介绍 | 内存芯片连接方式 | 内存初始化 | 汇编代码示例 )

[嵌入式开发]ARM 内存操作 ( DRAM SRAM 类型 简介 | Logical Bank | 内存地址空间介绍 | 内存芯片连接方式 | 内存初始化 | 汇编代码示例 ) 一. 内存 简介 1. 两大内存分类 ( 1 ) DRAM 简介 ( 定期刷新 | 速度慢 | 成本低 ) DRAM 简介 : 1.硬件描述 : DRAM 基本由一个个小电容基本原件组成, 电容的两端保留电荷; 2.优缺点描述 : ① 优点 : 成本很低, 很便宜; ② 缺点 : 需要 定期刷新数据, 速度较慢; a.

【玩转微信公众平台之八】 示例代码分析

0.下载安装Opencv,当前版本为249. 1.下载Python,当前OPencv版本为249,不过其支持的最新版本的Python为2.7,所以可以下载276版本. 2.下载numpy,开始我使用了1.6,没有通过,错误如图.下载了最新的1.8.1版本. 3.将Opencv安装目录下opencv\build\python\2.7\x86中的cv2.pyd复制到python安装目录Lib\site-packages下. 4.找到opencv源文件内的draw.py运行. [玩转微信公众平台之八]

(原创)cocos2d-x 3.0 示例代码分析1:AppDelegate

星月最近在用3.0做类似刀塔游戏,第一次用3.0,之前一直只是查查资料,最近发现做一些特定行为需要对3.0一些新的特性了解.所以趁这个机会,把3.0的测试代码过一遍,同时增加注释,希望能对大家有帮助~ 因为项目原因,所以不定期更新~~(小白:借口,继续找借口!) 星月倾心贡献~~~ // AppDelegate.cpp /**************************************************************************** Copyright (

频繁分配释放内存导致的性能问题的分析

频繁分配释放内存导致的性能问题的分析 现象 1 压力测试过程中,发现被测对象性能不够理想,具体表现为: 进程的系统态CPU消耗20,用户态CPU消耗10,系统idle大约70 2 用ps -o majflt,minflt -C program命令查看,发现majflt每秒增量为0,而minflt每秒增量大于10000. 初步分析 majflt代表major fault,中文名叫大错误,minflt代表minor fault,中文名叫小错误. 这两个数值表示一个进程自启动以来所发生的缺页中断的次数

微信公众平台开发(二) 微信公众平台示例代码分析

原文地址:http://www.cnblogs.com/mchina/archive/2013/06/07/3120592.html 一.摘要 微信公众平台提供了一个简单的php示例代码,在做进一步开发之前,我们有必要将其详细了解一下. 二.获取代码 微信官网:http://mp.weixin.qq.com/mpres/htmledition/res/wx_sample.zip 三.分析代码 完整代码如下: <?php /** * wechat php test */ //define your