如何确定SegFault代码中的问题在哪里?
下面的程序是SIC宏处理器,无需担心程序的逻辑,您可以识别引起SegFault的任何常见错误吗?
Input.txt(唯一的输入文件,其余文件由程序创建)
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 -
如果我在代码块中运行它,则只是创建文件inter.txt,但此后什么也没有做。我尝试在第一次打开后立即在inter.txt中添加一行,但这也没有发生(仅创建空文件)
#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;
}
答案 0 :(得分:0)
如何确定SegFault代码中的问题在哪里?
您在调试器下运行它。在Linux上,GDB是最常用的一个。 LLDB也可以使用。
如果您使用受支持的平台,则还可以使用Address Sanitizer(-fsanitize=address
)来构建程序,这很可能会直接指出您的错误。
将FILE指针发送到其他函数是否是错误的做法?
一点也不。不过,传递FILE **
是很不寻常的。
追加模式会导致任何问题吗?
可能不是。您的程序需要一堆输入文件,而您没有提供它们的内容,因此无法确定程序在哪里崩溃。
下面的程序是SIC宏处理器,无需担心程序的逻辑,您可以识别引起SegFault的任何常见错误吗?
我看到的常见错误:
fopen
的结果(这会使您的程序崩溃,我没有创建所有必需的文件)。fscanf
与非常小的输入缓冲区一起使用-如果您读取的字符串长于10个字符,则缓冲区溢出会变得异常丰富。有关如何避免这种情况的信息,请参见this answer。