Linux下segment fault的调试

合集下载

Linux下的段错误(Segmentationfault)产生的原因及调试方法(经典)

Linux下的段错误(Segmentationfault)产生的原因及调试方法(经典)

Linux下的段错误(Segmentation fault )产生的原因及调试方法(经典)2009-04-05 11:25简而言之,产生段错误就是访问了错误的内存段,一般是你没有权限,或者根本就不存在对应的物理内存,尤其常见的是访问0地址.一般来说,段错误就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gdtr来保存的,他是一个48位的寄存器,其中的32位是保存由它指向的gdt表,后13位保存相应于gdt的下标,最后3位包括了程序是否在内存中以及程序的在cpu中的运行级别,指向的gdt是由以64位为一个单位的表,在这张表中就保存着程序运行的代码段以及数据段的起始地址以及与此相应的段限和页面交换还有程序运行级别还有内存粒度等等的信息。

一旦一个程序发生了越界访问,cpu就会产生相应的异常保护,于是segmentation fault就出现了•在编程中以下几类做法容易导致段错误,基本是是错误地使用指针引起的1)访问系统数据区,尤其是往系统保护的内存地址写数据最常见就是给一个指针以0地址2)内存越界(数组越界,变量类型不一致等)访问到不属于你的内存区域解决方法我们在用C/C++语言写程序的时侯,内存管理的绝大部分工作都是需要我们来做的。

实际上,内存管理是一个比较繁琐的工作,无论你多高明,经验多丰富,难免会在此处犯些小错误,而通常这些错误又是那么的浅显而易于消除。

但是手工除虫”(debug),往往是效率低下且让人厌烦的,本文将就”段错误”这个内存访问越界的错误谈谈如何快速定位这些"段错误”的语句。

下面将就以下的一个存在段错误的程序介绍几种调试方法:1 dummy_function (void)2 {3 unsigned char *ptr = 0x00;4 *ptr = 0x00;5 }67 int main (void)8 {9 dummy_function ();1011 return 0;12 }作为一个熟练的C/C++程序员,以上代码的bug应该是很清楚的,因为它尝试操作地址为0 的内存区域,而这个内存区域通常是不可访问的禁区,当然就会出错了。

SegmentationFault错误原因总结

SegmentationFault错误原因总结

SegmentationFault错误原因总结 最近在项⽬上遇到了Segmentation Fault的错误,⼀直调试不出来是哪⾥出了问题,对于刚接触嵌⼊式的,也不知道该如何去调试⼀个项⽬,定位内存问题,纠结了好⼏天,好阿红整理下⾃⼰的思路。

从头开始。

以下内容只为整理来⾃⼰使⽤的,⼤多来源于⽹络,感谢⼤家的分享:⼀、什么是“Segmentation fault in Linux”A segmentation fault (often shortened to SIGSEGV) is a particular error condition that can occur during the operation of computer software. A segmentation fault occurs when a program attempts to access a memory location that it is not allowed to access, or attempts to access a memory location in a way that is not allowed (for example, attempting to write to a read-only location, or to overwrite part of the operating system).Segmentation is one approach to memory management and protection in the operating system. It has been superseded by paging for most purposes, but much of the terminology of segmentation is still used, "segmentation fault" being an example. Some operating systems still have segmentation at some logical level although paging is used as the main memory management policy.On Unix-like operating systems, a process that accesses an invalid memory address receives the SIGSEGV signal. On Microsoft Windows, a process that accesses invalid memory receives the STATUS_ACCESS_VIOLATION exception.就是:所谓的段错误就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gdtr来保存的,他是⼀个48位的寄存器,其中的32位是保存由它指向的gdt表,后13位保存相应于gdt的下标,最后3位包括了程序是否在内存中以及程序的在cpu中的运⾏级别,指向的gdt是由以64位为⼀个单位的表,在这张表中就保存着程序运⾏的代码段以及数据段的起始地址以及与此相应的段限和页⾯交换还有程序运⾏级别还有内存粒度等等的信息。

段错误总结

段错误总结

(版权声明:本文欢迎转载,但未经允许不得用于商业目的)
2
Segmentation Fault in Linux
内容提要
本文简单介绍了 Segmentation fault 发生的原因, 结合实 际例子描述了内核向用户态程序发送 SIGSEGV 信号的流 程。 文中以实例回答了常见的一些 SIGSEGV 问 题 ,例如“为 什么函数返回了栈还可以访问?”、“为什么 free()后的内存 仍然 可以使用 ”、“为什 么我遇到的是 SIGSEGV 而不 是 SIGILL 信号”等。最后笔者结合自己的经验,列举了一些预 防 SIGSEGV 的编程习惯,供大家参考。SIGSEGV 严格依赖 操作系统、编译器、硬件平台,本文基于 Linux、GCC、32bit IA32 架构,但对其他平台操作系统也有借鉴意义。
我们引用 wiki 上的一段话来回答这个问题。
A segmentation fault (often shortened to SIGSEGV) is a particular error condition that can occur during the operation of computer software. A segmentation fault occurs when a program attempts to access a memory location that it is not allowed to access, or attempts to access a memory location in a way that is not allowed (for example, attempting to write to a read-only location, or to overwrite part of the operating system). Segmentation is one approach to memory management and protection in the operating system. It has been superseded by paging for most purposes, but much of the terminology of segmentation is still used, "segmentation fault" being an example. Some operating systems still have segmentation at some logical level although paging is used as the main memory management policy. On Unix-like operating systems, a process that accesses an invalid memory address receives the SIGSEGV signal. On Microsoft Windows, a process that accesses invalid memory receives the STATUS_ACCESS_VIOLATION exception.

