0

How can I identify where the problem in the code with SegFault is?

  1. Is it a bad practice to send FILE pointers to other functions?
  2. Does append mode cause any problem?

Following program is a SIC macro processor, without worrying about the logic about the program can you identify any common errors causing SegFault?

Input.txt(The only input file, remaining files are created by program)

SAMPLE  START   1000
MACROS  MACRO   -
SUM     MACRO   &A,&B,&C
-       LDA     &A
-       ADD     &B
-       MOV     &C,&A
-       MEND    -
DIF     MACRO   &A,&B,&C
-       LDA     &A
-       SUB     &B
-       MOV     &C,&A
-       MEND    -
-       MEND    -
-       SUM     TWO,ONE,APLHA
-       SUB     TWO,ONE,BETA
ONE     WORD    1
TWO     WORD    2
ALPHA   RESW    1
BETA    RESW    1
-       END     -

If I run this in code blocks it is just creating the file inter.txt but nothing after that is being done. I tried adding a line to inter.txt right after opening it the first time , but that is also not happening (Only empty file is created)

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
void processline(FILE**,FILE**);
void define();
void expand();
char label[10],mn[10],oper[10];

void macrop()
{
    FILE *finter;
    finter=fopen("inter.txt","a+");
    fprintf(finter,"HI");
    FILE *f;
    f=fopen("input.txt","r");
    fscanf(f,"%s%s%s",label,mn,oper);
    fprintf(finter,"%s\t%s\t%s",label,mn,oper);
    fscanf(f,"%s%s%s",label,mn,oper);
    while(strcmp(mn,"END")!=0)
    {
        processline(&f,&finter);
        fscanf(f,"%s%s%s",label,mn,oper);
    }
    fprintf(finter,"%s\t%s\t%s",label,mn,oper);
    fclose(finter);
    fclose(f);
}

void processline(FILE** f,FILE** finter)
{
    FILE *fnam;
    unsigned long int p;
    char name[10];
    fnam=fopen("namtab.txt","r");
    fscanf(fnam,"%s %lu",name,&p);
    while(!feof(fnam))
    {
        if(strcmp(name,label)==0)
        {
            expand(finter,p);
            fclose(fnam);
            return;
        }
    fscanf(fnam,"%s%lu",name,&p);
    }
    if(strcmp(mn,"MACRO")==0)
    {
        fclose(fnam);
        define(f);
    }
    else
    fprintf(*finter,"%s\t%s\t%s",label,mn,oper);
    fclose(fnam);
}
void define(FILE** f)
{
    char *token;
    char *args[10];
    int level,j,i;
    i=0;
    level =1;
    FILE *fdef,*fnam;
    fdef=fopen("deftab.txt","a+");
    fnam=fopen("namtab.txt","a+");
    fprintf(fnam,"%s\t%lu\n",label,ftell(fdef));
    while(level>0)
    {
        fscanf(*f,"%s%s%s",label,mn,oper);
        if(strcmp(mn,"MACRO")==0)
        {
            level+=1;
            fprintf(fnam,"%s\t%lu\n",label,ftell(fdef));
            token=strtok(oper,",");
            while(token!=NULL)
        {
                args[i]=token;
                token=strtok(NULL,",");
                i++;
        }
        }
        else if(strcmp(mn,"MEND")==0)
        {
            level-=1;
            i=0;
            fprintf(fdef,"%s\t%s\t%s\n",label,mn,oper);
        }
        else
        {
        fprintf(fdef,"%s\t%s\t",label,mn);
        token=strtok(oper,",");
        while(token!=NULL)
        {
                if(token[0]=='&')
                {
                    j=0;
                    while(strcmp(token,args[j])!=0)
                    {
                        j++;
                    }
                    fprintf(fdef,"?%d",j);
                }
                else
                {
                fprintf(fdef,"%s\n",token);
                }
            }
        }

    }
    fclose(fdef);
    fclose(fnam);
}
void expand(FILE **finter,unsigned long int p)
{
    FILE * fdef;
    int i,c;
    i=0;
    c=0;
    char * args[10];
    char l[10],m[10],o[10];
    char *token;
    token=strtok(oper,",");
    while(token!=NULL)
    {
        args[i]=token;
        token=strtok(NULL,",");
        i++;
    }
    fdef=fopen("deftab.txt","r");
    fseek(fdef,p,SEEK_SET);
    fscanf(fdef,"%s%s%s",l,m,o);
    while(strcmp(m,"MEND")!=0)
    {
        c=0;
        fprintf(*finter,"%s\t%s\t",l,m);
        token=strtok(o,",");
        while(token!=NULL)
        {
           if(token[0]=='?')
           {
               if(c==1)
               fprintf(*finter,",");
               char a[2];
               a[0]=token[1];
               a[1]='\0';
               fprintf(*finter,"%s",args[atoi(a)]);
    }
            else
            {
                if(c==1)
                fprintf(*finter,",");
                fprintf(fdef,"%s",token);
            }
            c++;
            token=strtok(NULL,",");
        }
        fprintf(*finter,"\n");
        fscanf(fdef,"%s%s%s",l,m,o);
    }
fclose(fdef);
}
int main()
{
    macrop();
    return 0;
}
πTh0n
  • 75
  • 1
  • 1
  • 6
  • "Is it a bad practice to send FILE pointers to other functions?" - NO, in fact it is preferred. That way the file is opened and validated open in the caller before passing the open file stream as a parameter. If the file-open fails -- there is no need to call the function. After the call to `fnam=fopen("namtab.txt","r");` you must validate `if (fnam == NULL) { /* file open failed - handle error */ }` before you first attempt to read from the file stream. – David C. Rankin Nov 19 '18 at 05:59
  • I would suspect your problem is closely related to not having learned [**Why is while ( !feof (file) ) always wrong?**](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong). Make the changes needed and then edit your question (do not delete any of the original), and ***add*** your new results at the bottom of your current question. – David C. Rankin Nov 19 '18 at 06:02
  • 1
    Use a debugger like GDB while compiling the program – Vyshak Puthusseri Nov 19 '18 at 06:22

1 Answers1

0

How can I identify where the problem in the code with SegFault is?

You run it under debugger. On Linux, GDB is the most often used one. LLDB can also be used.

If you are on a supported platform, you could also build your program with Address Sanitizer (-fsanitize=address), which will likely point you straight at your bug(s).

Is it a bad practice to send FILE pointers to other functions?

Not at all. Passing FILE ** is quite unusual though.

Does append mode cause any problem?

Probably not. Your program requires a bunch of input files, and you didn't provide their contents, so it's impossible to tell where your program crashes for you.

Following program is a SIC macro processor, without worrying about the logic about the program can you identify any common errors causing SegFault?

The common errors I see:

  1. Not checking the result of fopen (this causes your program to crash for me -- I didn't create all the required files).
  2. Using fscanf with very small input buffers -- if the strings that you read are longer than 10 characters, you'll have buffer overflows galore. See this answer on how to avoid that.
Employed Russian
  • 199,314
  • 34
  • 295
  • 362