Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Getting a "Segmentation Fault" when running on Linux

Reply
Thread Tools

Getting a "Segmentation Fault" when running on Linux

 
 
Maxx
Guest
Posts: n/a
 
      12-29-2011
I'm writing this program which works like the linux command tee which
copies the standard input to standard output and to the file provided
in the command line argument. By default this program will truncate
any existing file to zero or if the option "-a" is specified on the
command line it will append the output at the end of the file. Now
this program is getting compiled error free but when i attempt to run
it i get a segmentation fault.

../exrcs401<ename.c.inc tfile
Segmentation fault.

exrcs401 is the name of the program
ename.c.inc is the input file
tfile is the output file.

here is the program:::


#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>

#ifndef BUF_SIZE
#define BUF_SIZE 1024
#endif

int
main(int argc, char *argv[])
{
int openFlags, outputFd;
mode_t filePerms;
ssize_t numRead, numWritten;
size_t len = 0;
char buf[BUF_SIZE], *tempBuf;

if (argc < 2 || strcmp(argv[1], "--help") == 0)
usageErr("%s input file or {-a:append}...\n",
argv[0]);

filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |
S_IROTH | S_IWOTH;



if (strcmp(argv[2], "-a") == 0)
openFlags = O_RDWR | O_APPEND;

else
openFlags = O_RDWR | O_CREAT | O_TRUNC;


outputFd = open(argv[1], openFlags, filePerms);
if (outputFd = -1)
errExit("opening file %s", argv[1]);

while ((numRead = read(STDIN_FILENO, buf, BUF_SIZE)) > 0)
len += numRead;
if (!tempBuf)

tempBuf = malloc(len);
if (tempBuf == NULL) {
errExit("cannot allocate");
memcpy(tempBuf, buf, numRead);

} else {
tempBuf = realloc(tempBuf, len);
memcpy(tempBuf, buf, numRead);
}

if (( write(STDOUT_FILENO, buf, numRead )) != numRead &&
( write(outputFd, tempBuf, numRead) != numRead ))
fatal("couldn't write whole buffer");

if (numRead == -1)
errExit("read");

if (close(outputFd) == -1)
errExit("close output");

exit(EXIT_SUCCESS);

}

Please help i cannot figure out the source of the problem.



 
Reply With Quote
 
 
 
 
Ben Bacarisse
Guest
Posts: n/a
 
      12-29-2011
Maxx <(E-Mail Removed)> writes:

> I'm writing this program which works like the linux command tee which
> copies the standard input to standard output and to the file provided
> in the command line argument. By default this program will truncate
> any existing file to zero or if the option "-a" is specified on the
> command line it will append the output at the end of the file. Now
> this program is getting compiled error free


Then you need more warning to be turned on. Maybe you only posted a
part of the program, but it uses functions that have no declaration
(or definition for that matter).

<snip>
> here is the program:::
>
> #include <sys/stat.h>
> #include <fcntl.h>
> #include <stdlib.h>
> #include <string.h>
>
> #ifndef BUF_SIZE
> #define BUF_SIZE 1024
> #endif
>
> int
> main(int argc, char *argv[])
> {
> int openFlags, outputFd;
> mode_t filePerms;
> ssize_t numRead, numWritten;
> size_t len = 0;
> char buf[BUF_SIZE], *tempBuf;
>
> if (argc < 2 || strcmp(argv[1], "--help") == 0)
> usageErr("%s input file or {-a:append}...\n",
> argv[0]);
>
> filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |
> S_IROTH | S_IWOTH;
>
> if (strcmp(argv[2], "-a") == 0)
> openFlags = O_RDWR | O_APPEND;
>
> else
> openFlags = O_RDWR | O_CREAT | O_TRUNC;
>
> outputFd = open(argv[1], openFlags, filePerms);
> if (outputFd = -1)


You mean == I think.

> errExit("opening file %s", argv[1]);
>
> while ((numRead = read(STDIN_FILENO, buf, BUF_SIZE)) > 0)


Big point: why are you giving yourself the hassle of using low-level IO
functions? It's way simpler to use C's standard IO library (fopen,
fread etc). If you really need to use read, you should consult
comp.unix.programmer to get all the details right.

> len += numRead;
> if (!tempBuf)


This is confusing indentation. Maybe you forgot to put this in {}s?

There is a lot else to say (you have some very odd logic below here) but
let's stick to the big stuff first.

> tempBuf = malloc(len);
> if (tempBuf == NULL) {
> errExit("cannot allocate");
> memcpy(tempBuf, buf, numRead);
>
> } else {
> tempBuf = realloc(tempBuf, len);
> memcpy(tempBuf, buf, numRead);
> }
>
> if (( write(STDOUT_FILENO, buf, numRead )) != numRead &&
> ( write(outputFd, tempBuf, numRead) != numRead ))
> fatal("couldn't write whole buffer");
>
> if (numRead == -1)
> errExit("read");
>
> if (close(outputFd) == -1)
> errExit("close output");
>
> exit(EXIT_SUCCESS);
> }