Linux命令行中的进程调试和错误排查技巧

Linux命令行中的进程调试和错误排查技巧

Linux命令行中的进程调试和错误排查技巧在Linux系统中,进程调试和错误排查是开发者和系统管理员必备的技能之一。

通过命令行界面,可以使用一系列工具和技巧来定位和解决进程中的错误和问题。

本文将介绍一些常用的Linux命令行中的进程调试和错误排查技巧,帮助读者快速定位和修复问题。

1. 进程的状态查看与管理在Linux系统中,可以通过以下命令查看和管理进程的状态:- `ps`:显示当前运行的进程列表。

可以使用`ps aux`命令查看所有进程的详细信息,包括PID(进程ID)、CPU使用率、内存占用等。

- `top`:实时动态显示进程列表和系统资源的使用情况。

按键盘上的`q`退出。

- `kill`:终止一个正在运行的进程。

使用`kill PID`命令,其中PID 是要终止的进程的ID。

- `killall`:终止指定进程名对应的所有进程。

使用`killallprocess_name`命令,其中process_name是要终止的进程名。

2. 进程的跟踪与调试当进程发生错误或异常时,可以使用以下命令进行跟踪和调试:- `strace`:跟踪系统调用和信号的发生情况。

使用`strace -p PID`命令,其中PID是要跟踪的进程ID。

- `gdb`:GNU调试器,可以对正在运行的进程进行调试。

使用`gdb -p PID`命令,其中PID是要调试的进程ID。

3. 日志分析与查看Linux系统中的日志文件记录了系统和各个进程的运行状态和错误信息。

以下是一些常用的日志文件和查看命令:- `/var/log/messages`:包含系统运行过程中的大量信息。

使用`tail -f /var/log/messages`命令实时查看该文件的最新内容。

- `/var/log/syslog`:包含系统日志信息,包括内核和其他系统组件的消息。

使用`tail -f /var/log/syslog`命令实时查看该文件的最新内容。

使用Linux终端进行进程调试和故障排除

使用Linux终端进行进程调试和故障排除

使用Linux终端进行进程调试和故障排除进程调试是软件开发和故障排除过程中非常重要的一部分。

在Linux操作系统中,使用终端进行进程调试和故障排除可以提供强大的工具和功能。

本文将介绍如何使用Linux终端进行进程调试和故障排除的步骤和技巧。

一、检查进程状态在进行调试和故障排除之前,我们首先需要检查进程的状态。

我们可以使用Linux终端的一些命令来查看当前运行的进程列表,以及它们的状态和资源使用情况。

1. ps命令ps命令是一个常用的用于显示当前运行进程的命令。

通过在终端中输入下面的命令,可以列出当前运行的进程列表:```ps aux```该命令将显示包括进程ID、父进程ID、CPU使用率、内存使用率等在内的详细信息。

2. top命令top命令是一个交互式的实时进程监视器,它可以显示当前运行的进程和它们的资源使用情况。

在终端中输入下面的命令,可以打开top命令的界面:```top```top命令将显示进程的CPU使用率、内存使用率、进程ID等信息,并按照CPU使用率的高低进行排序。

二、跟踪进程在进行进程调试和故障排除时,我们可能需要跟踪进程的执行情况,以便找到问题所在。

Linux终端提供了一些工具,可以用来跟踪进程的执行和输出。

1. strace命令strace命令可以用于跟踪进程的系统调用和信号。

通过在终端中输入下面的命令,可以跟踪一个进程的执行情况:```strace -p <进程ID>```该命令将显示进程执行时的系统调用和信号。

ltrace命令可以用于跟踪进程的库函数调用。

通过在终端中输入下面的命令,可以跟踪一个进程的库函数调用:```ltrace -p <进程ID>```该命令将显示进程执行时的库函数调用。

三、调试进程在进行进程调试时,我们可能需要在程序中设置断点,以便在特定位置暂停执行,并检查程序的状态和变量值。

Linux终端提供了一些调试工具,可以用来调试进程。

sefmentation fault 生成 dmp linux -回复

sefmentation fault 生成 dmp linux -回复

sefmentation fault 生成dmp linux -回复标题:解决Linux 中的段错误(Segmentation Fault)并生成转储文件(dmp)引言:在Linux 系统中,段错误(Segmentation Fault)是一种常见的错误类型。

当程序试图访问无效的内存地址或者发生内存访问冲突时,系统将发送一个SIGSEGV 信号,导致程序终止运行。

为了更好地解决段错误问题并进行调试分析,本文将一步一步回答如何生成dmp(转储)文件来捕获程序崩溃时的调试信息。

正文:Step 1:编译程序并添加调试信息在解决段错误问题之前,首先需要为程序添加调试信息。

在编译时,使用-g 选项将调试符号包含到可执行文件中,例如:gcc -g program.c -o programStep 2:运行程序并捕获段错误运行程序时,需要使用ulimit 命令设置core dump 文件的最大大小,以便生成转储文件。

