143 Linux 系统编程20,stack smashing detected ./main terminated Aborted (core dumped) error 分析和处理

在写前面代码的时候,搞出了个 数组越界的问题,

直接报了*** stack smashing detected ***: ./main terminated
Aborted (core dumped)

这一章就记录在C++中怎么排查这种错误

“Stack smashing detect”

“Stack smashing detect” 是指在程序运行过程中检测到栈溢出的情况。栈溢出是一种常见的安全漏洞,发生在程序尝试往栈空间写入超过其边界范围的数据时。

通常,导致 “Stack smashing detect” 错误的原因可能包括:

  1. 缓冲区溢出:当向一个缓冲区写入超过其分配大小的数据时,会覆盖到相邻的内存地址,导致栈被破坏。
  2. 函数调用错误:函数调用时参数传递错误或者返回值处理不当,可能引起栈结构被破坏。
  3. 格式化字符串漏洞:使用不当的格式化字符串函数(如printf)可能造成栈溢出。
  4. 递归深度过大:如果递归调用层数过多,可能导致栈空间耗尽而触发 stack smashing detect。

为了解决这个问题,可以采取以下措施:

  1. 对于缓冲区操作,请确保输入数据不会超过缓冲区边界,并进行输入验证和长度检查。
  2. 确保正确处理函数调用时传递的参数和返回值。
  3. 避免使用不受信任或未经验证的格式化字符串。
  4. 如果需要使用递归,请确保控制递归深度,并设置适当的终止条件。

总之,”Stack smashing detect” 错误是一个指示栈溢出问题的警告,需要检查代码中可能导致栈溢出的地方并进行修复。

一、Linux开发环境

OS:Ubuntu 16.04.1
编译工具:gcc 5.4.0
调试工具:gdb


二、关键词

栈保护
栈溢出
*** stack smashing detected ***
-fstack-protector
-fno-stack-protector


三、背景

gcc提供栈溢出保护机制,即默认编译时-fstack-protector选项为开。
在该保护机制下,如果程序中有栈溢出,会有以下报错信息,程序异常终止:
*** stack smashing detected ***: ./test terminated
Aborted (core dumped)

若要关闭栈溢出保护,在gcc编译选项中增加-fno-stack-protector即可。
关闭后,如果程序中有栈溢出,仍可能会成功执行完,没有任何报错。
但实际上,栈溢出会导致程序中定义的变量被篡改。

如果你的程序出现上面提到的两种异常:变量被篡改、或者栈溢出导致的异常终止,希望本文会对你有帮助。


四、定位分析


1)第一种情况:变量的值被篡改。


a)源代码(可不看)

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
#include <ctype.h>

int c2i(char ch)
{
	//如果是数字,则用ascii 减去48
	//isdight 判断数字函数
	if(isdigit(ch))
	{
		return ch-48;
	}
	//判断字母
	if(ch<'A'||(ch>'F'&&ch<'a')||ch>'z')
	{
		return -1;
	}
	//大写字母减去55,小写字母减去87
	if(isalpha(ch))
	{
		return isupper(ch)?ch-55:ch-87;
	}
}

int hex2dec(char *hex)
{
	int len, num,temp,bits,i;
	num = 0;
	len = strlen(hex);
	//printf("len = %d\n",len);
	for(i=0,temp=0;i<len;i++,temp=0)
	{
		//printf("hex = %c\n",hex[i]);
		//printf("num = %d\n",num);
		temp = c2i(*(hex+i));
		//printf("temp = %d\n",temp);
		bits = (len-i-1)*4;
		//printf("bits = %d\n",bits);
		temp = temp << bits;
		//printf("temp = %d\n",temp);
		num = num|temp;
	}
	return num;
}

char* itoa(long int num,char *str,int radix)
{
	char index[] = "0123456789ABCDEF";
	long unsigned unum;
	int i=0,j,k;
	if(radix==10&&num<0)
	{
		unum = (unsigned) -num;
		str[i++] = '-';
	}
	else
		unum = (unsigned)num;
	do
	{
		str[i++] = index[unum%(unsigned)radix];
		unum/=radix;
	}while(unum);
	//printf("str = %s\n",str);
	str[i] = '\0';
	if(str[0]=='-')
	{
		k = 1;
	}
	else
		k = 0;
	for(j = k;j<=(i-1)/2;j++)
	{
		char temp;
		temp = str[j];
		str[j] = str[i-1+k-j];
		str[i-1+k-j] = temp;
	}
	//printf("str = %s\n",str);
	return str;
}

/******************************************************
生成command 的chksum函数
*******************************************************/
char *creatChksum(char *Commandinfo,char* chkstr)
{
	int temp = 0;
	int chksum = 0;
	
	for(int i=1;i<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值