你的C/C++程序为什么无法运行?揭秘Segmentation fault (2)
什么让你对C/C++如此恐惧?
本篇将继续上一篇来讨论段错误(Segmentation fault)。
上一篇:
你的C/C++程序为什么无法运行?揭秘Segmentation fault(1)
追溯段错误
如果你觉得你已经理解了段错误的根源,也知道了如何防止段错误,那么可以到此为止。否则,下面的内容或许对你有所启发。
malloc
我们开始为指针所指向的地址分配内存:
注意,(*dest) = (char*)malloc(sizeof(char)*n);
的右边已经执行,但尚未将分配出的地址赋给指针*dest
。
接下来,我们的主角段错误的前夕:
上面的图告诉我们一些信息:
红线勾勒出的内容是:
从函数func1
的局部变量中取出指针dest(char ** 型)
指向的地址,正确的代码中地址是0x7fffffffddc0
,而错误的代码中地址则是0x0
.
下一步即将执行黄线勾勒出的内容
/*
注意这里的rax在错误的代码中为0x0
而rdx的值为malloc出的内存地址0x602010
*/
mov QWORD PTR [rax],rdx
那么,当执行上面的代码时,错误的代码试图将malloc分配出的在堆上的内存地址当作值放在指针dest
指向的地址中。
地址:0x0 值:0x602010
那么就出现了上篇所说的,0x0
是不能被访问的地址,也就不可能完成赋值操作。所以就会出现段错误:
什么是段错误
对于很多人来讲。上面的分析比第一篇要深入一些,也许看得到真相前的每一步才能让人踏实。
现在,我们来看看什么是段错误。
下图是一个进程地址空间的描述,这是一个旧图,网上到处都是,但可以用来理解VMA:
上面这幅图会告诉我们什么呢?
内核虚拟内存空间,你肯定访问不了.
用户栈,用户进程启动就会有这样一个结构,你超过它的上界就到了内核虚拟内存空间,就会出现段错误.
内存映射mmp区域.
堆,malloc、calloc就在这里找地址分配.(事实上不仅如此)
代码、数据段 包括全局变量、静态变量、代码、数据等等.
如果你访问了内核虚拟内存空间(就是比ebp大的空间,1都不行)、代码段、数据段都会引发段错误。
在上篇的例子中,是由于访问了图中红色圈出的保留区域造成的段错误。
补充一下x86_64的VMA-layout:
。
找到代码中的段错误
方法有很多。我也只会1个,毕竟我不写C/C++,更不是这方面的老手。
利用coredump+gdb来做。
获取coredump的方法:
1.在shell中`ulimit -c unlimited`
2.运行你发生了段错误的程序
有了coredump,就可以拿gdb来掰掰了gdb xx xxcoredump
.
上图有几个信息:
1.signal 11,是什么呢?
![]()
2.Segmentation fualt 段错误
3.stack2.c
中的第8行出现错误.
4.细心观察还会看到函数func1
的参数dest=0x0
.
我想,对于这样一个简单的c程序,上面的信息足够了.
其它
也许后面还想看看mmap、mm的fault处理、页异常处理还有signal的一些东西.
但本篇,就此结束.
你的C/C++程序为什么无法运行?揭秘Segmentation fault (2)的更多相关文章
- 你的C/C++程序为什么无法运行?揭秘Segmentation fault (1)
什么让你对C/C++如此恐惧? 晦涩的语法?还是优秀IDE的欠缺? 我想那都不是问题,最多的可能是一个类似这样的错误: 段错误(Segmentation fault) 这是新手无法避免的错误,也是老手 ...
- 你的java/c/c++程序崩溃了?揭秘段错误(Segmentation fault)(3)
前言 接上两篇: 你的C/C++程序为什么无法运行?揭秘Segmentation fault (1) 你的C/C++程序为什么无法运行?揭秘Segmentation fault (2) 写到这里,越跟 ...
- C#如何防止程序多次运行的技巧
一.使用互斥量Mutex弄懂了主要的实现思路之后,下面看代码实现就完全不是问题了,使用互斥量的实现就是第四点的思路的体现,我们用为该程序进程创建一个互斥量Mutex对象变量,当运行该程序时,该程序进程 ...
- iOS开发小技巧--iOS程序进入后台运行的实现
iOS程序进入后台运行的实现 视频中看到老师用的iOS7,代码中有开启timer,无限请求数据的功能,但是切换到后台,代码就不打印了 自己用的iOS9,进入后台还是可以打印的,再次进入前台也可以正常运 ...
- 配置ASP.NET Web应用程序, 使之运行在medium trust
这文章会向你展示, 怎么配置ASP.NET Web应用程序, 使之运行在medium trust. 如果你的服务器有多个应用程序, 你可以使用code access security和medium ...
- WPF 设置程序开机自动运行(+注册表项)
#region 设置程序开机自动运行(+注册表项) RegistryKey rgkRun = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Micr ...
- 【转】delphi程序只允许运行一个实例的三种方法:
一. 创建互斥对象 在工程project1.dpr中创建互斥对象 Program project1 Uses Windows,Form, FrmMain in 'FrmMain.pas' ...
- inno安装卸载时检测程序是否正在运行卸载完成后自动打开网页-代码无效
inno安装卸载时检测程序是否正在运行卸载完成后自动打开网页-代码无效 inno setup 安装卸载时检测程序是佛正在运行卸载完成后自动打开网页-代码无效 --------------------- ...
- .NET概念:.NET程序编译和运行
.NET概念:.NET程序编译和运行 分类: c#程序设计 2012-02-29 15:46 3001人阅读 评论(2) 收藏 举报 .net编译器语言microsoftassemblyvb.net ...
随机推荐
- Python爬虫---requests库快速上手
一.requests库简介 requests是Python的一个HTTP相关的库 requests安装: pip install requests 二.GET请求 import requests # ...
- python中set
集合update方法:是把要传入的元素拆分,做为个体传入到集合中,例如: >>> a = set('boy') >>> a.update('python') > ...
- TCP包服务器接受程序
//功能:客户端发送TCP包,此程序接受到,将字母转换为大写,在发送到客户端#include <stdio.h>#include <sys/socket.h>#include ...
- css同时满足两个类名才有效果的写法
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...
- SQlserver创建函数实现只取某个字段的数字部分
create FUNCTION [dbo].[GET_NUMBER](@S VARCHAR(100)) RETURNS VARCHAR(100) AS BEGIN WHILE PATINDEX('%[ ...
- Python获取指定文件夹下的文件名
本文采用os.walk()和os.listdir()两种方法,获取指定文件夹下的文件名. 一.os.walk() 模块os中的walk()函数可以遍历文件夹下所有的文件. os.walk(top, t ...
- day5模块学习 -- os模块学习
python基础之模块之os模块 os模块 os模块的作用: os,语义为操作系统,所以肯定就是操作系统相关的功能了,可以处理文件和目录这些我们日常手动需要做的操作,就比如说:显示当前目录下所有文件/ ...
- Cannot read property ‘msie’ of undefined错误原因以及解决方案
最近把一个项目的jQuery升级到最新版,发现有些页面报错Cannot read property ‘msie’ of undefined.上jQuery网站上搜了一下,$.browser这个api从 ...
- 基于Json.NET自己实现MVC中的JsonValueProviderFactory
写了博文ASP.NET MVC 3升级至MVC 5.1的遭遇:“已添加了具有相同键的项”之后,继续看着System.Web.Mvc.JsonValueProviderFactory的开源代码. 越看越 ...
- ODBC在注册表中的位置
增加一个oracle的odbc regedit打开注册表 64位 :HKEY_LOCAL_MACHINE -> SOFTWARE -> 32位: HKEY_LOCAL_MACHINE -& ...