我的代码在一个月前完全适用于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;
}
答案 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
此外,我没有查看整个代码,因此可能会有更多。