<snip>
--
Ben.
 
Reply With Quote
 
 
 
 
Nick Keighley
Guest
Posts: n/a
 
      12-29-2011
On Dec 29, 3:28*pm, Maxx <(E-Mail Removed)> wrote:

> I'm writing this program which works like the linux command tee which
> copies the standard input to standard output and to the file provided
> in the command line argument. By default this program will truncate
> any existing file to zero or if the option *"-a" is specified on the
> command line it will append the output at the end of the file. *Now
> this program is getting compiled error free but when i attempt to run
> it i get a segmentation fault.


<snip code>

> Please help i cannot figure out the source of the problem.


might help if you gave us a clue as to where it crashed.
Either stick some printf()s in or use a debugger.
 
Reply With Quote
 
Philip Lantz
Guest
Posts: n/a
 
      12-29-2011
Maxx wrote:

> ... when i attempt to run
> it i get a segmentation fault.
>
> ./exrcs401<ename.c.inc tfile
> Segmentation fault.
>
> exrcs401 is the name of the program
> ename.c.inc is the input file
> tfile is the output file.
>
>
> if (argc < 2 || strcmp(argv[1], "--help") == 0)
> usageErr("%s input file or {-a:append}...\n",
> argv[0]);
>
> if (strcmp(argv[2], "-a") == 0)


argv[2] is null.
 
Reply With Quote
 
Barry Schwarz
Guest
Posts: n/a
 
      12-29-2011
On Thu, 29 Dec 2011 07:28:16 -0800 (PST), Maxx
<(E-Mail Removed)> wrote:

>I'm writing this program which works like the linux command tee which
>copies the standard input to standard output and to the file provided
>in the command line argument. By default this program will truncate
>any existing file to zero or if the option "-a" is specified on the
>command line it will append the output at the end of the file. Now
>this program is getting compiled error free but when i attempt to run
>it i get a segmentation fault.
>
>./exrcs401<ename.c.inc tfile
>Segmentation fault.
>
>exrcs401 is the name of the program
>ename.c.inc is the input file
>tfile is the output file.
>
>here is the program:::
>
>
>#include <sys/stat.h>
>#include <fcntl.h>
>#include <stdlib.h>
>#include <string.h>
>
>#ifndef BUF_SIZE
>#define BUF_SIZE 1024
>#endif
>
>int
>main(int argc, char *argv[])
>{
> int openFlags, outputFd;
> mode_t filePerms;
> ssize_t numRead, numWritten;
> size_t len = 0;
> char buf[BUF_SIZE], *tempBuf;
>
> if (argc < 2 || strcmp(argv[1], "--help") == 0)
> usageErr("%s input file or {-a:append}...\n",
> argv[0]);
>
> filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |
> S_IROTH | S_IWOTH;
>
>
>
> if (strcmp(argv[2], "-a") == 0)
> openFlags = O_RDWR | O_APPEND;
>
> else
> openFlags = O_RDWR | O_CREAT | O_TRUNC;
>
>
> outputFd = open(argv[1], openFlags, filePerms);
> if (outputFd = -1)
> errExit("opening file %s", argv[1]);


Where is this function declared?

>
> while ((numRead = read(STDIN_FILENO, buf, BUF_SIZE)) > 0)
> len += numRead;
> if (!tempBuf)


Where is tempBuf provided a value. It is not initialized in the
definition. Its value is indeterminate and you have no idea how this
if evaluates. If it is not set to NULL by default in your compiler,
this if evaluates to false and ...

>
> tempBuf = malloc(len);
> if (tempBuf == NULL) {
> errExit("cannot allocate");


Does errExit actually return?

> memcpy(tempBuf, buf, numRead);


I think you have your braces mixed up. This call to memcpy is
executed only when tempBuf is NULL and you cannot copy into the area
pointed to by NULL. Dereferencing a NULL pointer is a frequent cause
of seg faults.

>
> } else {
> tempBuf = realloc(tempBuf, len);


.... you invoke undefined behavior by passing realloc a value that is
neither NULL nor the result of a previous call to {m|c|re}alloc.
Passing such a value to free or {c|re}alloc is also a frequent cause
of seg faults.

> memcpy(tempBuf, buf, numRead);
> }
>
> if (( write(STDOUT_FILENO, buf, numRead )) != numRead &&
> ( write(outputFd, tempBuf, numRead) != numRead ))
> fatal("couldn't write whole buffer");
>
> if (numRead == -1)
> errExit("read");
>
> if (close(outputFd) == -1)
> errExit("close output");
>
> exit(EXIT_SUCCESS);
>
>}
>
>Please help i cannot figure out the source of the problem.


Have you tried using a debugger?

--
Remove del for email
 
Reply With Quote
 
Joe Pfeiffer
Guest
Posts: n/a
 
      12-30-2011
Maxx <(E-Mail Removed)> writes:

> I'm writing this program which works like the linux command tee which
> copies the standard input to standard output and to the file provided
> in the command line argument. By default this program will truncate
> any existing file to zero or if the option "-a" is specified on the
> command line it will append the output at the end of the file. Now
> this program is getting compiled error free but when i attempt to run
> it i get a segmentation fault.
>
> ./exrcs401<ename.c.inc tfile
> Segmentation fault.


The first thing you need in tracking it down is the location of the seg
fault. Put in a bunch of printfs, e.g.

> exrcs401 is the name of the program
> ename.c.inc is the input file
> tfile is the output file.
>
> here is the program:::
>
>
> #include <sys/stat.h>
> #include <fcntl.h>
> #include <stdlib.h>