使用以下命令将core dump 文件的最大大小设置为无限:ulimit -c unlimited然后运行程序:./program当程序由于段错误而终止时,系统将生成一个名为core 的转储文件。

Step 3:使用gdb 进行调试使用gdb 工具可以方便地分析生成的转储文件。

首先,运行以下命令以启动gdb 调试器,并加载转储文件和可执行文件:gdb -c core ./program然后,使用bt 命令查看段错误发生时的函数调用栈信息,以确定导致段错误的位置:(gdb) btbt 命令会显示导致段错误的函数调用链。

Step 4:生成dmp 文件除了调试信息,我们还可以创建一个dmp 文件,该文件包含了在崩溃时程序的完整内存快照,帮助进一步分析问题。

首先,使用以下命令保存gdb 调试会话到一个文件中:(gdb) set logging on(gdb) set logging file program.dmp(gdb) set logging overwrite on(gdb) info registers(gdb) x/100i pc(gdb) info all-registers(gdb) x/100xb rsp...(gdb) set logging off以上命令将保存所有寄存器的值,当前指令以及一部分堆栈信息到program.dmp 文件中。

segment fault 数组越界解决方法

segment fault 数组越界解决方法

segment fault 数组越界解决方法
数组越界是程序中常见的错误之一,它会导致程序崩溃或产生不可预测的结果。

为了解决数组越界问题,我们可以采取以下几种方法:
1. 检查数组边界:在编写代码时,我们应该始终注意数组的边界。

确保数组索
引不超出数组的长度范围。

可以使用条件语句(如if语句)来检查数组索引,以
避免发生越界错误。

2. 使用循环迭代:在对数组进行迭代操作时,我们应该使用循环来确保不会越
界访问数组元素。

可以使用for循环或while循环,以合适的条件来循环迭代数组。

3. 使用try-catch语句:一些编程语言提供了异常处理机制,我们可以使用try-catch语句来捕获并处理数组越界异常。

在try块中访问数组元素,并在catch块中
处理越界异常,以避免程序崩溃。

4. 使用内置函数或库:某些编程语言提供了内置函数或库来处理数组越界问题。

我们可以使用这些功能来快速识别和解决数组越界错误。

无论采取何种方法,解决数组越界问题的关键是在编码过程中要审慎处理数组
边界,并确保我们的代码在任何情况下都不会访问超出数组范围的索引。

这样可以增加程序的稳定性和可靠性,并防止潜在的错误出现。

Segmentation fault in linux

Segmentation fault in linux

Segmentation Fault in Linux——原因与避免Author:ZX_WING(xing5820@)写在前面的话最近CU(chinaunix)出现了很多问segmentation fault 的帖子,其实这也是个“月经贴”了,泡CU几年,每个月都有人问。

为了减少重复回帖,笔者结合自己的经验,总结了SIGSEGV在Linux中产生的机理,并用实际例子概括哪些编程错误容易引发SIGSEGV。

由于本人经验有限,文中难免有疏漏和错误,请发现的朋友发信到xing5820@ 指正,笔者好即使修改。

(版权声明:本文欢迎转载,但未经允许不得用于商业目的)内容提要本文简单介绍了Segmentation fault发生的原因,结合实际例子描述了内核向用户态程序发送SIGSEGV信号的流程。

文中以实例回答了常见的一些SIGSEGV问题,例如“为什么函数返回了栈还可以访问?”、“为什么free()后的内存仍然可以使用”、“为什么我遇到的是SIGSEGV而不是SIGILL信号”等。

最后笔者结合自己的经验,列举了一些预防SIGSEGV的编程习惯,供大家参考。

SIGSEGV严格依赖操作系统、编译器、硬件平台,本文基于Linux、GCC、32bit IA32架构,但对其他平台操作系统也有借鉴意义。

Revision History日期版本描述2009.12.21 1.0初次发表版本1.什么是“Segmentation fault in Linux”?我们引用wiki上的一段话来回答这个问题。

A segmentation fault(often shortened to SIGSEGV)is a particular error condition that can occur during the operation of computer software.A segmentation fault occurs when a program attempts to access a memory location that it is not allowed to access,or attempts to access a memory location in a way that is not allowed (for example,attempting to write to a read-only location,or to overwrite part of the operating system).Segmentation is one approach to memory management and protection in the operating system.It has been superseded by paging for most purposes,but much of the terminology of segmentation is still used, "segmentation fault"being an example.Some operating systems still have segmentation at some logical level although paging is used as the main memory management policy.On Unix-like operating systems,a process that accesses an invalid memory address receives the SIGSEGV signal.On Microsoft Windows,a process that accesses invalid memory receives theSTATUS_ACCESS_VIOLATION exception.上述文字没有给出SIGSEGV的定义,仅仅说它是“计算机软件操作过程中的一种错误情况”。

Linux命令行下的系统调试和故障排除

Linux命令行下的系统调试和故障排除

Linux命令行下的系统调试和故障排除系统调试和故障排除是Linux系统管理员日常工作中必备的技能。

在Linux命令行下,有许多强大而实用的工具可以帮助我们进行系统调试和故障排除。

本文将介绍一些常用的Linux命令行工具和技巧,以帮助读者更好地解决系统故障。

