seg fault

B

Bill Cunningham

I have put together this program that seems to do what I want without
error checking added yet. If I just run the program it produces a
segmentation fault. If I add the proper value say 43.56 it's fine. Does
anyone see what's wrong ? I have a c99 compiler. Thanks.

#include <stdio.h>
#include <stdlib.h>

int main ( int argc, char *argv[] ) {
FILE*fp;
double x;
x=strtod(argv[1],NULL);
if (argc !=2) {
fprintf(stderr,"usage error\n");
exit(EXIT_FAILURE);
}
fp=fopen( "data", "a");
ftell(fp);
fseek(fp,sizeof(double),SEEK_CUR);
fprintf(fp,"%.2f\n",x);
fclose(fp);
}
 
B

Bill Cunningham

Malcolm McLean said:
Bill Cunningham said:
I have put together this program that seems to do what I want without
error checking added yet. If I just run the program it produces a
segmentation fault. If I add the proper value say 43.56 it's fine. Does
anyone see what's wrong ? I have a c99 compiler. Thanks.

#include <stdio.h>
#include <stdlib.h>

int main ( int argc, char *argv[] ) {
FILE*fp;
double x;
x=strtod(argv[1],NULL);
If argc is 1 this passes a null pointer to strtod, which could well cause
a segfault.

This may be where it is. Just running the program argv[0] would be
execution, giving no arguments like I didn't would be NULL.
 
S

santosh

Bill said:
I have put together this program that seems to do what I want
without
error checking added yet. If I just run the program it produces a
segmentation fault. If I add the proper value say 43.56 it's fine.
Does anyone see what's wrong ? I have a c99 compiler. Thanks.

#include <stdio.h>
#include <stdlib.h>

int main ( int argc, char *argv[] ) {
FILE*fp;
double x;
x=strtod(argv[1],NULL);
if (argc !=2) {
fprintf(stderr,"usage error\n");
exit(EXIT_FAILURE);
}

This test should come before the conversion with strtod. Otherwise
strtod is passed a null pointer, which is what causes the segmentation
fault.
fp=fopen( "data", "a");
ftell(fp);

What is the purpose of calling ftell and discarding the return?
fseek(fp,sizeof(double),SEEK_CUR);

When you open a file in the append mode the file position indicator is
already positioned after any contents the file may have. You are now
trying to seek sizeof(double) bytes beyond the end of the file, which
will return an error. Exactly what do you hope to accomplish by doing
so?
 
J

Johannes Bauer

Bill said:
This may be where it is. Just running the program argv[0] would be
execution, giving no arguments like I didn't would be NULL.

"may be"? Say do you think debugging C-programs is like guessing where
the fault could occur? Why don't you use a helper tool, say, uhmm, a
debugger?

With a program that short however you could well have inserted some
fprintf(stderr, "xyz\n") statements after every line and found it yourself.

Regards,
Johannes
 
B

Bill Cunningham

santosh said:
Bill said:
I have put together this program that seems to do what I want
without
error checking added yet. If I just run the program it produces a
segmentation fault. If I add the proper value say 43.56 it's fine.
Does anyone see what's wrong ? I have a c99 compiler. Thanks.

#include <stdio.h>
#include <stdlib.h>

int main ( int argc, char *argv[] ) {
FILE*fp;
double x;
x=strtod(argv[1],NULL);
if (argc !=2) {
fprintf(stderr,"usage error\n");
exit(EXIT_FAILURE);
}

This test should come before the conversion with strtod. Otherwise
strtod is passed a null pointer, which is what causes the segmentation
fault.
fp=fopen( "data", "a");
ftell(fp);

What is the purpose of calling ftell and discarding the return?
fseek(fp,sizeof(double),SEEK_CUR);

When you open a file in the append mode the file position indicator is
already positioned after any contents the file may have. You are now
trying to seek sizeof(double) bytes beyond the end of the file, which
will return an error. Exactly what do you hope to accomplish by doing
so?
fprintf(fp,"%.2f\n",x);
fclose(fp);
}

Well I've added error checking to ftell, fseek, and fopen and the
program works. It will still segfault if the program is run and nothing
entered. I've used these return values.
For ftell and fseek -1. For fopen NULL. I believe those are the values
to test against.

Bill
 
B

Bill Cunningham

santosh said:
Bill said:
I have put together this program that seems to do what I want
without
error checking added yet. If I just run the program it produces a
segmentation fault. If I add the proper value say 43.56 it's fine.
Does anyone see what's wrong ? I have a c99 compiler. Thanks.

#include <stdio.h>
#include <stdlib.h>

int main ( int argc, char *argv[] ) {
FILE*fp;
double x;
x=strtod(argv[1],NULL);
if (argc !=2) {
fprintf(stderr,"usage error\n");
exit(EXIT_FAILURE);
}

This test should come before the conversion with strtod. Otherwise
strtod is passed a null pointer, which is what causes the segmentation
fault.

Oh OK
What is the purpose of calling ftell and discarding the return?

Where do I put it?
When you open a file in the append mode the file position indicator is
already positioned after any contents the file may have. You are now
trying to seek sizeof(double) bytes beyond the end of the file, which
will return an error. Exactly what do you hope to accomplish by doing
so?

People tell me look at the docs. I read the sentnece or two that
describes the functions in man pages and it's return values and stick it in
code. Hell I don't know what ftell does.

http://www.cppreference.com/stdio/index.html

Just look at the descriptions of functions on this page. You better
already know what they do before you read. I thought fseek would take as a
3rd paramter 0,1, or 2.

Bill
 
R

Richard

Bill Cunningham said:

Because I actually think you are too stuck in your ways to bother to
learn how to use one and you seem incapable of using Google I provide
you this link: (I think you mentioned you use gcc)

http://dirac.org/linux/gdb/

Read the "What is a debugger" part thoroughly.

http://dirac.org/linux/gdb/01-Introduction.php#whatisadebugger

Many people suggest using printf's. This is, IMO, amateurish at best.

From this web page:

,----
| Most people use the printf() debugging method. This is called adding
| "trace code" to your program. Simply put, they sprinkle their code with
| printf() to view the value of variables at certain strategic points and
| also to examine the order of execution of lines of source code.
|
|
| There are a few reasons why this may not be the best way of doing things:
|
| 1. Sometimes you need a lot of printf()'s, and it can get tedious
| putting them in and taking them out. Inserting and deleting
| superfluous code all the time is really distracting. It draws
| attention away from what you're doing. It's like trying to implement
| a linked list while someone is talking to you about last night's
| Futurama episode.
|
| 2. A symbolic debugger can do an awful lot that printf() can't. You
| can do just about anything you can think of, including changing the
| value of variables at run-time, halt the program temporarily, list
| source code, printo the datatype of a variable or struct that you
| don't recognize, jump to an arbitrary line of code, and much, much
| more.
|
| 3. You can use a symbolic debugger on a running process; you don't
| even have to kill the process! Try that with printf()!
|
| 4. You can use a symbolic debugger on a process that has already
| crashed and died without having to re-run the program. You'll see the
| state the program was in at the time of death and can inspect all the
| variables.
|
| 5. A knowledge of GDB will increase your knowledge of programs,
| processes, memory and your language of choice.
|
|
| You'll be able to find and fix your bugs faster using a symbolic
| debugger like GDB. However, this isn't to say that printf() has no use
| in debugging. Sometimes it's the best way to go. However, for real code,
| a debugger can almost always get the job done orders of magnitude faster
| and easier. And using a debugger is always more elegant, and if you
| don't care about elegance, you should quit programming on Linux and
| start using Visual C++.
`----
 
S

santosh

Bill said:
santosh said:
Bill said:
I have put together this program that seems to do what I want
without
error checking added yet. If I just run the program it produces a
segmentation fault. If I add the proper value say 43.56 it's fine.
Does anyone see what's wrong ? I have a c99 compiler. Thanks.

#include <stdio.h>
#include <stdlib.h>

int main ( int argc, char *argv[] ) {
FILE*fp;
double x;
x=strtod(argv[1],NULL);
if (argc !=2) {
fprintf(stderr,"usage error\n");
exit(EXIT_FAILURE);
}

This test should come before the conversion with strtod. Otherwise
strtod is passed a null pointer, which is what causes the
segmentation fault.
fp=fopen( "data", "a");
ftell(fp);

What is the purpose of calling ftell and discarding the return?
fseek(fp,sizeof(double),SEEK_CUR);

When you open a file in the append mode the file position indicator
is already positioned after any contents the file may have. You are
now trying to seek sizeof(double) bytes beyond the end of the file,
which will return an error. Exactly what do you hope to accomplish by
doing so?
fprintf(fp,"%.2f\n",x);
fclose(fp);
}

Well I've added error checking to ftell, fseek, and fopen and the
program works. It will still segfault if the program is run and
nothing entered.

That's expected. In the case of no arguments argv[1] is a null pointer
and passing it to strtod results in undefined behaviour.
I've used these return values.
For ftell and fseek -1. For fopen NULL. I believe those are the
values to test against.

Yes.
 
S

santosh

Bill said:
santosh said:
Bill said:
I have put together this program that seems to do what I want
without
error checking added yet. If I just run the program it produces a
segmentation fault. If I add the proper value say 43.56 it's fine.
Does anyone see what's wrong ? I have a c99 compiler. Thanks.

#include <stdio.h>
#include <stdlib.h>

int main ( int argc, char *argv[] ) {
FILE*fp;
double x;
x=strtod(argv[1],NULL);
if (argc !=2) {
fprintf(stderr,"usage error\n");
exit(EXIT_FAILURE);
}

This test should come before the conversion with strtod. Otherwise
strtod is passed a null pointer, which is what causes the
segmentation fault.

Oh OK
What is the purpose of calling ftell and discarding the return?

Where do I put it?

What is the purpose of this program. Is it to append to a text file a
double value? If so, then you do not need the ftell above since upon
opening the file with the "a" mode, the file position indicator is
already correctly positioned.
People tell me look at the docs. I read the sentnece or two that
describes the functions in man pages and it's return values and stick
it in code.

Reading a "sentence or two" is not good enough. You need to completely
and systematically read the standard's description and your
implementation's description of each standard library function before
using it. If you don't understand what a function does even after
reading it's documentation, then you can ask here.
Hell I don't know what ftell does.

Then read it's documentation in n1256 below:


I do not know how good the above link is, but other than the standard
itself the following documentation is very good as a reference for the
C99 standard library.

Just look at the descriptions of functions on this page. You
better already know what they do before you read.

Not at all.
I thought fseek would take
as a 3rd paramter 0,1, or 2.

No. The possible values are SEEK_SET, SEEK_CUR and SEEK_END.
 
U

user923005

    I have put together this program that seems to do what I want without
error checking added yet. If I just run the program it produces a
segmentation fault. If I add the proper value say 43.56 it's fine. Does
anyone see what's wrong ? I have a c99 compiler. Thanks.

#include <stdio.h>
#include <stdlib.h>

int main ( int argc, char *argv[] ) {
    FILE*fp;
    double x;
    x=strtod(argv[1],NULL);
    if (argc !=2) {
       fprintf(stderr,"usage error\n");
       exit(EXIT_FAILURE);
       }
    fp=fopen( "data", "a");
    ftell(fp);
    fseek(fp,sizeof(double),SEEK_CUR);
    fprintf(fp,"%.2f\n",x);
    fclose(fp);



}

While the advice to use a debugger is good advice, the entire solution
to this problem can be found via static analysis. Splint is free:
http://www.splint.org

Here is the analysis using splint and pc-lint:

#include <stdio.h>
#include <stdlib.h>

int main ( int argc, char *argv[] ) {
FILE*fp;
double x;
x=strtod(argv[1],NULL);
if (argc !=2) {
fprintf(stderr,"usage error\n");
exit(EXIT_FAILURE);
}
fp=fopen( "data", "a");
ftell(fp);
fseek(fp,sizeof(double),SEEK_CUR);
fprintf(fp,"%.2f\n",x);
fclose(fp);
}
/*
Splint output:
==============
C:\tmp>splint bug.c
Splint 3.1.1 --- 12 Mar 2007

bug.c: (in function main)
bug.c(13,11): Possibly null storage fp passed as non-null param: ftell
(fp)
A possibly null pointer is passed as a parameter corresponding to a
formal
parameter with no /*@null@*/ annotation. If NULL may be used for
this
parameter, add a /*@null@*/ annotation to the function parameter
declaration.
(Use -nullpass to inhibit warning)
bug.c(12,8): Storage fp may become null
bug.c(13,5): Return value (type long int) ignored: ftell(fp)
Result returned by function call is not used. If this is intended,
can cast
result to (void) to eliminate message. (Use -retvalother to inhibit
warning)
bug.c(14,29): Function fseek expects arg 2 to be long int gets size_t:
sizeof(double)
To allow arbitrary integral types to match long unsigned, use
+longintegral.
bug.c(14,5): Return value (type int) ignored: fseek(fp, sizeof...
Result returned by function call is not used. If this is intended,
can cast
result to (void) to eliminate message. (Use -retvalint to inhibit
warning)
bug.c(16,5): Return value (type int) ignored: fclose(fp)
bug.c(17,2): Path with no return in function declared to return int
There is a path through a function declared to return a value on
which there
is no return statement. This means the execution may fall through
without
returning a meaningful result to the caller. (Use -noret to inhibit
warning)

Finished checking --- 6 code warnings

Lint output:
============
C:\tmp>"C:\Lint\Lint-nt" +v -i"C:\Lint" std.lnt -os(_LINT.TMP)
bug.c
PC-lint for C/C++ (NT) Vers. 8.00u, Copyright Gimpel Software
1985-2006

--- Module: bug.c (C)

C:\tmp>type _LINT.TMP | more

--- Module: bug.c (C)
_
ftell(fp);
bug.c(13) : Warning 534: Ignoring return value of function
'ftell(struct _iobuf
*)' (compare with line 257, file C:\Program Files\Microsoft Visual
Studio
8\VC\INCLUDE\stdio.h)
C:\Program Files\Microsoft Visual Studio 8\VC\INCLUDE\stdio.h(257) :
Info 830:
Location cited in prior message
_
ftell(fp);
bug.c(13) : Warning 668: Possibly passing a null pointer to function
'ftell(struct _iobuf *)', arg. no. 1 [Reference: file bug.c: line
12]
bug.c(12) : Info 831: Reference cited in prior message
_
}
bug.c(17) : Warning 533: function 'main(int, char **)' should return a
value
(see line 4)
bug.c(4) : Info 830: Location cited in prior message
_
}
bug.c(17) : Note 952: Parameter 'argv' (line 4) could be declared
const ---
Eff. C++ 3rd Ed. item 3
bug.c(4) : Info 830: Location cited in prior message
_
}
bug.c(17) : Info 818: Pointer parameter 'argv' (line 4) could be
declared as
pointing to const --- Eff. C++ 3rd Ed. item 3
bug.c(4) : Info 830: Location cited in prior message
_
}
bug.c(17) : Note 952: Parameter 'argc' (line 4) could be declared
const ---
Eff. C++ 3rd Ed. item 3
bug.c(4) : Info 830: Location cited in prior message

*/

A few minutes with Splint or PC-Lint and a C book can tell you exactly
what is wrong.
It will also behoove you to learn how to use a debugger. It is a very
bad idea to try to program by the seat of your pants (meaning making
*guesses* about what various program constructs are supposed to be
doing). If you learn the correct meanings of the language constructs
and also how to use tools at your disposal then you can learn to be an
effective programmer. If you do not learn these things then you will
never learn to be an effective programmer. It is not difficult to do
it, though it can be a bit tedious.
 
B

Bill Cunningham

Richard said:
Because I actually think you are too stuck in your ways to bother to
learn how to use one and you seem incapable of using Google I provide
you this link: (I think you mentioned you use gcc)

http://dirac.org/linux/gdb/

Read the "What is a debugger" part thoroughly.

http://dirac.org/linux/gdb/01-Introduction.php#whatisadebugger

Many people suggest using printf's. This is, IMO, amateurish at best.

From this web page:
[snip]

I use fprintfs to stderr so there's an error only if there's an error. I've
tried learning gdb. I don't read debugging symbols and gdb looks very
overwhelming atleast to me. I have it in my system and looked over the docs.
I thought about putting breakpoints into my program and gave up because
things were too complicated. With the trouble I'm having with C and I want
to stay with it I think my plate's pretty full right now. But I'll look at
your sites.

Bill
 
K

Kenny McCormack

Because I actually think you are too stuck in your ways to bother to
learn how to use one and you seem incapable of using Google I provide
you this link: (I think you mentioned you use gcc)

Let me put in a word for the other side.

The problem with debuggers (at least all the ones I've used, including
gdb), is that they are very unfriendly, and mostly undocumented. I have
no doubt that when fully understood, they are quite powerful, but I have
never been able to wrap my head around one (of the type that we are
discussing here). man pages are no help. There's no built-in help.
There's no built-in useful error messages.

To continue this rant, I'm sure if I downloaded and studied (for a few
days and/or weeks) the voluminous documentation (in some weird GNU
format), I could probably become an expert in it, but it just ain't
worth the trouble.
 
R

Richard

Bill Cunningham said:
Richard said:
Because I actually think you are too stuck in your ways to bother to
learn how to use one and you seem incapable of using Google I provide
you this link: (I think you mentioned you use gcc)

http://dirac.org/linux/gdb/

Read the "What is a debugger" part thoroughly.

http://dirac.org/linux/gdb/01-Introduction.php#whatisadebugger

Many people suggest using printf's. This is, IMO, amateurish at best.

From this web page:
[snip]

I use fprintfs to stderr so there's an error only if there's an error. I've
tried learning gdb. I don't read debugging symbols and gdb looks very
overwhelming atleast to me. I have it in my system and looked over the docs.
I thought about putting breakpoints into my program and gave up because
things were too complicated. With the trouble I'm having with C and I want
to stay with it I think my plate's pretty full right now. But I'll look at
your sites.

Bill

It is one site. And it is there to help people. It could not be
easier. If you can not follow the instructions there then you should
really consider giving up - you will never be a programmer.
 
R

Richard

Let me put in a word for the other side.

The problem with debuggers (at least all the ones I've used, including
gdb), is that they are very unfriendly, and mostly undocumented. I have
no doubt that when fully understood, they are quite powerful, but I have
never been able to wrap my head around one (of the type that we are
discussing here). man pages are no help. There's no built-in help.
There's no built-in useful error messages.

To continue this rant, I'm sure if I downloaded and studied (for a few
days and/or weeks) the voluminous documentation (in some weird GNU
format), I could probably become an expert in it, but it just ain't
worth the trouble.

Or alternatively you could just read the tutorial I linked to ....

Using a debugger is a lot easier than sprinkling prints around,
recompiling etc.

And with Bill's attention span god knows that he will mess up when he
keeps re-editing the code to add and remove printfs.
 
K

Kenny McCormack

Or alternatively you could just read the tutorial I linked to ....

Using a debugger is a lot easier than sprinkling prints around,
recompiling etc.

And with Bill's attention span god knows that he will mess up when he
keeps re-editing the code to add and remove printfs.

Like I said, I've tried. I've tried all those so-called tutorials.

There seems to be a cult associated with C debuggers, much like the cult
associated with this newsgroup. The "It was hard for me; it should be
hard for you" cult.
 
S

santosh

Bill Cunningham wrote:

[ ... ]
I use fprintfs to stderr so there's an error only if there's an error.

How do you come to this conclusion?
I've tried learning gdb. I don't read debugging symbols

It's the purpose of the debugger to read debugging symbols. You
certainly are not expected to do so.
and gdb looks
very overwhelming atleast to me.

It is a complicated program, but it is fairly easy to learn a few basic
commands that would do in your case.
I have it in my system and looked
over the docs. I thought about putting breakpoints into my program and
gave up because things were too complicated. With the trouble I'm
having with C and I want to stay with it I think my plate's pretty
full right now. But I'll look at your sites.

Why don't you try one of the many GUI drivers available for GDB like
DDD, Eclipse's built-in debugger etc.?
 
R

Richard

Like I said, I've tried. I've tried all those so-called tutorials.

There seems to be a cult associated with C debuggers, much like the cult
associated with this newsgroup. The "It was hard for me; it should be
hard for you" cult.

Hmm. I am surprised. How hard can it be to do something like "step to
next line of code" and examine the local variables?

Or to type "backtrace" when their is a seg fault?

It's this easy:

http://www.unknownroad.com/rtfm/gdbtut/gdbsegfault.html

Still, if you think it doesn't help you then all to their own.
 
S

santosh

Kenny said:
Let me put in a word for the other side.

The problem with debuggers (at least all the ones I've used, including
gdb), is that they are very unfriendly, and mostly undocumented.

The GDB manual is one of the largest of GNU's manuals.
I have no doubt that when fully understood, they are quite powerful,
but I have never been able to wrap my head around one (of the type
that we are discussing here). man pages are no help.

info gdb
There's no
built-in help.

Try typing 'help' at the GDB prompt.
There's no built-in useful error messages.

GDB has often been accused of excessive verbosity, but this accusation
is the first I'm seeing.
 
R

Richard

santosh said:
The GDB manual is one of the largest of GNU's manuals.

For a reason : it does a lot. But the CORE functionality is simple and
VERY easy to use.

Same info as the man pages normally. And I agree it is only useful for
reference - certainly not for a tutorial unless you are experienced
enough.
 

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

Similar Threads

seg fault 10
C99 Seg fault on while(), why ? 0
seg fault 11
code question 74
sh?tpile of errors 82
no error by fscanf on reading from output file 18
code 50
URGENT 1

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top