#include <stdio.h> // so you'll have stderr
> #include <string.h>
>
> #ifndef BUF_SIZE
> #define BUF_SIZE 1024
> #endif
>
> int
> main(int argc, char *argv[])
> {
> int openFlags, outputFd;
> mode_t filePerms;
> ssize_t numRead, numWritten;
> size_t len = 0;
> char buf[BUF_SIZE], *tempBuf;


fprintf(stderr, "checkpoint 1\n");

> if (argc < 2 || strcmp(argv[1], "--help") == 0)
> usageErr("%s input file or {-a:append}...\n",
> argv[0]);
>
> filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |
> S_IROTH | S_IWOTH;
>
>
>
> if (strcmp(argv[2], "-a") == 0)
> openFlags = O_RDWR | O_APPEND;
>
> else
> openFlags = O_RDWR | O_CREAT | O_TRUNC;
>
>
> outputFd = open(argv[1], openFlags, filePerms);
> if (outputFd = -1)
> errExit("opening file %s", argv[1]);


fprintf(stderr, "checkpoint 2\n");
> while ((numRead = read(STDIN_FILENO, buf, BUF_SIZE)) > 0)
> len += numRead;
> if (!tempBuf)


<snip>

> Please help i cannot figure out the source of the problem.


And, of course, once you know where the crash is occurring you can start
putting in printf's that tell the value of key variables.

Another (and in the long term better) alternative would be to run it in
a debugger like gdb and simply have it tell you where it crashed.
 
Reply With Quote
 
Maxx
Guest
Posts: n/a
 
      01-01-2012
On Dec 29 2011, 7:47*am, Ben Bacarisse <(E-Mail Removed)> wrote:
> Maxx <(E-Mail Removed)> writes:
> > I'm writing this program which works like the linux command tee which
> > copies the standard input to standard output and to the file provided
> > in the command line argument. By default this program will truncate
> > any existing file to zero or if the option *"-a" is specified on the
> > command line it will append the output at the end of the file. *Now
> > this program is getting compiled error free

>
> Then you need more warning to be turned on. *Maybe you only posted a
> part of the program, but it uses functions that have no declaration
> (or definition for that matter).
>
> <snip>
>
>
>
>
>
>
>
>
>
> > here is the program:::

>
> > #include <sys/stat.h>
> > #include <fcntl.h>
> > #include <stdlib.h>
> > #include <string.h>

>
> > #ifndef BUF_SIZE
> > #define BUF_SIZE 1024
> > #endif

>
> > int
> > main(int argc, char *argv[])
> > {
> > * * int openFlags, outputFd;
> > * * mode_t filePerms;
> > * * ssize_t numRead, numWritten;
> > * * size_t len = 0;
> > * * char buf[BUF_SIZE], *tempBuf;

>
> > * * if (argc < 2 || strcmp(argv[1], "--help") == 0)
> > * * * * usageErr("%s input file or {-a:append}...\n",
> > * * * * * * * * * argv[0]);

>
> > * * filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |
> > * * * * * * * * S_IROTH | S_IWOTH;

>
> > * * if (strcmp(argv[2], "-a") == 0)
> > * * * * openFlags = O_RDWR | O_APPEND;

>
> > * * else
> > * * * * openFlags = O_RDWR | O_CREAT | O_TRUNC;

>
> > * * outputFd = open(argv[1], openFlags, filePerms);
> > * * if (outputFd = -1)

>
> You mean == I think.
>
> > * * * * errExit("opening file %s", argv[1]);

>
> > * * while ((numRead = read(STDIN_FILENO, buf, BUF_SIZE)) > 0)

>
> Big point: why are you giving yourself the hassle of using low-level IO
> functions? *It's way simpler to use C's standard IO library (fopen,
> fread etc). *If you really need to use read, you should consult
> comp.unix.programmer to get all the details right.
>
> > * * * * len += numRead;
> > * * * * if (!tempBuf)

>
> This is confusing indentation. *Maybe you forgot to put this in {}s?
>
> There is a lot else to say (you have some very odd logic below here) but
> let's stick to the big stuff first.
>
>
>
>
>
>
>
>
>
> > * * * * * * tempBuf = malloc(len);
> > * * * * * * if (tempBuf == NULL) {
> > * * * * * * * * errExit("cannot allocate");
> > * * * * * * * * memcpy(tempBuf, buf, numRead);

>
> > * * * * * * } else {
> > * * * * * * * * tempBuf = realloc(tempBuf, len);
> > * * * * * * * * memcpy(tempBuf, buf, numRead);
> > * * * * * * }

>
> > * * * * if (( write(STDOUT_FILENO, buf, numRead )) != numRead&&
> > * * * * * * ( write(outputFd, tempBuf, numRead) != numRead ))
> > * * * * * * * * fatal("couldn't write whole buffer");

>
> > * * if (numRead == -1)
> > * * * * errExit("read");

>
> > * * if (close(outputFd) == -1)
> > * * * * errExit("close output");

>
> > * * exit(EXIT_SUCCESS);
> > }

>
> <snip>
> --
> Ben.


I was learning system programming on linux so i was using the system
calls in this program.


> > len += numRead;
> > if (!tempBuf)

>
> This is confusing indentation. Maybe you forgot to put this in {}s?
>
> There is a lot else to say (you have some very odd logic below here) but
> let's stick to the big stuff first.


Here i intended tempbuf to store the dynamically allocated memory
which if not already allocated (hence the check "if (!tempbuf)") then
will be allocated using malloc() else if tempbuf already points to a
memory location then it will be resized to the new size stored in len
using realloc().
Yeah i know by logics are a lot fuzzy cause i was just starting out
this system programming thing and still got a lots to learn.

Thanks
Maxx
 
Reply With Quote
 
Maxx
Guest
Posts: n/a
 
      01-01-2012
On Dec 29 2011, 7:56*am, Nick Keighley
<(E-Mail Removed)> wrote:
> On Dec 29, 3:28*pm, Maxx <(E-Mail Removed)> wrote:
>
> > I'm writing this program which works like the linux command tee which
> > copies the standard input to standard output and to the file provided
> > in the command line argument. By default this program will truncate
> > any existing file to zero or if the option *"-a" is specified on the
> > command line it will append the output at the end of the file. *Now
> > this program is getting compiled error free but when i attempt to run
> > it i get a segmentation fault.

>
> <snip code>
>
> > Please help i cannot figure out the source of the problem.

>
> might help if you gave us a clue as to where it crashed.
> Either stick some printf()s in or use a debugger.


Thats the thing i tried using printf() almost everywhere in the
program even right in the part after all the declarations are but the
program still gives Segmentation fault without printing any other
message whatsoever..
 
Reply With Quote
 
Maxx
Guest
Posts: n/a
 
      01-01-2012
On Dec 29 2011, 9:49*am, Barry Schwarz <(E-Mail Removed)> wrote:
> On Thu, 29 Dec 2011 07:28:16 -0800 (PST), Maxx
>
>
>
>
>
>
>
>
>
> <(E-Mail Removed)> wrote:
> >I'm writing this program which works like the linux command tee which
> >copies the standard input to standard output and to the file provided
> >in the command line argument. By default this program will truncate
> >any existing file to zero or if the option *"-a" is specified on the
> >command line it will append the output at the end of the file. *Now
> >this program is getting compiled error free but when i attempt to run
> >it i get a segmentation fault.

>
> >./exrcs401<ename.c.inc tfile
> >Segmentation fault.

>
> >exrcs401 is the name of the program
> >ename.c.inc is the input file
> >tfile is the output file.

>
> >here is the program:::

>
> >#include <sys/stat.h>
> >#include <fcntl.h>
> >#include <stdlib.h>
> >#include <string.h>

>
> >#ifndef BUF_SIZE
> >#define BUF_SIZE 1024
> >#endif

>
> >int
> >main(int argc, char *argv[])
> >{
> > * *int openFlags, outputFd;
> > * *mode_t filePerms;
> > * *ssize_t numRead, numWritten;
> > * *size_t len = 0;
> > * *char buf[BUF_SIZE], *tempBuf;

>
> > * *if (argc < 2 || strcmp(argv[1], "--help") == 0)
> > * * * *usageErr("%s input file or {-a:append}...\n",
> > * * * * * * * * *argv[0]);

>
> > * *filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |
> > * * * * * * * *S_IROTH | S_IWOTH;

>
> > * *if (strcmp(argv[2], "-a") == 0)
> > * * * *openFlags = O_RDWR | O_APPEND;

>
> > * *else
> > * * * *openFlags = O_RDWR | O_CREAT | O_TRUNC;

>
> > * *outputFd = open(argv[1], openFlags, filePerms);
> > * *if (outputFd = -1)
> > * * * *errExit("opening file %s", argv[1]);

>
> Where is this function declared?
>
>

This custom error functions are all declared in "tlpi_hdr.h". and they
work fine i've tested them in other programs


>
> > * *while ((numRead = read(STDIN_FILENO, buf, BUF_SIZE)) > 0)
> > * * * *len += numRead;
> > * * * *if (!tempBuf)

>
> Where is tempBuf provided a value. *It is not initialized in the
> definition. *Its value is indeterminate and you have no idea how this
> if evaluates. *If it is not set to NULL by default in your compiler,
> this if evaluates to false and ...
>
>

Yeah i get it leaving tempbuf with an indeterminate value must have
been the source of the error.
I wasn't aware of this at all.

>
> > * * * * * *tempBuf = malloc(len);
> > * * * * * *if (tempBuf == NULL) {
> > * * * * * * * *errExit("cannot allocate");

>
> Does errExit actually return?
>
> > * * * * * * * *memcpy(tempBuf, buf, numRead);

>
> I think you have your braces mixed up. *This call to memcpy is
> executed only when tempBuf is NULL and you cannot copy into the area
> pointed to by NULL. *Dereferencing a NULL pointer is a frequent cause
> of seg faults.
>
>
>
> > * * * * * *} else {
> > * * * * * * * *tempBuf = realloc(tempBuf, len);

>
> ... you invoke undefined behavior by passing realloc a value that is
> neither NULL nor the result of a previous call to {m|c|re}alloc.
> Passing such a value to free or {c|re}alloc is also a frequent cause
> of seg faults.
>
>
>
>
>
>
>
>
>
> > * * * * * * * *memcpy(tempBuf, buf, numRead);
> > * * * * * *}

>
> > * * * *if (( write(STDOUT_FILENO, buf, numRead )) != numRead &&
> > * * * * * *( write(outputFd, tempBuf, numRead) != numRead))
> > * * * * * * * *fatal("couldn't write whole buffer");

>
> > * *if (numRead == -1)
> > * * * *errExit("read");

>
> > * *if (close(outputFd) == -1)
> > * * * *errExit("close output");

>
> > * *exit(EXIT_SUCCESS);

>
> >}

>
> >Please help i cannot figure out the source of the problem.

>
> Have you tried using a debugger?
>


No i haven't but i did used the printf() technique pointed out by the
others in this board. Anyways i think that tempbuf thing was the
source of the problem, i will fix it right away. Thanks a lot.

Thanks
Maxx
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      01-01-2012
Maxx <(E-Mail Removed)> writes:

> On Dec 29 2011, 7:47*am, Ben Bacarisse <(E-Mail Removed)> wrote:

<snip>
>> > len += numRead;
>> > if (!tempBuf)

>>
>> This is confusing indentation. Maybe you forgot to put this in {}s?
>>
>> There is a lot else to say (you have some very odd logic below here) but
>> let's stick to the big stuff first.

>
> Here i intended tempbuf to store the dynamically allocated memory
> which if not already allocated (hence the check "if (!tempbuf)") then
> will be allocated using malloc() else if tempbuf already points to a
> memory location then it will be resized to the new size stored in len
> using realloc().


That was obvious. What was no obvious is why you had the "if" outside
the while loop. Only "len += numRead;" is in the while loop. That did
not look like what you wanted.

Also, tempBuf was not initialised so the test is undefined -- anything
could happen.

<snip>
--
Ben.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Getting GUI for ruby for Linux running (QT or wxWidget)? Markus Fischer Ruby 22 09-25-2010 01:27 PM
Re: Is Netscape Leaving Firefox Behind on GNU/Linux? THE LINUX PROPAGANDA MACHINE CONTINUES. FIREFOX IGNORING LINUX............. traci.manicotti@gmail.com Computer Support 2 10-20-2007 02:12 PM
Linux... yeah linux.. Linux Have a nice cup of pee NZ Computing 19 04-17-2006 10:16 AM
Want to dual boot XP & Linux - Getting new PC - Will it work with Linux? Alan NZ Computing 55 09-11-2005 12:50 AM
Getting the KVM running on ARM Linux on an ARM processor based device Steve Jasper Java 0 11-20-2003 06:55 PM



Advertisments