在C中查找段故障

时间:2014-01-02 22:39:06

标签: c segmentation-fault

我的代码在一个月前完全适用于clang编译器,现在它将故障分段。使用gdb,我得到

#0  0x00007ffff7a85bf9 in __GI__IO_vfscanf () from /lib64/libc.so.6
#1  0x00007ffff7a96b8b in __isoc99_fscanf () from /lib64/libc.so.6
#2  0x0000000000401470 in main ()

当我尝试选择特定的框架时,它不会透露任何其他内容。

下面我发布了整个代码。 clang已更新? fscanf已被更改?我不确定是什么改变导致这个错误。 任何帮助揭示故障的位置都将非常感激!

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


//a stack for if else endif
#define MAXSTACK 20
#define EMPTYSTACK -1
int top = EMPTYSTACK;
int items[MAXSTACK];
int counter = 0;
int ifcounter = 0;
int temp = 0;

void cpush(int c) {
   items[++top] = c;
}
int cpop() {
   return items[top--];
}
int cfull()  {
   return top+1 == MAXSTACK;
}
int cempty()  {
   return top == EMPTYSTACK;
}

int push(int n, FILE *write){
  if ((n <= 255 && n >= -255))
    fprintf (write, "\tCONST R3, #%d\n", n);
  if (n > 255 || n < -255) {
    int d = n & 0xFF;
    fprintf (write, "\tCONST R3, #%d\n", d);
    //unsigned short int d = ((unsigned short int) n);
    //d &= 0xFF00;
    n = n >> 8;
    fprintf (write, "\tHICONST R3, #%u\n", n);
  }
  fprintf (write, "\tSTR R3, R6, #-1\n");
  fprintf (write, "\tADD R6, R6, #-1\n");
  return 1;
}

int pop(int n, FILE *write){
  fprintf (write, "\t;; pop %d      \n", n);
  fprintf (write, "\tADD R6, R6, #%d    \n", n);
  return 0;
}

int compare(char *s, FILE *write, char* filename){
    counter++;
    fprintf (write, "\t;; %s\n", s);
    fprintf (write, "\tLDR R0, R6, #0 \n");
    fprintf (write, "\tLDR R1, R6, #1 \n");
    pop(2, write);
    //fprintf (write, "\tSUB R0, R0, R1 \n");
    fprintf (write, "\tCMP R0, R1   \n");
    if (strcmp(s , "lt") == 0)
    fprintf (write, "\tBRn TRUE%d_%s    \n", counter, filename);
    else if (strcmp(s , "le") == 0)
    fprintf (write, "\tBRnz TRUE%d_%s   \n", counter, filename);
    else if (strcmp(s , "eq") == 0)
    fprintf (write, "\tBRz TRUE%d_%s    \n", counter, filename);
    else if (strcmp(s , "ge") == 0)
    fprintf (write, "\tBRzp TRUE%d_%s   \n", counter, filename);
    else fprintf (write,"\tBRp TRUE%d_%s    \n", counter, filename); //gt
    push(0, write);
    fprintf (write, "\tBRnzp FALSE%d_%s \n", counter, filename);
    fprintf (write, "TRUE%d_%s      \n", counter, filename);
    push(1, write);
    fprintf (write, "FALSE%d_%s     \n", counter, filename);
    return 1;
}

int printdefun (char *s, FILE *write){
    fprintf (write, ";;;;;;;;;;;;;;;;;;;;;;;;;;;;%s;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n", s);
  fprintf (write, "\t.CODE\n");
  fprintf (write, "\t.FALIGN\n");
  fprintf (write, "%s\n", s);
  fprintf (write, "\t;; prologue\n");
  fprintf (write, "\tSTR R7, R6, #-2  ;; save return address\n");
  fprintf (write, "\tSTR R5, R6, #-3  ;; save base pointer\n");
  fprintf (write, "\tADD R6, R6, #-3\n");
  fprintf (write, "\tADD R5, R6, #0\n");
  fprintf (write, "\t;; function body\n");
  return 1;
}

int printreturn (FILE *write){
  fprintf (write, "\t;; epilogue\n");
  fprintf (write, "\tLDR R7, R6, #0 ;; \n");
  fprintf (write, "\tADD R6, R6, #1 ;; \n");
  fprintf (write, "\tSTR R7, R5, #2 ;; \n");
  fprintf (write, "\tADD R6, R5, #0 ;; \n");
  fprintf (write, "\tLDR R5, R6, #0 ;; \n");
  fprintf (write, "\tLDR R7, R6, #1 ;; \n");
  fprintf (write, "\tADD R6, R6, #2 ;; \n");
  fprintf (write, "\tJMPR R7\n");
  return 1;
}

