gsgs
Posts: 134
Joined: Sun Dec 13, 2015 6:48 pm
Location: Germany
Contact: Website

segmentation fault with gcc

Sun Dec 27, 2015 9:35 am

I tried to compile C programs on the Rpi2B with Raspbian that I had compiled with gcc
and run successfully before on Windows' cmd.exe (DOS-commandline)

One common error was that my editor included ascii 26 at fileend , that is fixed now.
Another error was, that gcc on the Rpi2B doesn't accept my exit(x); commands,
they are replaced by goto program end commands now, that worked.

Now I get segmentation fault errors on some(most) programs at runtime,
after they compiled well, while some other similar programs ran well

User avatar
PeterO
Posts: 5132
Joined: Sun Jul 22, 2012 4:14 pm

Re: segmentation fault with gcc

Sun Dec 27, 2015 10:03 am

Do you know how to use a debugger (e.g.gdb) ?

If not these might help:
https://www.cs.cmu.edu/~gilpin/tutorial/
http://web.eecs.umich.edu/~sugih/pointers/gdbQS.html
PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

User avatar
RogerW
Posts: 286
Joined: Sat Dec 20, 2014 12:15 pm
Location: London UK

Re: segmentation fault with gcc

Sun Dec 27, 2015 11:12 am

Can you create a small program that shows the problem? If you can post the code and it may be someone can spot what is going wrong.

Segmentation faults can be caused by using a pointer that is incorrect - this will often show up differently on different platforms.

User avatar
PeterO
Posts: 5132
Joined: Sun Jul 22, 2012 4:14 pm

Re: segmentation fault with gcc

Sun Dec 27, 2015 11:24 am

RogerW wrote:Can you create a small program that shows the problem? If you can post the code and it may be someone can spot what is going wrong.
It sounds to me that the OP has little idea where the problem lies, so I would say that your suggestion is a step that comes after running the original code with a debugger.
PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

sprinkmeier
Posts: 410
Joined: Mon Feb 04, 2013 10:48 am
Contact: Website

Re: segmentation fault with gcc

Sun Dec 27, 2015 12:10 pm

gsgs wrote:...
Another error was, that gcc on the Rpi2B doesn't accept my exit(x); commands,
they are replaced by goto program end commands now, that worked.
...
what's the error message?
learning to decode compiler error messages is hugely valuable, so even if your solution is acceptable to you it's a good idea to figure out why exit is deemed unacceptable to gcc.

