segmentation fault with getc()

H

hzmonte

My C program has the following:
static int skip_space(FILE *fp, int *line, int c)
{
int i = 0;
if(feof(fp)) { printf("in skip feof ...\n"); }
printf("in skip start fp=%p line=%d c=%d\n", fp, *line, c);
while ((c == ' ' || c == '\t') && !feof(fp)) {
printf("i=%d\n", i++);
if(feof(fp)) { printf("in skip feof\n"); break;}
c = getc(fp);
printf("right after getc, c=%d\n", c);
}
....
}

strace has the following:
open("/es/m/.messengers_profile", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0600, st_size=122, ...}) = 0
mmap2(NULL, 32768, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1,
0) = 0xb75ee000
read(3, "key = 1244\nlib = /lib/libc.so.6\n"..., 32768) = 122
....
write(1, "in skip start fp=0x9ded0f8 line="..., 39in skip start
fp=0x9ded0f8 line=6 c=32) = 39
write(1, "i=0\n", 4i=0) = 4
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++
It appears that the C runtime reads all the file's 122 characters in a
cache with starting address 0xb75ee000. And my C program continues to
read (i.e. getc) from this cache. Eventually, when it reaches EOF when
executing the getc(fp) in skip_space(), it crashes.

Interestingly, running it with gdb does not crash. I am using gcc
3.2.3 on Red Hat Linux kernel 2.4. How can I find out what's wrong?
 
A

Andrew Poelstra

My C program has the following:
static int skip_space(FILE *fp, int *line, int c)
{
int i = 0;
if(feof(fp)) { printf("in skip feof ...\n"); }
printf("in skip start fp=%p line=%d c=%d\n", fp, *line, c);
while ((c == ' ' || c == '\t') && !feof(fp)) {
printf("i=%d\n", i++);
if(feof(fp)) { printf("in skip feof\n"); break;}
c = getc(fp);
printf("right after getc, c=%d\n", c);
}
...
}

Formatting is far more important that you'd think. Space well.

static int skip_space (FILE *fp, int *line, int c)
{
int i = 0;

if (feof (fp))
printf("in skip feof ...\n");

printf ("in skip start fp=%p line=%d c=%d\n", fp, *line, c);

while ((c == ' ' || c == '\t') && !feof(fp))
{
printf ("i=%d\n", i++);
if (feof (fp))
{
printf("in skip feof\n");
break;
}
c = getc(fp);
printf("right after getc, c=%d\n", c);
}
}

I'll leave it at that and reply to my own post, so that I can quote it
in the style that I prefer when commenting.
 
A

Andrew Poelstra

Formatting is far more important that you'd think. Space well.

static int skip_space (FILE *fp, int *line, int c)

I can't see what this function does; it takes a file pointer and
an int pointer called line, of all things, and an int passed by
value called c. I've no idea why you need any of them, just glancing
at it.
{
int i = 0;

if (feof (fp))
printf("in skip feof ...\n");
If this fails, you should do something, like return from the function.
printf ("in skip start fp=%p line=%d c=%d\n", fp, *line, c);
Fine.

while ((c == ' ' || c == '\t') && !feof(fp))
What do you expect c to be initially?
{
printf ("i=%d\n", i++);
This looks like a debug statement. Why is it incrementing i?
if (feof (fp))
You are already testing for this in your while statement. Why do it twice?
{
printf("in skip feof\n");
break;
}
c = getc(fp);
Shouldn't this be up higher?
printf("right after getc, c=%d\n", c);
}
}

I'll leave it at that and reply to my own post, so that I can quote it
in the style that I prefer when commenting.

Done. Much easier. :)


So, you should fix the design issues, and explain how to use the function,
so that we can compile this and test it. At least tell us what it is supposed
to do.
 
K

Keith Thompson

