原文地址:http://iamcaihuafeng.blog.sohu.com/145118361.html
因为没法分享和转载,所以放到这个地方。
我用GDB调试Segmentation fault错误的过程
标签: c gdb
分类: C/C Plus Plus
2010-03-01 23:52
file.c最开始的内容为,程序是从网上拷贝下来的,调整了一下,主要功能为读取file.c本身,然后将内容写到file2.c中。
#include <stdio.h>
#include <string.h>
int main() {
FILE *sourceFile;
FILE *destinationFile;
char *buffer;
int n;
sourceFile = fopen("file.c", "r");
destinationFile = fopen("file2.c", "w");
if(sourceFile==NULL) {
printf("Error: can't access file.c./n");
return 1;
}
else if(destinationFile==NULL) {
printf("Error: can't create file for writing./n");
return 1;
}
else {
n = fread(buffer, 1, 1000, sourceFile); /* grab all the text */
fwrite(buffer, 1, n, destinationFile); /* put it in file2.c */
fclose(sourceFile);
fclose(destinationFile);
destinationFile = fopen("file2.c", "r");
n = fread(buffer, 1, 1000, destinationFile); /* read file2.c */
printf("%s", buffer); /* display it all */
fclose(destinationFile);
return 0;
}
}
编译,执行,报Segmentation fault的错误
[root@CentOS_Test_Server server]# gcc -o file file.c
[root@CentOS_Test_Server server]# ./file
Segmentation fault (core dumped)
如果编译的时候没有生成以core开头的文件,编译时加上-g的选项即可,即gcc -o file -g file.c
[root@CentOS_Test_Server server]# ls core*
core.25899
[root@CentOS_Test_Server server]# gdb file core.25899
GNU gdb Fedora (6.8-37.el5)
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...
warning: Can't read pathname for load map: Input/output error.
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
Core was generated by `./file'.
Program terminated with signal 11, Segmentation fault.
[New process 25208]
#0 0x001720ac in memcpy () from /lib/libc.so.6
(gdb)
输入bt,输出如下:
#0 0x001720ac in memcpy () from /lib/libc.so.6
#1 0x0016387a in _IO_file_xsgetn_internal () from /lib/libc.so.6
#2 0x001658a8 in _IO_sgetn_internal () from /lib/libc.so.6
#3 0x00159b4e in fread () from /lib/libc.so.6
#4 0x08048531 in main () at file.c:71
(gdb)
我们可以看到,gdb提示file.c的第71行出了问题。
file.c的第71行是n = fread(buffer, 1, 1000, sourceFile); /* grab all the text */
gdb提示说跟memcpy有关,可能是fread时调用了memcpy函数,难道是跟变量buffer的定义有关,试着将char *buffer改为char buffer[1000],重新编译,没想到问题解决了,真的是很高兴:-)
这里大家要对
字符串数组及
指针变量非常熟悉,否则很容易出现上述的错误,我在网上找到一篇文章,写得还算可以,基本上可以理解。
引用一段,方便以后查阅:
四、使用字符串指针变量与字符数组的区别
用字符数组和字符指针变量都可实现字符串的存储和运算。 但两者是有区别的。在使用时应注意以下几个问题:
1. 字符串指针变量本身是一个变量,用于存放字符串的首地址。而字符串本身是存放在以该首地址为首的一块连续的内存空间中并以‘/0’作为串的结束。字符数组是由于若干个数组元素组成的,它可用来存放整个字符串。
2. 对字符数组作初始化赋值,必须采用外部类型或静态类型,如: static char st[]={“C Language”};而对字符串指针变量则无此限制,如: char *ps="C Language";
3. 对字符串指针方式 char *ps="C Language";可以写为: char *ps;
ps="C Language"; 而对数组方式: static char st[]={"C Language"};不能写为: char st[20]; st={"C Language"};而只能对字符数组的各元素逐个赋值。
从以上几点可以看出字符串指针变量与字符数组在使用时的区别,同时也可看出使用指针变量更加方便。
前面说过,当一个指针变量在未取得确定地址前使用是危险的,容易引起错误。但是对指针变量直接赋值是可以的。因为C系统对指针变量赋值时要给以确定的地址。因此, char *ps="C Langage";或者 char *ps; ps="C Language";都是合法的。
参考:
http://blog.csdn.net/learnhard/archive/2009/11/26/4879834.aspx
http://www.baidu.com/s?wd=