This is a program I wrote for class, and its completely done and compiles with no errors, but I keep getting a segmentation fault and even after using GDB and putting print lines (with fflush attached) I cannot figure out what the problem is. I do however think I found the right line.
The program itself reads in a mock MAL (MIPS Assembly Language) file and prints out a the same thing to the outfile with added line numbers and a variable reference table.
This is my code, there are two c files, one header, and a makefile, ill post everything but the makefile here.
This is the p4b.c file which contains my main() function. The problem isn't here but I figured I'd post it anyway just in case.
/* Program 4b -- This program reads MAL instructions and prints a reference table for them */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Main */
int main(int argc, char *argv[])
{
/* prototypes */
void xref(FILE*, FILE*);
/* variable definitions */
FILE * inf, * outf;
/* check the number of command line arguments */
if(argc != 3)
{
fprintf(stderr, "Incorrect number of command line arguments.\n Proper Usage: p4b infile outfile\n");
exit(1);
}
/* open the infile for reading */
if((inf = fopen(argv[1], "r")) == NULL)
{
fprintf(stderr, "Could not open %s (infile) for reading\n", argv[1]);
exit(1);
}
/* open the outfile for writing */
if((outf = fopen(argv[2], "w")) == NULL)
{
fprintf(stderr, "could not open %s (outfile) for writing\n", argv[2]);
exit(1);
}
/* pass infile and outfile to be read/written in another function/file */
xref(inf, outf);
/* close the infile */
if(fclose(inf) == EOF)
{
fprintf(stderr, "Could not close %s (infile)\n", argv[1]);
exit(1);
}
/* close the outfile */
if(fclose(outf) == EOF)
{
fprintf(stderr, "Could not close %s (outfile)\n", argv[2]);
exit(1);
}
return 0;
}
This is the xref.c file which contains the xref() function, which is void, and takes two arguments, an in file and an out file.
/* Program 4b -- This program reads MAL instructions and prints a reference table for them */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "struct.h"
void xref(FILE * inf, FILE * outf)
{
printf("1\n");fflush(stdout);/* POINT 1 */
struct label malarray[100];
int linenum, arrpos, count;
char *str, *tmp;
char linein[81];
linenum = arrpos = 0;
while(fgets(linein, 80, inf) != NULL)
{
printf("2\n");fflush(stdout);/* POINT 2 */
linenum++;
sprintf(str, "%c", linein[0]);
if((strchr(str, '_') || isalpha(linein[0])) && (strchr(linein, ':') != NULL))
{
printf("3\n");fflush(stdout);/* POINT 3 */
/* get the label name out of the string */
str = strtok(linein, ":");
/* find the next empty array location */
while(malarray[arrpos].flag == 1)
{
printf("4\n");fflush(stdout);/* POINT 4 */
arrpos++;
}
/* put the label name and line number into the struct array */
malarray[arrpos].flag = 1;
strcpy(str, malarray[arrpos].labelname);
malarray[arrpos].defline = linenum;
}
str = strtok(NULL, " ");
str = strtok(NULL, " ");
if(isalpha(str[0]) || (strstr(str, ",") != NULL))
{
printf("5\n");fflush(stdout);/* POINT 5 */
while(isalpha(str[0]) || str[0] == '$')
{
printf("6\n");fflush(stdout);/* POINT 6 */
str = strtok(NULL, " ,");
arrpos = 0;
while(malarray[arrpos].flag == 1)
{
printf("7\n");fflush(stdout);/* POINT 7 */
if(strcmp(malarray[arrpos].labelname, str) == 0)
{
printf("8\n");fflush(stdout);/* POINT 8 */
/* store the useline and incriment the watermark */
malarray[arrpos].useline[malarray[arrpos].uses] = linenum;
malarray[arrpos].uses++;
}
arrpos++;
}
}
}
}
rewind(inf);
linenum = 1;
while(fgets(linein, 81, inf) != NULL)
{
printf("9\n");fflush(stdout);/* POINT 9 */
sprintf(str, "%d", linenum);
strcat(str, linein);
fputs(str, outf);
}
fputs("\n", outf);
fputs("Cross Reference Table\n", outf);
fputs("\n", outf);
fputs("\tIdentifier\tDefinition\tUse\n", outf);
arrpos = 0;
while(malarray[arrpos].flag == 1)
{
printf("10\n");fflush(stdout);/* POINT 10 */
strcpy(str, " ");
/* put all the uselines into a string to print them to the outfile */
while(count < malarray[arrpos].uses)
{
printf("11\n");fflush(stdout);/* POINT 11 */
sprintf(tmp, "%d", malarray[arrpos].useline[count]);
strcat(str, tmp);
count++;
}
count = 0;
fprintf(outf, "\t %s \t %d \t %s \n", malarray[arrpos].labelname, malarray[arrpos].defline, str);
}
}
Lastly, though I don't think this has anything to do with the problem either, here is the struct.h header file that just contains a struct that I used to store information about each MAL variable in.
struct label
{
int defline;
int uses;
int useline[100];
char labelname[10];
int flag;
};
When I run the file in my prompt this is what is printed to me:
$ ./p4b in.mal out.lst
1
2
Segmentation fault
The '1' and '2' that are printed are from the printf statements I put in to help myself trace the fault, which as far as I can tell point to it being in the if() statement on line 22 of xref.c.
The GDB output is as follows:
dyn-169-226-78-157:p4 adamrosscohen$ gdb --args ./p4b in.mal out.lst
GNU gdb 6.3.50-20050815 (Apple version gdb-1346) (Fri Sep 18 20:40:51 UTC 2009)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin"...Reading symbols for shared libraries .. done
(gdb) run
Starting program: /Users/adamrosscohen/Desktop/p4/p4b in.mal out.lst
Reading symbols for shared libraries +. done
1
2
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: 13 at address: 0x0000000000000000
0x00007fffffe007d9 in __memcpy ()
(gdb) backtrace
#0 0x00007fffffe007d9 in __memcpy ()
#1 0x00007fff8862ac05 in __sfvwrite ()
#2 0x00007fff8862a6dc in __vfprintf ()
#3 0x00007fff886de328 in vsprintf ()
#4 0x00007fff8865a447 in __sprintf_chk ()
#5 0x00000001000014be in xref (inf=0x7fff7107ee80, outf=0x7fff7107ef18) at xref.c:23
#6 0x000000010000139c in main (argc=3, argv=0x7fff5fbff9e0) at p4b.c:39
I still cannot figure out what is wrong with the program, but I now know it has something to do with memcpy(), which I'm not actually even calling.... anywhere in my program.
Anyone who could tell me why this is happening and/or how to fix it I would greatly appreciate it.
Thank you in advance,
A. Ross Cohen