int arith(FILE *write, char *s){
  fprintf (write, "\t;; %s      \n", s);
  fprintf (write, "\tLDR R0, R6, #0 \n");
  fprintf (write, "\tLDR R1, R6, #1 \n");
  pop(2, write);
  fprintf (write, "\t%s R0, R0, R1  \n", s);
  fprintf (write, "\tSTR R0, R6, #-1  \n");
  fprintf (write, "\tADD R6, R6, #-1  \n");
  return 1;
}

int not(FILE *write){
  fprintf (write, "\t;; NOT     \n");
  fprintf (write, "\tLDR R0, R6, #0 \n");
  pop(1, write);
  fprintf (write, "\tNOT R0, R0   \n");
  fprintf (write, "\tSTR R0, R6, #-1  \n");
  fprintf (write, "\tADD R6, R6, #-1  \n");
  return 1;
}


/*Makes a new file without comments or anything following
 * also turns lone + into p and lone - into m
 */
int removeComments(char* readname){
  FILE *read;
  read = fopen(readname,"r");
  FILE *write;
  write = fopen("file.j", "wb");
  int c;
  int read_semicolon = 0;

    while ((c = fgetc(read)) != EOF)
    {
        if (c == '\n')
        {
            fprintf(write, "%c", c);
            read_semicolon = 0;
        }
        else if (c == ';')
            read_semicolon = 1;
        else if (!read_semicolon) {
          if(c == '+'){
            int t = fgetc(read);
            if (t == ' ' || t ==';' || t == '\t')
              c = 'p';
            ungetc(t, read);
          }
          else if(c == '-'){
            int t = fgetc(read);
            if (t == ' ' || t ==';' || t == '\t'){
              c = 'm';
              ungetc(t, read);
            }
            else if (t == '0'){
              int t = fgetc(read);
              if (t == 'x'){
                fprintf(write, "OX ");
                c = '-';
              } else ungetc(t, read);
            }
            else ungetc(t, read);
          }
          else if(c == '0'){
            int t = fgetc(read);
            if (t == 'x'){
            fprintf(write, "OX");
            c = ' ';
            }else ungetc(t, read);
          }
            fprintf(write, "%c", c);
        }
        /* else suppressed because read_semicolon is true */
    }
    fclose(read);
    fclose(write);
    return 0;
}

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

  removeComments(argv[1]);
  FILE *read;               //file to read in
  read = fopen("file.j","r");

  char *filename = strtok(argv[1], ".");  //gets rid of the . and beyond
  strcat (filename,".asm");         //makes the name .asm via concatenation
  FILE *write;  
  write = fopen(filename, "wb");

  char *s;
  int c;
  int d;
  int n = 0;
  unsigned int u;
    char *asmname = strtok(argv[1], ".");
  while(feof(read) == 0){
    if (fscanf(read, "0x%s", s) == 1){
      char* hexstring = s;
      long int y = strtol(hexstring, (char**)0, 0);
      //int y = strtod(s, &endp);
      push(y, write);
    }
      if(fscanf(read,"%d", &d)) {
        /* this makes sure that ints preceding "pick" etc are not
         * counted as ints that are pushed onto the stack. Further this makes sure
         * the testing for this does not "eat" and of the words in the file
         */ 
        /*const long pos = ftell(read); // stores current position
        //checks if the next thing 
        if (fscanf(read,"%s", s)){
        if ((strcmp(s , "pick") == 0 || (strcmp(s , "eq") == 0))){
          //fprintf (write, "%d %s called\n", d, s);
        }
        else {
          push(d, write);
          //undo the word we "ate" 
          fseek(read, pos, SEEK_SET);
        }
      } else */ push(d, write);
      } 
      else if (fscanf(read,"%s", s)){ 
        if (strcmp(s , "defun") == 0) {
          fscanf(read,"%s", s);
          printdefun (s, write);
        }
        else if (strcmp(s , "return") == 0) {
          printreturn (write);
        }
        else if (strcmp(s , "p") == 0) {
          arith(write, "ADD");
        }
        else if (strcmp(s , "m") == 0) {
          arith(write, "SUB");
        }
        else if (strcmp(s , "*") == 0) {
          arith(write, "MUL");
        }
        else if (strcmp(s , "/") == 0) {
          arith(write, "DIV");
        }
        else if (strcmp(s , "%") == 0) {
          arith(write, "MOD");
        }
        else if (strcmp(s , "and") == 0) {
          arith(write, "AND");
        }
        else if (strcmp(s , "or") == 0) {
          arith(write, "OR");
        }
        else if (strcmp(s , "not") == 0) {
          not(write);
        }
        else if (strcmp(s , "drop") == 0) {
          fprintf (write, "\t;; drop\n");
          pop(1, write);
        }
        else if (strcmp(s , "dup") == 0) {
          fprintf (write, "\t;; dup\n");
          fprintf (write, "\tLDR R0, R6, #0 \n");
          fprintf (write, "\tSTR R0, R6, #-1  \n");
          fprintf (write, "\tADD R6, R6, #-1  \n");
        }
        else if (strcmp(s , "swap") == 0) {
          fprintf (write, "\t;; swap\n");
          fprintf (write, "\tLDR R0, R6, #0 \n");
          fprintf (write, "\tLDR R1, R6, #1 \n");
          fprintf (write, "\tSTR R0, R6, #1 \n");
          fprintf (write, "\tSTR R1, R6, #0 \n");
        }
        else if (strcmp(s , "rot") == 0) {
          fprintf (write, "\t;; rot\n");
          fprintf (write, "\tLDR R0, R6, #0 \n");
          fprintf (write, "\tLDR R1, R6, #1 \n");
          fprintf (write, "\tLDR R2, R6, #2 \n");
          fprintf (write, "\tSTR R2, R6, #0 \n");
          fprintf (write, "\tSTR R1, R6, #2 \n");
          fprintf (write, "\tSTR R0, R6, #1 \n");
        }
        else if (strcmp(s , "pick") == 0){
          fprintf (write, "\t;; pick\n");
          fprintf (write, "\tLDR R0, R6, #0 \n");
          fprintf (write, "\tADD R1, R6, R0 \n");
          fprintf (write, "\tADD R1, R1, #1 \n");
          pop(1, write);
          fprintf (write, "\tLDR R2, R1, #0 \n");
          fprintf (write, "\tSTR R2, R6, #-1  \n");
          fprintf (write, "\tADD R6, R6, #-1  \n");
        }
        else if (strcmp(s , "lt") == 0 || strcmp(s , "le") == 0 
          || strcmp(s , "eq") == 0 || strcmp(s , "ge") == 0 
          || strcmp(s , "gt") == 0){
          compare(s, write, asmname);
        }
        else if (strcmp(s , "if") == 0) {
          ifcounter+=2;
          cpush(ifcounter);
          fprintf (write, "\tLDR R0, R6, #0 \n");
          pop(1, write);
          fprintf (write, "\tCMPI R0, #0    \n");
          fprintf (write, "\tBRz ELSE%d_%s  \n", ifcounter, asmname);
        }
        else if (strcmp(s , "else") == 0) {
          ifcounter = cpop();
          fprintf (write, "\tBRnzp ELSE%d_%s  \n", (ifcounter + 1), asmname);
          fprintf (write, "ELSE%d_%s    \n", ifcounter, asmname);
          cpush(++ifcounter);
        }
        else if (strcmp(s , "endif") == 0) {
          ifcounter = cpop();
          if (temp < ifcounter)
            temp = ifcounter;
          fprintf (write, "ELSE%d_%s    \n", ifcounter, asmname);
          ifcounter = temp;
        }
        else if (strcmp(s , "OX") == 0) {
          fscanf(read,"%s", s);
          //int aInt = 368;
          //char str[16];
          //sprintf(str, "%d", d);
          //char *num = d;
          long int li = strtol (s,NULL,16);
          d = (int) li;
          push(d, write);
        }
        else {
          fprintf (write, "\tJSR %s\n", s);
        }
      }
      //else if(fscanf(read,"%x", &u)) {}
  } //while(c != EOF);  
  fclose(read);
  fclose(write);
  return 0;
}

2 个答案:

答案 0 :(得分:4)

问题在于: if (fscanf(read, "0x%s", s) == 1){

s变量简单地定义为char *s;,这意味着没有为它应该指向的字符串分配任何内存,因此它包含任意值。不知道为什么这个和clang一起工作就像你说的那样;它应该早些时候进行细分。

答案 1 :(得分:0)

老实说,你应该使用gdb来设置断点,并且至少要经过更少的代码,但看起来像main()中的char *在fscanf()中使用而没有任何内存分配给它(通常是什么分段错误)。如果要将其用作字符串,请使用

 x = amount of characters
 char s[x] //this will make an array(pointer) of chars

 char *s = (char *) malloc(x * sizeof(char)); //allocates memory to the pointer

此外,我没有查看整个代码,因此可能会有更多。