1. 检查系统日志系统日志是记录系统运行状态和错误信息的重要工具。

在Linux命令行下,我们可以通过命令"cat /var/log/messages"来查看系统日志。

系统日志中通常包含了各个组件和服务的运行信息,对于排查问题非常有帮助。

2. 监视进程和资源使用情况在Linux系统中,我们可以使用命令"top"来实时监视系统中运行的进程、CPU和内存的使用情况。

通过top命令,我们可以快速找出占用资源较多的进程,并进一步分析和解决问题。

3. 查看网络连接和端口网络问题是系统故障的常见原因之一。

在Linux命令行下,我们可以使用命令"netstat"来查看系统中的网络连接和占用的端口。

通过netstat命令,我们可以找出占用了某个端口的进程,并进一步排除网络问题。

4. 分析性能和资源利用率性能问题是系统故障排查中的重要方面。

在Linux命令行下,我们可以使用命令"vmstat"来查看系统的CPU、内存、磁盘和网络的使用情况。

通过vmstat命令,我们可以及时发现性能瓶颈,并采取相应的优化措施。

5. 检查硬件信息和设备状态硬件故障也是系统故障的一个常见原因。

在Linux命令行下,我们可以使用命令"lspci"和"lsusb"来查看系统中的PCI设备和USB设备信息。

此外,命令"dmidecode"可以帮助我们查看系统的BIOS和硬件配置信息。

通过检查硬件信息和设备状态,我们可以找出可能的硬件故障,并采取相应的修复措施。

Linux编程时出现Segmentationfault错误如何解决?

Linux编程时出现Segmentationfault错误如何解决?

Linux编程时出现Segmentationfault错误如何解决?
有些开发者在Linux下进程编程,使⽤GDB调试时发现了⼀个Segmentation fault错误。

这个错误主要是访问了错误的内存段引起的,可能是没有权限或者是内存段不存在,这个问题如何处理呢?下⾯⼩编将为⼤家带来Linux编程时出现Segmentation fault错误的处理办法,⼀起去看看吧。

⽅法如下:
这个错误是怎么导致的呢?原来是在定义⼀个char类型的指针,然后就直接对这个指针进⾏字符串的相关操作。

例如:
char *c1;
for(i=0; i《n;i++)
{
*c1 = getchar();
c1++;
}
代码意思⼤概是这样,这是很多开发者会犯的问题。

这个指针危险啊,要谨慎对待,就拿这⾥来说,这样给指针赋值,我们并不知道这指针指向的是哪⾥呢,如果写的数据覆盖了关键区域数据那可能会有灾难性的后果,这就是访问了不该访问的地⽅。

解决的办法是什么呢,告诉这个指针到该到的地⽅,我⽤malloc为该指针将要指向的字符串申请⼀段空间,这样就会指明系统分配⼀段安全的空间,不会在把内存关键区域分给你了。

这样你就可以安全操作了。

这个例⼦告诉我们指针是不能乱⽤的,如果指针指向错误的内存,导致编程时出现Segmentation fault错误,还可以⽤上⾯的办法处理,如果指向其他区域,还会导致更严重的后果。

关于Segmentationfault(coredumped)

关于Segmentationfault(coredumped)

关于Segmentationfault(coredumped)有的程序可以通过编译,但在运⾏时会出现Segment fault(段错误)。

这通常都是指针错误引起的。

但这不像编译错误⼀样会提⽰到⽂件⼀⾏,⽽是没有任何信息。

⼀种办法是⽤gdb的step, ⼀步⼀步寻找。

但要step⼀个上万⾏的代码让⼈难以想象。

我们还有更好的办法,这就是core file。

如果想让系统在信号中断造成的错误时产⽣core⽂件, 我们需要在shell中按如下设置:#设置core⼤⼩为⽆限 ulimit -c unlimited#设置⽂件⼤⼩为⽆限 ulimit unlimited发⽣core dump之后,⽤gdb进⾏查看core⽂件的内容, 以定位⽂件中引发core dump的⾏:gdb [exec file] [core file]如: gdb ./test test.core 在进⼊gdb后,⽤bt命令查看backtrace以检查发⽣程序运⾏到哪⾥,来定位core dump的⽂件->⾏。

另外需要注意的是,如果你的机器上跑很多的应⽤,你⽣成的core⼜不知道是哪个应⽤产⽣的,你可以通过下列命令进⾏查看:file core⼏个问题:1. 什么是Core:在使⽤半导体作为内存的材料前,⼈类是利⽤线圈当作内存的材料(发明者为王安),线圈就叫作 core ,⽤线圈做的内存就叫作 core memory。

如今,半导体⼯业澎勃发展,已经没有⼈⽤core memory 了,不过,在许多情况下,⼈们还是把记忆体叫作 core 。

2. 什么是Core Dump:我们在开发(或使⽤)⼀个程序时,最怕的就是程序莫明其妙地当掉。

虽然系统没事,但我们下次仍可能遇到相同的问题。

于是这时操作系统就会把程序当掉时的内存内容 dump 出来(现在通常是写在⼀个叫 core 的 file ⾥⾯),让我们或是 debugger 做为参考。

这个动作就叫作 core dump。

在Linux上什么是段错误?如何获得一个核心转储-

在Linux上什么是段错误?如何获得一个核心转储-

