2011-12-16 6 views
0

는 편집 : 그래서 내 코드에서 나는 세그멘트 폴트가 /* Cache Structure */는 segfault는

EDIT2라는 주석 섹션에서 보면, 무슨 일이 일어나고 생각 어디 사람이 쉽게 찾을 수 : GDB에 큰 실수를했다 이 GDB에서 세그먼테이션 폴트 (segfault) 올바른 출력은 다음과 같습니다

(gdb) run 
Starting program: /.autofs/ilab/ilab_users/petejodo/Assignment4/a.out 
1 
/.autofs/ilab/ilab_users/petejodo/Assignment4/a.out 

Program received signal SIGSEGV, Segmentation fault. 
0x00449453 in strlen() from /lib/libc.so.6 
(gdb) 

EDIT3 : 라인을 인쇄처럼 n00b 전술에 의지 후, 나는 그것이 인쇄 발견했습니다 전에 :

file = fopen(purefile, "r"); 
    if (file == 0){ 
     printf ("Could not find file!\n"); 
     return 0; 
    } 

하지만 인쇄 "테스트"나 밑에있다.

ORIGINAL

그래서는 segfault의 모든 스레드를 확인하고 내 프로그램이이 줄에서 segfaulting 왜 내가 알아낼 수 없습니다 GDB 사용 후. 캐시 시뮬레이터를 작성 중이며 (현재 코드에 write-through 만 있음) 괜찮 았기 때문에 메소드를 포함하지 않았습니다.이 메소드는 기본 메소드에 있습니다.

**INCORRECT** 

(gdb) run 
Starting program: /.autofs/ilab/ilab_users/petejodo/Assignment4/a.out 

Program received signal SIGSEGV, Segmentation fault. 
0x080489b6 in main (argc=1, argv=0xbfffe954) at sim.c:128 
128    if (strcmp(argv[1], "-h")==0) 
(gdb) bt 

#0 0x080489b6 in main (argc=1, argv=0xbfffe954) at sim.c:128 

나는 종류의 손실, 어떤 도움이 좋을 것 해요 :

int main(int argc, char **argv) { 
    FILE* file; 

    /* Counter variables */ 
    int i; 
    int j; 

    /* Helper Variables */ 
    int setAdd; 
    int totalSet; 
    int trash; 
    int size; 
    int extra; 
    char rw; 

    /* Necessary Character Arrays */ 
    char hex[100]; 
    char bin[100]; 
    char origTag[100]; 
    char bbits[100]; 
    char sbits[100]; 
    char tbits[100]; 

    /* Cache Info Variables */ 
    int setNumber = 4096; /* cacheSize/blockSize : (16,384/4) */ 
    int setBits = 12; /* log(setNumber)/log(2) : (log(4096)/log(2)) */ 
    int tagSize = 18; /* 32-(blockBits + setBits) **blockBits = log(blockSize)/log(2)** : (32 - (2 + 12) */ 

    /* Results */ 
    int cacheHit = 0; 
    int cacheMiss = 0; 
    int write = 0; 
    int read = 0; 

    /* Cache Structure */ 
    tempLine cache[4096]; 

    char* style; 
    char* purefile; 
    if (strcmp(argv[1], "-h")==0) 
    { 
     puts("Usage: sim <write policy> <trace file>"); 
     return 0; 
    } 
    style = argv[1]; 
    purefile = argv[2]; 
    file = fopen(purefile, "r");/* HYPOTHESIZED SEGFAULT HERE */ 
    if (file == 0){ 
     printf ("Could not find file!\n"); 
     return 0; 
    } 
    printf("test1"); 
    /* Setting Structure Default Values */ 
    for(i = 0; i < setNumber; i++) 
    { 
     cache[i].tag = (char *)malloc(sizeof(char)*(tagSize + 1)); 
     for(j = 0; j < tagSize; j++) 
     { 
      cache[i].tag[j] = '0'; 
     } 
     cache[i].valid = 0; 
    } 

    /* Main Loop */ 
    while(fgetc(file) != '#') 
    { 
     setAdd = 0; 
     totalSet = 0; 

     fseek(file, -1, SEEK_CUR); 
     fscanf(file, "%d: %c %s\n", &trash, &rw, origTag); 

     /* Cutting off '0x' off from address '0x00000000' and adding 0's if necessary */ 
     size = strlen(origTag); 
     extra = (10 - size); 
     for(i = 0; i < extra; i++) 
      hex[i] = '0'; 
     for(i = extra, j = 0; i < (size-(2-extra)); i++, j++) 
      hex[i] = origTag[j + 2]; 

     hex[8] = '\0'; 

     hex2bin(hex, bin); 

     split(bin, bbits, sbits, tbits); 

     /* Changing cArray into int */ 
     for(i = 0, j = (setBits - 1); i < setBits; i++, j--) 
     { 
      if (sbits[i] == '1') 
       setAdd = 1; 
      if (sbits[i] == '0') 
       setAdd = 0; 
      setAdd = setAdd * pow(2, j); 
      totalSet += setAdd; 
     } 

     /* Calculating Hits and Misses */ 
     if (cache[totalSet].valid == 0) 
     { 
      cache[totalSet].valid = 1; 
      strcpy(cache[totalSet].tag, tbits); 
     } 

     if ((cache[totalSet].valid == 1) && (strcmp(cache[totalSet].tag, tbits) == 0)) 
     { 
      /* HIT */ 
      if (rw == 'W') 
      { 
       cacheHit++;   
       write++; 
      } 
      if (rw == 'R') 
       cacheHit++;  
     } 
     else 
     { 
      /* MISS */ 
      if (rw == 'R') 
      { 
       cacheMiss++; 
       read++; 
      } 
      if (rw == 'W') 
      { 
       cacheMiss++; 
       read++; 
       write++; 
      } 
      cache[totalSet].valid = 1; 
      strcpy(cache[totalSet].tag, tbits); 
     } 
     /* End Calculations */ 
    } 
    printResult(cacheHit, cacheMiss, read, write); 

    return 0; 
} 