(BTW, "don't use goto" is one of those rules that you shouldn't break until you can explain exactly why)

User avatar
rpdom
Posts: 15572
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: segmentation fault with gcc

Sun Dec 27, 2015 12:23 pm

I'm a real noob at C programming (been trying to find ways not to use it for over 20 years now ;)). I found that I needed to #include <stdlib.h> for exit(x) to work.

Code: Select all

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

int main()
{
  printf( "Hello Ankh Morpork!\n" );
  exit(0);
}
That seems to work for me.

User avatar
PeterO
Posts: 5132
Joined: Sun Jul 22, 2012 4:14 pm

Re: segmentation fault with gcc

Sun Dec 27, 2015 1:25 pm

rpdom wrote:I'm a real noob at C programming (been trying to find ways not to use it for over 20 years now ;)). I found that I needed to #include <stdlib.h> for exit(x) to work.
"man" is your friend ! The manual page for exit clearly shows that stdlib.h needs to be included. There is no need to "find" these things out.

Code: Select all

EXIT(3)                    Linux Programmer's Manual                   EXIT(3)

NAME
       exit - cause normal process termination

SYNOPSIS
       #include <stdlib.h>

       void exit(int status);

PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

gsgs
Posts: 134
Joined: Sun Dec 13, 2015 6:48 pm
Location: Germany
Contact: Website

Re: segmentation fault with gcc

Sun Dec 27, 2015 1:29 pm

it's difficult for me to do things in Linux and today I have no access to the TV for the raspberry.
The programs did all run in Windows and they compiled well on Raspbian.
And I don;t think it's the RAM-limit since one program with much RAM worked well

Yes, I will do some debugging later, when there is no easy solution/idea,
if this hadn't come up before

I don't remember the error message for the exit commands, but it showed the lines
and it could be easily fixed.

I assume exit(x) reports error-code x , whose interpretation is system-dependent

including stdlib is an idea ... not because of the exit(), but I speculate there is a chance of 10%
that it easily fixes the segmentation fault, so I'll try that

gsgs
Posts: 134
Joined: Sun Dec 13, 2015 6:48 pm
Location: Germany
Contact: Website

Re: segmentation fault with gcc

Sun Dec 27, 2015 1:37 pm

usually my programs display a "usage:" message when run without parameters

e.g.
if(argc<2){printf("usage:filtentr file position segments \n");
printf(...
printf(...
goto m99;}

...

m99:;fclose(file);

}

and then, when run without parameters on the Rpi2B, (./filtentr) it displays the message
and then reports segmentation fault


hmm, fclose(file) when it had not been opened could do this ?
No problem with that in Windows, though (GCC 3.2 , DJGPP)

however the program that worked had no m99:fclose(file); at the end, just m99:;

User avatar
PeterO
Posts: 5132
Joined: Sun Jul 22, 2012 4:14 pm

Re: segmentation fault with gcc

Sun Dec 27, 2015 2:58 pm

So, here's a technique to help....

Where possible initialise variables to illegal or impossible values, then before using them check they have a valid value.

Code: Select all

int fd = -1;

if(valid_input())
{
.....
  fd = open(......)
.....
}

if(fd != -1) close(fd);
Note that file descriptors should be assigned to signed integers, but only positive values are returned from open() when successful.

PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

gsgs
Posts: 134
Joined: Sun Dec 13, 2015 6:48 pm
Location: Germany
Contact: Website

Re: segmentation fault with gcc

Sun Dec 27, 2015 4:20 pm

variables are not initialized as zero ?

User avatar
PeterO
Posts: 5132
Joined: Sun Jul 22, 2012 4:14 pm

Re: segmentation fault with gcc

Sun Dec 27, 2015 5:04 pm

gsgs wrote:variables are not initialized as zero ?
Some are, some aren't.

Code: Select all

#include <stdio.h>

int a;

void f(void)
{
int c;

        printf("c=%d\n",c);
}


int main(int argc,char **argv)
{
int b;

        printf("a=%d b=%d\n",a,b);
        f();
}

produces

Code: Select all

a=0 b=0
c=32529
Note: The value of c is not always the same!

Also I suggested using invalid values to detect the use on uninitialised variables, and zero IS a valid value for a file descriptor !

PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

gsgs
Posts: 134
Joined: Sun Dec 13, 2015 6:48 pm
Location: Germany
Contact: Website

Re: segmentation fault with gcc

Sun Dec 27, 2015 5:28 pm

this one, compiled fine but segmentation fault when run without parameters ./names

Code: Select all


# define N 199999999
# define M 3543
#include <stdio.h>

int f,g,i,j,k,x,y,a,b,s,z,m,n,maxl;
int Ns,Nn;
unsigned char name[M],A[N];
FILE *file,*file1;


//------------------------------------------------------------
int main(int argc,char*argv[]){
  if(argc<2){printf("\nusage:names file [file2] [dummy]\n\n");
             printf("prints the names from the 1-segment records in file\n");
             printf("if file2 is specified then it replaces the names\n");
             printf("in flu-file by those in names-file2\n\n");
             printf("dummy --> sequences\n\n");
       goto m3;}

...

m3:fclose(file);fclose(file1);


}


User avatar
buja
Posts: 507
Joined: Wed Dec 31, 2014 8:21 am
Location: Netherlands

Re: segmentation fault with gcc

Sun Dec 27, 2015 5:51 pm

As already mentioned above, you are trying to close files that were never opened and Linux does not like that. I am surprised that Windows let you get away with it, maybe it hides the error message?

Get rid of the goto statements and replace them with exit() (and #include <stdlib.h>). I don't think exit() was the (single) cause of failure anyway.

User avatar
RogerW
Posts: 286
Joined: Sat Dec 20, 2014 12:15 pm
Location: London UK

Re: segmentation fault with gcc

Sun Dec 27, 2015 5:52 pm

> this one, compiled fine but segmentation fault when run without parameters ./names

That is hardly surprising.

You have declared file and file1 to be pointers to FILE but you have not initialised them so they contain whatever junk was on the stack.

You then call fclose passing what is almost certainly an invalid pointer so it is hardly surprising that you get a segmentation fault.

User avatar
PeterO
Posts: 5132
Joined: Sun Jul 22, 2012 4:14 pm

Re: segmentation fault with gcc

Sun Dec 27, 2015 6:32 pm

The true problem becomes instantly obvious if you run it under gdb !
PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

User avatar
PeterO
Posts: 5132
Joined: Sun Jul 22, 2012 4:14 pm

Re: segmentation fault with gcc

Sun Dec 27, 2015 6:56 pm

RogerW wrote: You have declared file and file1 to be pointers to FILE but you have not initialised them so they contain whatever junk was on the stack.
You then call fclose passing what is almost certainly an invalid pointer so it is hardly surprising that you get a segmentation fault.
Sorry, but you are not quite right. file and file1 are globals so they are not on the stack but are being initialised to NULL, so fclose is being passed NULL causing a segmentation fault.

PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

stderr
Posts: 2178
Joined: Sat Dec 01, 2012 11:29 pm

Re: segmentation fault with gcc

Sun Dec 27, 2015 7:29 pm

gsgs wrote:this one, compiled fine but segmentation fault when run without parameters ./names

Code: Select all

int main(int argc,char*argv[]){
  if(argc<2){
     printf("\nusage:names file [file2] [dummy]\n\n");
     goto m3;
  }
m3:fclose(file);fclose(file1);
}
When you check the arguments for logical consistency in your other programs, do you then jump to something that closes files and does other things that you never even got into because you found out that the arguments didn't make sense? Does this work for you in other cases?

In other ways of dealing with these issues, perhaps using other languages, the scope of, say, the open file would be clear, for example using with in Python. But by using a goto and global variables, you don't really know where the open file scope should logically end and it should be closed. You just guessed that it was at the fclose and went with it, but you could've put that fclose anywhere including a place that was wrong for the fclose itself. So this guess introduced a bug because in the case of incorrect command line arguments, the file was never opened in the first place.

gsgs
Posts: 134
Joined: Sun Dec 13, 2015 6:48 pm
Location: Germany
Contact: Website

Re: segmentation fault with gcc

Mon Dec 28, 2015 9:41 am

yes, it was the fclose ! Thanks.
Well, some other programs had a segmentation fault presumably because too much
memory was requested.

I had lots of exit(x) commands, most were when the file was already opened.
I had replaced those with gotos to the end, and thought closing a nonopened file would be ok.
No problem on Windows.

2 other errors : getch - command , label at end of compound statement

I forgot to test including stdlib -- may solve getch and exit ? [not needed in Windows]
I'll edit this post later with the result [I can't yet edit files on the Rpi]

----------edit--------including stdlib had no effect-----------------

global variables are initialized as zero ?
Last edited by gsgs on Mon Dec 28, 2015 3:15 pm, edited 1 time in total.

User avatar
RogerW
Posts: 286
Joined: Sat Dec 20, 2014 12:15 pm
Location: London UK

Re: segmentation fault with gcc

Mon Dec 28, 2015 10:57 am

> global variables are initialized as zero ?

Yes - as Peter() correctly pointed out. The C standard requires static variables to be initialized. However it may be considered good practice to expicitly initialize thus.

FILE *file = NULL;

You should also consider whether these variables need to be global. Because globals can be accessed from anywhere in your code file they are a potential source of bugs. Personally I prefer to avoid globals unless there is no reasonable alternative.

gsgs
Posts: 134
Joined: Sun Dec 13, 2015 6:48 pm
Location: Germany
Contact: Website

Re: segmentation fault with gcc

Mon Dec 28, 2015 4:55 pm

otoh being initialized as zero is an advantage
and you have a better overview, how much is used in total
and usually, when I have subroutines, they use those variables too

And while we're at it ... I'd like a command
unsigned char A[xx% of the memory available];
I may have known howto, but forgot

User avatar
buja
Posts: 507
Joined: Wed Dec 31, 2014 8:21 am
Location: Netherlands

Re: segmentation fault with gcc

Mon Dec 28, 2015 7:36 pm

gsgs wrote:and usually, when I have subroutines, they use those [global] variables too
Wow, back to the dark ages of programming :!:

User avatar
buja
Posts: 507
Joined: Wed Dec 31, 2014 8:21 am
Location: Netherlands

Re: segmentation fault with gcc

Mon Dec 28, 2015 8:15 pm

(post deleted, not relevant here)

swampdog
Posts: 265
Joined: Fri Dec 04, 2015 11:22 am

Re: segmentation fault with gcc

Thu Dec 31, 2015 1:00 am

gsgs wrote:otoh being initialized as zero is an advantage
and you have a better overview, how much is used in total
and usually, when I have subroutines, they use those variables too
I dunno if this helps or will be more confusing..

Code: Select all

$ nano -w c.c

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

bool
OpenMe(FILE **fpp, const char f[], const char m[])
{
 if (*fpp)      {
        fprintf(stderr,"Pointer %lx uninitialised/open?\n",*fpp);
        exit (1);
 }
 return *fpp = fopen(f,m);
}

bool
CloseMe(FILE **fpp)
{
 #if 0
 if (NULL == (*fpp))    {
        fprintf(stderr,"Pointer at *address %lx is null\n",fpp);
        exit (1);
 }
 #endif
 if (*fpp)      {
        fclose(*fpp);
        *fpp = NULL;
 }
}

int
main()
{FILE   *fpa    =NULL,
        *fpb    =NULL;

 OpenMe(&fpa,"./a.txt","r");
 OpenMe(&fpb,"./b.txt","r");

 printf("fpa=%lx, fpb=%lx\n",fpa,fpb);

 CloseMe(&fpb);
 CloseMe(&fpa);
}

$ gcc -o c -std=c11 -pedantic -Werror c.c && touch a.txt && ./c
..it gives an idea how you can put wrappers around things to stop them breaking so easily.
gsgs wrote:And while we're at it ... I'd like a command
unsigned char A[xx% of the memory available];
I may have known howto, but forgot
You can't (easily). If you don't know at compile-time how much memory you need then just "malloc" the required amount of memory at run-time once you do know (and "free" it after, provided the malloc worked). Most systems these days will allow you to obtain more memory than exists (paging) and even if you are prepared to talk directly to the operating system it can still be difficult to even figure out what xx% of memory even means. Look at the 'top' command for instance: there often isn't any free memory on a unix system because when there is, the operating system grabs most of it for itself. When an application wants some the OS hands back enough to let the app get the memory it asked for.

Return to “C/C++”