在Linux上什么是段错误?如何获得一个核心转储?本周工作中,我花了整整一周的时间来尝试调试一个段错误。

我以前从来没有这样做过,我花了很长时间才弄清楚其中涉及的一些基本事情(获得核心转储、找到导致段错误的行号)。

于是便有了这篇博客来解释如何做那些事情!在看完这篇博客后,你应该知道如何从“哦,我的程序出现段错误,但我不知道正在发生什么”到“我知道它出现段错误时的堆栈、行号了!”。

什么是段错误?“段错误segmentation fault”是指你的程序尝试访问不允许访问的内存地址的情况。

这可能是由于:试图解引用空指针(你不被允许访问内存地址 0);试图解引用其他一些不在你内存(LCTT 译注:指不在合法的内存地址区间内)中的指针;一个已被破坏并且指向错误的地方的C++++ 虚表指针C++ vtable pointer,这导致程序尝试执行没有执行权限的内存中的指令;其他一些我不明白的事情,比如我认为访问未对齐的内存地址也可能会导致段错误(LCTT 译注:在要求自然边界对齐的体系结构,如MIPS、ARM 中更容易因非对齐访问产生段错误)。

这个“C++ 虚表指针”是我的程序发生段错误的情况。

我可能会在未来的博客中解释这个,因为我最初并不知道任何关于C++ 的知识,并且这种虚表查找导致程序段错误的情况也是我所不了解的。

但是!这篇博客后不是关于C++ 问题的。

让我们谈论的基本的东西,比如,我们如何得到一个核心转储?运行valgrind我发现找出为什么我的程序出现段错误的最简单的方式是使用 valgrind:我运行valgrind -vyour-program这给了我一个故障时的堆栈调用序列。

简洁!。

Segment Fault(core dump)调试方法

Segment Fault(core dump)调试方法

Coredump关于程序core dump的调试方法简述:首先,在程序不正常退出时,内核会在当前工作目录下生成一个core文件(是一个内存映像,同时加上调试信息)。

使用gdb来查看core文件,可以指示出导致程序出错的代码所在文件和行数。

这个能给debug带来极大方便。

查看core dump位置方法:"gdb ./app core".故,我们需要gdb,可执行文件app,以及core文件。

下面将根据这3个需求,依次得到它们;一、1,得到gdb;其实这个是最简单的,Linux PC上gdb不用说了。

Android的是~/opt/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/b in/arm-linux-androideabi-gdb(其中~/opt/,与个人设置有关;android-ndk-r7与编译器版本有关,貌似android-ndk-r4没有toolchains目录,不知是否可以用gdbserver调试程序,当然这就不在本文档的讨论范围之内了).2,得到可执行文件app由于要使用gdb,所以app必须是"not stripped".Linux PC上"gcc hello.c"编译出来的a.out默认就是"not stripped".Android工程中jni目录下,我们使用"ndk-build"默认是"stripped"的。

因此需要更改编译脚本:在~/opt/android-ndk-r7/build/core/中打开default-build-commands.mk文件,将"cmd-strip = $(PRIVATE_STRIP) --strip-unneeded $(call host-path,$1)"这一行注释掉.这一行就是做的"strip"操作。

sefmentation fault 生成 dmp linux

sefmentation fault 生成 dmp linux

sefmentation fault 生成dmp linux“段错误生成dmp(转储文件)- Linux”问题解答介绍:在Linux操作系统中,当一个进程因为某种原因崩溃或出现错误时,会产生一个称为“段错误”的特殊类型错误。

段错误是由程序访问不存在的内存地址或没有写权限的内存地址引起的。

生成“dmp”(转储文件)是一种记录程序在崩溃之前的状态的方法,帮助开发人员找到出错的原因。

本文将一步一步解答如何在Linux上生成dmp文件以进行错误分析。

步骤一:编译和运行程序首先,我们需要一个可以产生“段错误”的程序。

你可以使用C或C++编程语言创建一个简单的程序,故意访问一个不存在的内存地址。

下面是一个C语言的示例程序:c#include <stdio.h>int main() {int *ptr = NULL;*ptr = 10;return 0;}以上程序会在`*ptr = 10`这一行引发段错误。

将上述代码保存为`main.c`文件。

然后,我们需要使用gcc编译器将其编译成可执行文件。

在终端中运行以下命令:bashgcc main.c -o dmp_example这将生成名为`dmp_example`的可执行文件。

步骤二:设置生成dmp文件的方法在Linux中,生成dmp文件的方法各不相同,下面将介绍两种常用的方法。

方法一:使用GNU Debugger(GDB)GDB是一个功能强大的调试工具,它可以用于分析程序的崩溃和错误。

下面是使用GDB生成dmp文件的步骤:1. 打开终端并导航到程序所在的目录。

2. 在终端中运行以下命令打开程序:bashgdb dmp_example3. 在GDB提示符下,运行以下命令设置生成dmp文件的方式:bashgenerate-core-file这将生成一个名为“core”的文件,它是程序当前状态的转储文件。

4. 使用以下命令退出GDB:bashquit生成的dmp文件将保存在程序所在的目录中。

linux segmentation fault定位方法

linux segmentation fault定位方法