그리고 내가 gdb가 나왔을이이었다. 감사!

아, 또한 argv[1]의 값을 확인하는 것은 NULL 또는 0x0이므로 그 때문이라고 생각합니다. argv[1]에는 도움말 플래그가 있거나 쓰기 쓰 기 또는 다시 쓰기가 포함되어 있다고 가정합니다. 필기 확인 또는 다시 쓰기 여부를 코딩하지 않았습니다.

답변

1

argv[1]에 액세스하려면 argc > 1을 테스트해야합니다. 프로그램에서 항상 호출 한 이름 (예 : ./a.out)은 argv[0]이므로 argc >= 1은 항상 true입니다. 첫 번째 실제 인수, 즉 argv의 두 번째 요소에 액세스하려면 두 개의 인수가 있는지 테스트해야합니다. 그러나 argv[n]에 액세스 할 때 > n 요소가 있는지 테스트하는 경우 두 숫자가 동일하기 때문에 더 읽기 쉬운 IMO입니다. 첫 번째 인수가 -h 경우 유효 argv[1]argv[2] 요소가 있거나 제공 충분한 인수가없는 경우 오류가 표시됩니다이 경우

if (argc < 3 || (argv > 1 && strcmp(argv[1], "-h")==0)) 
{ 
    puts("Usage: sim <write policy> <trace file>"); 
    return 0; 
} 

: 여기

은 코드를 변경하는 방법에 대한 예제 (누군가가 -h 이후에 물건을 넣을 경우를 대비해 - 그렇지 않으면 너무 적은 수의 인자에 의해 처리 될 것입니다).

그런데 getopt()을 살펴 봐야합니다. 그러면 인수/스위치 구문 분석이 훨씬 쉽고 빠릅니다.

+0

segfaults 때 다른 플래그를 사용할 때만 -h 플래그를 사용할 때 segfault가 아니라고 추가해야합니다. 나는 여전히 당신의 코드를 사용하여 세그 폴트를 얻는다. –

+0

'-h'를 사용하면'argv [1]'에 접근하기 전에 종료합니다; 다른 플래그를 사용할 때 유효하지 않은 배열 요소에 액세스하므로 붐 (BOOM)이 발생합니다. 프로그램이 여전히 내 코드로 깨지면, 뭔가 잘못 될 수 있습니다. GDB에서 메시지/라인을 보지 않고는 말할 수 없습니다. – ThiefMaster

+0

그러면 다음 행동은 어떻게 될까요?편집 : btw 나는 모든 인수를 인쇄하려고했는데 잘 작동합니다. –