Page 1 of 1
Segmentation Fault in CentOS5
Posted: Thu Nov 10, 2011 4:42 pm
by osmiumusa
Hello,
I'm writing a program called "peek" that takes a couple of parameters, such as a file, and displays a bit of the file. The code looks like it will work, but when I run it, even without arguments, I get a "Segmentation Fault" message instead of what its supposed to print out.
I tried to debug it with GDB but it doesn't seem to want to tell me anything useful. It tells me the error, but beyond that, it doesn't tell me much else. I can't do a backtrace as the problem seems to be in the main() function. I think it has something to do with the file functions, but I'm not sure.
This program is written in C, and uses the functions "fopen, fclose, fgets, atoi, printf, strcat"
Compiled with "gcc peek.c" and puts out "a.out"
Executed with "./a.out <arguments>"
I'll show source code as a worst-case scenario, but I'm the kind of person who is reluctant to do so... I've had some bad experiences with that...
Thank you so much in advance for any help.
~osmiumusa
Re: Segmentation Fault in CentOS5
Posted: Thu Nov 10, 2011 4:58 pm
by JackScott
Could you please paste the output from GDB (the error message)? That would probably be the best start. The code would also be really helpful. Can I ask why you have bad experiences with showing it?
In my personal experience, "Segmentation Fault" usually indicates a bad pointer dereference. But not always.
You could also try my favourite debugging method: put calls to printf() with numbers or short messages (i.e. 'printf("got to the bit where i open the file\n")') in between every major function call or part where you suspect the code of failing, and then seeing where the output gets to before it crashes.
Re: Segmentation Fault in CentOS5
Posted: Fri Nov 11, 2011 5:48 pm
by osmiumusa
Code: Select all
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int, char**);
void color_settopaper();
void color_revert();
void newline();
void done(int);
void stripnl(char *);
void color_warning();
void help();
int usecolor = 1;
//usage "peek <file> -m <linecount> --nocolor
//BEGIN ACTUALL CODE
int main(int argc, char** argv) {
//defaults and declarations
// int usecolor = 1;
int maxcount = 10;
int lcount = 0;
if (argc==1) {done(1);}
//parse the arguments...
int i=0;
for (i=2;i<=argc;i++) {
if (!strcmp(argv[i],"-m")) {
maxcount = atoi(argv[(i+1)]);
i++;
continue;
}
if (!strcmp(argv[i],"--nocolor")) {
usecolor = 0;
continue;
}
if (!strcmp(argv[i],"-l")) {
lcount = atoi(argv[(i+1)]);
i++;
continue;
}
if (!strcmp(argv[i],"--help")) {
help();
continue;
}
color_warning();
printf("You passed me an invalid switch: %s. I'll ignore it this time but ",argv[i]);
color_error();
printf("DON'T LET IT HAPPEN AGAIN!");
color_revert();
printf(" Thanks!");
newline();
}
color_settopaper();
FILE *infile;
char line[100];
/* Read in the filename */
/* We need to get rid of the newline char. */
stripnl(argv[1]);
/* Open the file. If NULL is returned there was an error */
if((infile = fopen(argv[1], "r")) == NULL) {
done(2);
}
while(fgets(line, sizeof(line), infile) != NULL || lcount>maxcount) {
/* Get each line from the infile */
lcount++;
/* print the line number and data */
printf("Line %d: %s", lcount, line);
}
fclose(infile); /* Close the file */
color_revert();
done(0); //finish with no error
}
void stripnl(char *str) {
while(strlen(str) && ( (str[strlen(str) - 1] == 13) ||
( str[strlen(str) - 1] == 10 ))) {
str[strlen(str) - 1] = 0;
}
}
void color_warning() {
printf("\033[31;42m");
}
void color_settopaper() {
if (usecolor) printf("\033[30;47m");
}
void color_revert() {
if (usecolor) printf("\033[0m");
}
void color_error() {
if (usecolor) printf("\033[1;33;41m");
}
void newline() {
printf("\n");
}
void help() {
printf("Let colors be enabled if possible for this help message");
newline();
printf("Peek allows you to peek at a file without seeing the entire thing");
newline();
printf("Peek does not clear the entire screen");
newline();
printf("Usage:");
newline();
printf(" peek <filename> [-m <numberoflines> -l <startingline> --nocolor --help");
newline();
printf("You MUST specify a file name to peek at!");
newline();
printf("Options:");
newline();
printf("-m <numberoflines> <numberoflines> specifies how many lines to peek at. The default is 10.");
newline();
printf("-l <startingline> <startingline> specifies where to start in the file. The default is at the begining.");
newline();
printf("--nocolor Disables the use of color in the program's output.");
newline();
printf("--help Displays this help file and quits.");
newline();
printf("If you pass the program an invalid switch, it may be rude about it.");
newline();
newline();
color_settopaper();
printf("This color");
color_revert();
printf(" is the \"paper\" color. The file will be this color");
newline();
color_warning();
printf("This color");
color_revert();
printf(" is a warning color; not used often.");
newline();
color_error();
printf("This color");
color_revert();
printf(" is the error color.");
done(0);
}
void done(int errorcode) {
if (errorcode==1) {
color_error();
printf("No file specified. Please specify a file.");
}
if (errorcode==2) {
color_error();
printf("Error opening the file specified. Make sure the source is readable");
}
color_revert();
printf("\n");
exit(1);
}
Here is what I do to exicute it and its respective outputs...
Code: Select all
[root@localhost peek]# ./a.out
No file specified. Please specify a file.
[root@localhost peek]# ./a.out foo.bar
Segmentation fault
[root@localhost peek]# ./a.out foo.bar -m 7
Segmentation fault
And here is what GDB can tell me...
Code: Select all
[root@localhost peek]# gdb a.out
GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-37.el5_7.1)
Copyright (C) 2009 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".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/programs/peek/a.out...(no debugging symbols found)...done.
(gdb) run
Starting program: /root/programs/peek/a.out
No file specified. Please specify a file.
Program exited with code 01.
(gdb) ru foo.dat
Starting program: /root/programs/peek/a.out foo.dat
Program received signal SIGSEGV, Segmentation fault.
0x08048894 in main ()
(gdb) backtrace
#0 0x08048894 in main ()
I can't seem to do anything else useful without a symbol file or a core dump. Any thoughts? It doesn't look like (to me) that I'm doing things that I shouldn't...
Re: Segmentation Fault in CentOS5
Posted: Fri Nov 11, 2011 6:08 pm
by osmiumusa
I did what JackScott suggested and found that it was dying at...
Whats wrong with this and how can I fix it?
Re: Segmentation Fault in CentOS5
Posted: Fri Nov 11, 2011 6:25 pm
by Minoto
osmiumusa wrote:I did what JackScott suggested and found that it was dying at...
Whats wrong with this and how can I fix it?
Try printing the value of argc as you run the program with varying numbers of arguments. Then think about loop termination conditions.
Edit: and starting points, too, actually.
Re: Segmentation Fault in CentOS5
Posted: Fri Nov 11, 2011 6:59 pm
by neon
There is an error here that could very well cause a seg fault in the last iteration of the loop. Think about it...
Re: Segmentation Fault in CentOS5
Posted: Fri Nov 11, 2011 10:41 pm
by osmiumusa
I think I see the problem... its going past the array by atleast one. How do I fix this? By changing the operator to "<"?
Re: Segmentation Fault in CentOS5
Posted: Fri Nov 11, 2011 10:49 pm
by JackScott
Try it and see! It's only a quick edit and a recompile if it goes wrong.
Hint: Yes, that will probably fix it.
Re: Segmentation Fault in CentOS5
Posted: Sat Nov 12, 2011 4:19 am
by Combuster
If an array has 5 elements, they will be:
a[0] // 1st
a[1] // 2nd
a[2] // 3rd
a[3] // 4th
a[4] // 5th
and a[5] is the sixth element and therefore does not exist. Same goes for argv[argc] which does not exist either.