linux segmentation fault定位方法
在Linux下定位Segmentation Fault时,可以使用以下几种方法:
1. 使用gdb(GNU Debugger)进行调试:在命令行中运行`gdb <可执行文件>`,然后在gdb命令提示符中输入`run`来运行程序,当出现Segmentation Fault时,gdb会提供一些有用的信息,包括错误的源代码行号和堆栈跟踪。

可以使用命令`backtrace`
来查看堆栈跟踪信息,以及使用其他gdb命令来调试和分析错误。

2. 使用valgrind进行内存错误检测:在命令行中运行`valgrind
<可执行文件>`,valgrind会在运行程序时监视和报告任何内存错误,包括Segmentation Fault。

它会给出具体的错误信息,
包括错误的内存地址和相关函数调用堆栈。

3. 使用core dump文件进行分析:当程序出现Segmentation Fault时,系统会生成core dump文件,其中包含了程序在崩溃时的内存映像。

可以使用gdb命令`core <core dump文件>`来
加载core dump文件并进行调试。

通过该方法,可以在程序崩
溃后分析内存和堆栈的状态。

4. 手动插入调试语句:在问题可能出现的地方插入一些调试语句,例如打印变量值和函数调用信息,以便定位错误发生的位置和原因。

需要注意的是,Segmentation Fault通常是由于访问非法内存
地址导致的,因此通常需要检查代码中的指针操作、数组越界、内存泄漏等问题。

Linux程序Segmentationfault(coredumped)

Linux程序Segmentationfault(coredumped)

Linux程序Segmentationfault(coredumped)1 问题原因Segmentation fault (core dumped)多为内存不当操作造成。

空指针、野指针的读写操作,数组越界访问,破坏常量等。

对每个指针声明后进⾏初始化为NULL是避免这个问题的好办法。

排除此问题的最好办法则是调试。

更为详细的原因:(1)内存访问越界a) 由于使⽤错误的下标,导致数组访问越界b) 搜索字符串时,依靠字符串结束符来判断字符串是否结束,但是字符串没有正常的使⽤结束符c) 使⽤strcpy, strcat, sprintf, strcmp, strcasecmp等字符串操作函数,将⽬标字符串读/写爆。

应该使⽤strncpy, strlcpy, strncat, strlcat, snprintf, strncmp, strncasecmp等函数防⽌读写越界。

(2)多线程程序使⽤了线程不安全的函数。

(3)多线程读写的数据未加锁保护。

对于会被多个线程同时访问的全局数据,应该注意加锁保护,否则很容易造成core dump(4)⾮法指针a) 使⽤空指针b) 随意使⽤指针转换。

⼀个指向⼀段内存的指针,除⾮确定这段内存原先就分配为某种结构或类型,或者这种结构或类型的数组,否则不要将它转换为这种结构或类型的指针,⽽应该将这段内存拷贝到⼀个这种结构或类型中,再访问这个结构或类型。

这是因为如果这段内存的开始地址不是按照这种结构或类型对齐的,那么访问它时就很容易因为bus error⽽core dump.(5)堆栈溢出。

不要使⽤⼤的局部变量(因为局部变量都分配在栈上),这样容易造成堆栈溢出,破坏系统的栈和堆结构,导致出现莫名其妙的错误。

2 使⽤GDB查看core⽂件默认编译出来的程序在出现Segmentation fault 时并没有⽣成core崩溃⽂件,可以在gcc/g++编译时增加-g选项。

如果仍然没有⽣成core⽂件,则可能是因为系统设置了core⽂件⼤⼩为0,可以通过:ulimit -a 查询得知。

Segmentationfault到底怎么回事

Segmentationfault到底怎么回事

Segmentationfault到底怎么回事(备注:我的glibc版本是2.12,GCC版本4.4.6,内核版本2.6.32-279)Linux上开发时最恼火的就是遇到“Segmetation Fault”错误。

为什么这么说,很多人看到这个错误后心里第一反应是程序访问的非法的内存,导致其被操作系统强行终止。

这固然没错,可这里有个比较模糊的概念了:什么叫“非法”的内存?程序运行时,每个进程都有自己的虚拟地址,理论上说进程应该可以随便使用才对,为什么还会出现这个错误呢?这里就涉及到程序的装载过程及原理。

先澄清几个概念:程序:一般是一组CPU指令的集合构成的文件,静态存储在诸如硬盘之类的存储设备上。

进程:当一个程序要被计算机运行时,就是在内存中产生该程序的一个运行时实例,我们就把这个实例叫做进程。

装载:上述从硬盘上的静态“程序”到内存中动态的“进程”之间的转变过程就叫做装载。

往通俗里讲,就是启动一个进程。

本文的主要目的是在简单了解进程的内存布局的情况下,从装载的过程入手,深入了解一下Segmetation Fault在操作系统层面是如何产生的,以及程序开发过程中应该如何避免这样的错误。

众所周知Linux中可执行文件的格式是ELF,其实编译过程中的中间文件*.o文件、动态共享库*.so文件也是ELF格式的。

在链接器看来,当它通过*.o或者配合*.so文件来生成可执行文件时,它对ELF格式的文件以链接视图(Linking View)进行看待。

也就是说链接器以Section 的形式来对待和处理ELF文件,诸如我们常见说的代码段(.text)、数据段(.data和.bss)等待概念。

