@snuffles
2014-12-25T13:28:05.000000Z
字数 1659
阅读 1094
程序语言
debug
references:
简单介绍其发生原因的文章
一篇对于每种原因有代码例子的好的文章
知其所以然的一片好文章
今天是历史性的一天,碰到了著名的Segment Fault问题。(怎么办好兴奋,看来我也是坏掉了)。
对于伟大的第一次相遇确实非常简单。确实是访问了空指针,三两句话说一下我的状况。
void getIaq4(IAQ *iaq)函数中有对iaq进行操作的iaq->status=buffer[0], getIaq4(myiaq)函数的调用时候并没有定义函数参数myiaq。
下文来自于第二篇文章的摘抄
段错误是对于软件是老熟人了,总之他就是访问了不让访问的存储器,或者以错误的方式访问了存储器。
段呢,原来是用来管理和维护存储的方式,现在几乎被页方式代替了,但是很多关于段的段子,哦不对是术语仍旧被使用着。段错误就是这样一个例子。在类Unix操作系统,访问无效的内存中的进程收到SIGSEGV信号。
在Microsoft Windows中,访问无效的内存接收STATUS_ACCESS_VIOLATION例外的预警。
2.1 访问不存在的内存地址
#include<stdio.h>
#include<stdlib.h>
void main()
{
int *ptr = NULL;
*ptr = 0;
}
2.2 访问系统保护的内存地址
#include<stdio.h>
#include<stdlib.h>
void main()
{
int *ptr = (int *)0;
*ptr = 100;
}
2.3 访问只读的内存地址
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void main()
{
char *ptr = "test";
strcpy(ptr, "TEST");
}
2.4 栈溢出
#include<stdio.h>
#include<stdlib.h>
void main()
{
main();
}
等等其他原因。
dmesg|-g|nm|ldd(本文略、详见references)
printf|gcc gdb|core gdb|objdump|catchsegv(本文略、详见references)
可以使用条件编译指令#ifdef DEBUG和#endif把printf函数包起来。这样在程序编译时,如果加上-DDEBUG参数就能查看调试信息;否则不加该参数就不会显示调试信息。
下文来自于第三篇文章的摘抄
提到segment fault经常会说到非法的内存,那就要了解程序的装载过程、原理本文在简单了解进程的内存布局的情况下,从装载的过程入手,深入了解一下Segmetation Fault在操作系统层面是如何产生的,以及程序开发过程中应该如何避免这样的错误。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int bssvar;
int main(int argc,char** argv)
{
void *ptr;
printf("main start = %p\n",main);
printf("bss end = %p\n",(long)&bssvar+4);
ptr=sbrk(0);
printf("current brk = %p\n",(long*)ptr);
sleep(8);
int i=0x08049628;
brk((char*)0x804A123); //注意这行代码
for(;;i++)
printf("At:0x%x-0x%x\n",i,*((char*)i));
}