My C program has the following:
static int skip_space(FILE *fp, int *line, int c)
{
int i = 0;
if(feof(fp)) { printf("in skip feof ...\n"); }
printf("in skip start fp=%p line=%d c=%d\n", fp, *line, c);
while ((c == ' ' || c == '\t') && !feof(fp)) {
printf("i=%d\n", i++);
if(feof(fp)) { printf("in skip feof\n"); break;}
c = getc(fp);
printf("right after getc, c=%d\n", c);
}
...
}

One big problem, I think, is that you're misusing the feof() function.

The way to tell whether you've reached the end of your input file is
to check whether getchar() (or getc() or fgetc(), or whatever you're
using) has returned the value EOF. Unlike the analagous function in
some other languages, feof() returns true only *after* you've
attempted to read past the end of the file. It's mainly used after
fgetc() has returned EOF, to determine whether this was caused by
reaching end-of-file or by an error.

Read section 12 of the comp.lang.c FAQ, <http://www.c-faq.com/>.

I can't tell you how to do this right, because it's not clear from
what you've posted just what your function is supposed to do or what
its arguments are supposed to mean. Describe clearly in English what
it's supposed to do, and we might be able to help you.
 
T

Tom St Denis

My C program has the following:
static int skip_space(FILE *fp, int *line, int c)
{
int i = 0;
if(feof(fp)) { printf("in skip feof ...\n"); }
printf("in skip start fp=%p line=%d c=%d\n", fp, *line, c);
while ((c == ' ' || c == '\t') && !feof(fp)) {
printf("i=%d\n", i++);
if(feof(fp)) { printf("in skip feof\n"); break;}
c = getc(fp);
printf("right after getc, c=%d\n", c);
}
...
}

strace has the following:
open("/es/m/.messengers_profile", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0600, st_size=122, ...}) = 0
mmap2(NULL, 32768, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1,
0) = 0xb75ee000
read(3, "key = 1244\nlib = /lib/libc.so.6\n"..., 32768) = 122
...
write(1, "in skip start fp=0x9ded0f8 line="..., 39in skip start
fp=0x9ded0f8 line=6 c=32) = 39
write(1, "i=0\n", 4i=0) = 4
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++

Use a debugger.

strace is NOT A DEBUGGER. It is meant only to show you what system
calls are going on, e.g. to see what a process is doing.

If you want to know why your process is segfaulting compile with debug
symbols and run it in GDB.

Learn to use your tools...

Tom
 
H

hzmonte

Tom said:
If you want to know why your process is segfaulting compile with debug
symbols and run it in GDB.
I think I already said running it with gdb does not produce any error.
By the way, compiling it with gcc 3.2.3 without -O3 and running it on
Linux 2.4 is fine. Compiling it using gcc 3.4.4 with -O3 and running
it on Linux 2.6 is fine too. The segfault occurs only when compiling
it with -O3 and running it on Linux 2.4.
 
I

Ian Collins

I think I already said running it with gdb does not produce any error.
By the way, compiling it with gcc 3.2.3 without -O3 and running it on
Linux 2.4 is fine. Compiling it using gcc 3.4.4 with -O3 and running
it on Linux 2.6 is fine too. The segfault occurs only when compiling
it with -O3 and running it on Linux 2.4.
Then you may have hit a Linux or gcc bug, try a gcc group.
 
B

Bill Pursell

My C program has the following:
static int skip_space(FILE *fp, int *line, int c)
{
int i = 0;
if(feof(fp)) { printf("in skip feof ...\n"); }
printf("in skip start fp=%p line=%d c=%d\n", fp, *line, c);
while ((c == ' ' || c == '\t') && !feof(fp)) {
printf("i=%d\n", i++);
if(feof(fp)) { printf("in skip feof\n"); break;}
c = getc(fp);
printf("right after getc, c=%d\n", c);
}
...
}

I'm not able to answer your exact question, but
I'm pretty sure that if ferror() returns true, feof()
may still return false and your while loop is
never going to terminate.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,154
Members
46,702
Latest member
LukasConde

Latest Threads

Top