当程序最终需要被装载成进程时,装载器就出场了,装载器将可执行文件以装载视图(Executive View)进行看待。

装载器将以Segment的形式来处理ELF文件。

网上很多教程也是这样说的,大家可能还是理解的不是很明白,后面我们通过实例的方式将进一步向大家来澄清这两者的区别。

怎样调试确定Segmentationfault的程序位置

怎样调试确定Segmentationfault的程序位置

怎样调试确定Segmentationfault的程序位置EsrCreate时遇到段错误导致程序崩溃signal(SIGSEGV, signal_handler);void sig_function(int sig){void *array[100];size_t size;char **strframe ;size_t i;if(sig == SIGSEGV){EDEBUG(0, "get illegal instruction or segmation fault: %d\n", sig);size = backtrace (array, 100);EDEBUG(0, "backtrace() returned %d addresses\n", size);strframe= backtrace_symbols (array, size);if(strframe==NULL){perror("backtrace_symbols");exit(EXIT_FAILURE);}for(i = 0; i < size; i++){EDEBUG(0, "frame [%02d] -- %s\n", i, strframe[i]);}}free(strframe);signal(sig, SIG_DFL);raise(sig);}通过以上程序代码打印程序运行轨迹和崩溃地址将源代码目录的c文件编译生产.o文件powerpc-none-linux-gnuspe-c++ -g --rdynamic -c main.cpp 使用一下命令连接生成带debug信息的可执行文件powerpc-none-linux-gnuspe-c++ -o demo m_pthread.o main.o aitalk.o -lpthread -lstdc++ -ldl ./Aitalk/Lib/Aitalk5.a ./gbuni/gbuni.a使用以下命令反汇编生产汇编文件powerpc-none-linux-gnuspe-objdump -S -D -t demo >test.txt然后根据以下程序语音打印地址在汇编文件中查找程序崩溃位置和函数进行调试=========>>>catch signal 11 <<<=========Dump stack start...backtrace() returned 11 addresses[00] ./demo [0x10002b88][01] ./demo [0x10002e60][02] [0x100344][03] ./demo [0x100d3a08][04] ./demo [0x1000c960][05] ./demo [0x10006658][06] ./demo [0x100049fc][07] ./demo [0x10004d2c][08] ./demo [0x10002a90][09] /lib/libc.so.6 [0xfbbfd18][10] /lib/libc.so.6 [0xfbbfe34]Dump stack end...Segmentation fault[user@P10xxCPB home]$。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Linux下的段错误产生的原因及调试方法简而言之,产生段错误就是访问了错误的内存段,一般是你没有权限,或者根本就不存在对应的物理内存,尤其常见的是访问0地址.一般来说,段错误就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gdtr来保存的,他是一个48位的寄存器,其中的32位是保存由它指向的gdt表,后13位保存相应于gdt的下标,最后3位包括了程序是否在内存中以及程序的在cpu中的运行级别,指向的gdt是由以64位为一个单位的表,在这张表中就保存着程序运行的代码段以及数据段的起始地址以及与此相应的段限和页面交换还有程序运行级别还有内存粒度等等的信息。

一旦一个程序发生了越界访问,cpu就会产生相应的异常保护,于是segmentation fault就出现了.在编程中以下几类做法容易导致段错误,基本是是错误地使用指针引起的1)访问系统数据区,尤其是往系统保护的内存地址写数据最常见就是给一个指针以0地址2)内存越界(数组越界,变量类型不一致等)访问到不属于你的内存区域解决方法我们在用C/C++语言写程序的时侯,内存管理的绝大部分工作都是需要我们来做的。

实际上,内存管理是一个比较繁琐的工作,无论你多高明,经验多丰富,难免会在此处犯些小错误,而通常这些错误又是那么的浅显而易于消除。

但是手工“除虫”(debug),往往是效率低下且让人厌烦的,本文将就"段错误"这个内存访问越界的错误谈谈如何快速定位这些"段错误"的语句。

下面将就以下的一个存在段错误的程序介绍几种调试方法:1dummy_function(void)2{3unsigned char*ptr=0x00;4*ptr=0x00;5}67int main(void)8{9dummy_function();1011return0;12}作为一个熟练的C/C++程序员,以上代码的bug应该是很清楚的,因为它尝试操作地址为0的内存区域,而这个内存区域通常是不可访问的禁区,当然就会出错了。

我们尝试编译运行它:xiaosuo@gentux test$./a.out段错误果然不出所料,它出错并退出了。

1.利用gdb逐步查找段错误:这种方法也是被大众所熟知并广泛采用的方法,首先我们需要一个带有调试信息的可执行程序,所以我们加上“-g-rdynamic"的参数进行编译,然后用gdb调试运行这个新编译的程序,具体步骤如下:xiaosuo@gentux test$gcc-g-rdynamic d.cxiaosuo@gentux test$gdb./a.outGNU gdb 6.5Copyright(C)2006Free Software Foundation,Inc.GDB is free software,covered by the GNU General Public License, and you arewelcome to change it and/or distribute copies of it under certain conditions.Type"show copying"to see the conditions.There is absolutely no warranty for GDB.Type"show warranty" for details.This GDB was configured as"i686-pc-linux-gnu"ing host libthread_db library"/lib/libthread_db.so.1".(gdb)rStarting program:/home/xiaosuo/test/a.outProgram received signal SIGSEGV,Segmentation fault.0x08048524in dummy_function()at d.c:44*ptr=0x00;(gdb)哦?!好像不用一步步调试我们就找到了出错位置d.c文件的第4行,其实就是如此的简单。

从这里我们还发现进程是由于收到了SIGSEGV信号而结束的。

通过进一步的查阅文档(man7signal),我们知道SIGSEGV默认handler的动作是打印”段错误"的出错信息,并产生Core文件,由此我们又产生了方法二。

2.分析Core文件:Core文件是什么呢?The default action of certain signals is to cause a process to terminate andproduce a core dump file,a disk file containing an image of the process's memoryat the time of termination.A list of the signals which cause a process to dumpcore can be found in signal(7).以上资料摘自man page(man5core)。

不过奇怪了,我的系统上并没有找到core文件。

后来,忆起为了渐少系统上的拉圾文件的数量(本人有些洁癖,这也是我喜欢Gentoo的原因之一),禁止了core文件的生成,查看了以下果真如此,将系统的core文件的大小限制在512K大小,再试:xiaosuo@gentux test$ulimit-cxiaosuo@gentux test$ulimit-c1000xiaosuo@gentux test$ulimit-c1000xiaosuo@gentux test$./a.out段错误(core dumped)xiaosuo@gentux test$lsa.out core d.c f.c g.c pango.c test_iconv.c test_regex.ccore文件终于产生了,用gdb调试一下看看吧:xiaosuo@gentux test$gdb./a.out coreGNU gdb 6.5Copyright(C)2006Free Software Foundation,Inc.GDB is free software,covered by the GNU General Public License, and you arewelcome to change it and/or distribute copies of it under certain conditions.Type"show copying"to see the conditions.There is absolutely no warranty for GDB.Type"show warranty" for details.This GDB was configured as"i686-pc-linux-gnu"ing host libthread_db library"/lib/libthread_db.so.1".warning:Can't read pathname for load map:输入/输出错误. Reading symbols from/lib/libc.so.6...done.Loaded symbols for/lib/libc.so.6Reading symbols from/lib/ld-linux.so.2...done.Loaded symbols for/lib/ld-linux.so.2Core was generated by`./a.out'.Program terminated with signal11,Segmentation fault.#00x08048524in dummy_function()at d.c:44*ptr=0x00;哇,好历害,还是一步就定位到了错误所在地,佩服一下Linux/Unix系统的此类设计。

接着考虑下去,以前用windows系统下的ie的时侯,有时打开某些网页,会出现“运行时错误”,这个时侯如果恰好你的机器上又装有windows的编译器的话,他会弹出来一个对话框,问你是否进行调试,如果你选择是,编译器将被打开,并进入调试状态,开始调试。

Linux下如何做到这些呢?我的大脑飞速地旋转着,有了,让它在SIGSEGV的handler中调用gdb,于是第三个方法又诞生了:3.段错误时启动调试:#include<stdio.h>#include<stdlib.h>#include<signal.h>#include<string.h>void dump(int signo){char buf[1024];char cmd[1024];FILE*fh;snprintf(buf,sizeof(buf),"/proc/%d/cmdline",getpid()); if(!(fh=fopen(buf,"r")))exit(0);if(!fgets(buf,sizeof(buf),fh))exit(0);fclose(fh);if(buf[strlen(buf)-1]=='\n')buf[strlen(buf)-1]='\0';snprintf(cmd,sizeof(cmd),"gdb%s%d",buf,getpid()); system(cmd);exit(0);}voiddummy_function(void){unsigned char*ptr=0x00;*ptr=0x00;}intmain(void){signal(SIGSEGV,&dump);dummy_function();return0;}编译运行效果如下:xiaosuo@gentux test$gcc-g-rdynamic f.cxiaosuo@gentux test$./a.outGNU gdb 6.5Copyright(C)2006Free Software Foundation,Inc.GDB is free software,covered by the GNU General Public License, and you arewelcome to change it and/or distribute copies of it under certain conditions.Type"show copying"to see the conditions.There is absolutely no warranty for GDB.Type"show warranty" for details.This GDB was configured as"i686-pc-linux-gnu"ing host libthread_db library"/lib/libthread_db.so.1".Attaching to program:/home/xiaosuo/test/a.out,process9563Reading symbols from/lib/libc.so.6...done.Loaded symbols for/lib/libc.so.6Reading symbols from/lib/ld-linux.so.2...done.Loaded symbols for/lib/ld-linux.so.20xffffe410in__kernel_vsyscall()(gdb)bt#00xffffe410in__kernel_vsyscall()#10xb7ee4b53in waitpid()from/lib/libc.so.6#20xb7e925c9in strtold_l()from/lib/libc.so.6#30x08048830in dump(signo=11)at f.c:22#4<signal handler called>#50x0804884c in dummy_function()at f.c:31#60x08048886in main()at f.c:38怎么样?是不是依旧很酷?以上方法都是在系统上有gdb的前提下进行的,如果没有呢?其实glibc为我们提供了此类能够dump栈内容的函数簇,详见/usr/include/execinfo.h(这些函数都没有提供manpage,难怪我们找不到),另外你也可以通过gnu的手册进行学习。

相关文档
最新文档