分段错误:缓存实验室

时间:2016-11-13 04:25:07

标签: c caching segmentation-fault

当我在命令行中使用此命令运行它时,我的缓存模拟器文件会生成分段错误错误:

./csim.c -s 1 -E 1 -b 1 -t traces/yi2.trace. 

我不熟悉分段错误错误。

任何帮助将不胜感激。

编辑:使用gdb找到这个

Program received signal SIGSEGV, Segmentation fault.
strcmp () at ../sysdeps/x86_64/multiarch/../strcmp.S:132
132 ../sysdeps/x86_64/multiarch/../strcmp.S: No such file or directory.
(gdb) bt
#0  strcmp () at ../sysdeps/x86_64/multiarch/../strcmp.S:132
#1  0x00007ffff7deb1a5 in _dl_name_match_p (name=0x400459 "libm.so.6", 
    map=0x7ffff7ffe1c8) at dl-misc.c:289
#2  0x00007ffff7de402f in do_lookup_x (new_hash=new_hash@entry=193502747, 
    old_hash=old_hash@entry=0x7fffffffe200, 
    result=result@entry=0x7fffffffe210, scope=<optimized out>, 
    i=<optimized out>, i@entry=0, flags=flags@entry=1,                skip=skip@entry=0x0, 
    undef_map=undef_map@entry=0x7ffff7ffe1c8) at dl-lookup.c:462
#3  0x00007ffff7de4961 in _dl_lookup_symbol_x (undef_name=0x4004bc "pow", 
    undef_map=0x7ffff7ffe1c8, ref=ref@entry=0x7fffffffe2c8, 
    symbol_scope=0x7ffff7ffe520, version=0x7ffff7ff7f58, 
    type_class=type_class@entry=1, flags=1, skip_map=skip_map@entry=0x0)
    at dl-lookup.c:737
#4  0x00007ffff7de9527 in _dl_fixup (l=<optimized out>, 
    reloc_arg=<optimized out>) at ../elf/dl-runtime.c:111
#5  0x00007ffff7df04d5 in _dl_runtime_resolve ()
    at ../sysdeps/x86_64/dl-trampoline.S:45
#6  0x000000000040109d in main (argc=9, argv=0x7fffffffe4c8) at csim.c:497

代码:

#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>
#include <strings.h>
#include <unistd.h>
#include <math.h>
#include "cachelab.h"

typedef struct lines{

    short int valid;
    long long int tag;
    char block;
    int last, n_accesses;
} line;

typedef struct sets{

    line *set_line;
} set;

typedef struct caches{

    set *cache_set;
} cache;

typedef struct cache_evaluations{

    int hits, misses, evictions;
} evaluation;

typedef struct HME{

  evaluation *eval;
} hme;

typedef struct data_reads{

    int s, E, b, n_sets, n_lines;
} data;

int verbosity;

void help(){

    printf("Usage: [-hv] -s <num> -E <num> -b <num> -t <file>\n\n");
    printf("  -h         Help message.\n");
    printf("  -v         Verbose flag (optional).\n");
    printf("  -s <num>   Number of set index bits.\n");
    printf("  -E <num>   Number of lines per set.\n");
    printf("  -b <num>   Number of block offset bits.\n");
    printf("  -t <file>  Trace file.\n");

    exit(0);
}

void create_cache(cache c_cache, data r_data){

    set c_set;
    line c_line;
    int n_sets = r_data.n_sets;
    int n_lines = r_data.n_lines;
    int set_i, line_j;
    c_cache.cache_set = (set *) (malloc(sizeof(set) * n_sets));

    for(set_i = 0; set_i < n_sets; set_i += 1){

        c_set.set_line = (line *) (malloc(sizeof(line) * n_lines));
        c_cache.cache_set[set_i] = c_set;

        for(line_j = 0; line_j < n_lines; line_j += 1){

            c_line.valid = 0;
            c_line.tag = 0;
            c_line.n_accesses = 0;
            c_line.last = 0;
            c_set.set_line[line_j] = c_line;
        }
    }
}

void empty_cache(cache c_cache, data r_data){

    set set_ptr;
    int n_sets = r_data.n_sets;
    int set_i;
    for(set_i = 0; set_i < n_sets; set_i += 1){
        set_ptr = c_cache.cache_set[set_i];
        if(set_ptr.set_line != NULL)
          free(set_ptr.set_line);
    }
}

int find_lru(set tmp_set, data r_data){

    int min_count = tmp_set.set_line[0].n_accesses;
    int n_lines = r_data.n_lines;
    int line_j;

    for(line_j = 0; line_j < n_lines; line_j += 1){

        if(tmp_set.set_line[line_j].n_accesses < min_count){
           min_count = tmp_set.set_line[line_j].n_accesses;
        }
    }

    for(line_j = 0; line_j < n_lines; line_j += 1){

        if(tmp_set.set_line[line_j].n_accesses != min_count){
           tmp_set.set_line[line_j].n_accesses += 1;
        }
    }
    return min_count;
}

int eviction(set tmp_set, data r_data){

    int lru = find_lru(tmp_set, r_data);
    int n_lines = r_data.n_lines;
    int evict_idx;
    int line_n;

    for(line_n = 0; line_n < n_lines; line_n += 1){

        if((tmp_set.set_line[line_n].last == 0) && tmp_set.set_line[line_n].n_accesses == lru){

            tmp_set.set_line[line_n].valid = 0;
            tmp_set.set_line[line_n].tag = 0;
            tmp_set.set_line[line_n].n_accesses = 0;
            tmp_set.set_line[line_n].last = 0;
            evict_idx = line_n;
            break;
        }
        tmp_set.set_line[line_n].n_accesses += 1;
    }
    return evict_idx;
}

int find_line(set tmp_set, data r_data, hme c_hme){

    short int cont = 1;
    int n_lines = r_data.n_lines;
    int line_idx;
    int line_n;

    for(line_n = 0; line_n < n_lines; line_n += 1){

        tmp_set.set_line[line_n].n_accesses += 1;

        if(!(tmp_set.set_line[line_n].valid)){

            cont = 0;
            line_idx = line_n;
            break;
        }
    }

    if(cont){

      c_hme.eval[0].evictions += 1;
      line_idx = eviction(tmp_set, r_data);
    }
    return line_idx;
}

int mask(int b){

    int masked_b = pow(2.0,b) - 1;
  return masked_b;
}

void cache_sim(cache c_cache, hme c_hme, data r_data, unsigned long long int address){

    int n_lines = r_data.n_lines;
    unsigned long long int n_tag = address >> (r_data.s + r_data.b);
    int set_index = (address >> r_data.b) & mask(r_data.s);
    set tmp_set = c_cache.cache_set[set_index];
    int block_offset = address & mask(r_data.b);
    char n_block = (char) block_offset;
    int hit = 0;
    int line_j;

    for (line_j = 0; line_j < n_lines; line_j += 1){

        tmp_set.set_line[line_j].n_accesses += 1;
        tmp_set.set_line[line_j].last = 0;

        if(tmp_set.set_line[line_j].valid && tmp_set.set_line[line_j].tag == n_tag){

            tmp_set.set_line[line_j].last = 1;
            hit = 1;
            break;
        }
    }

    if(hit)
        c_hme.eval[0].hits += 1;

    else{

        c_hme.eval[0].misses += 1;
        int line_n = find_line(tmp_set, r_data, c_hme);
        tmp_set.set_line[line_n].valid = 1;
        tmp_set.set_line[line_n].tag = n_tag;
        tmp_set.set_line[line_n].block = n_block;
        tmp_set.set_line[line_n].last = 1;
        tmp_set.set_line[line_n].n_accesses += 1;
      }
}

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

    char cl_arg, *tracefile;
    data r_data = {0};

    while((cl_arg = getopt(argc,argv,"hv:s:E:b:t")) != -1){
        switch(cl_arg){

            case 'h':
                help();
            case 'v':
                verbosity = 1;
                break;
            case 's':
                r_data.s = atoi(optarg);
                break;
            case 'E':
                r_data.E = atoi(optarg);
                break;
            case 'b':
                r_data.b = atoi(optarg);
                break;
            case 't':
                tracefile = optarg;
                break;
            default:
                help();
                exit(1);
        }
    }

    cache c_cache;
    evaluation c_eval;
    c_eval.hits = 0;
    c_eval.misses = 0;
    c_eval.evictions = 0;
    hme c_hme;
    c_hme.eval[0] = c_eval;
    r_data.n_sets = pow(2, r_data.s);
    r_data.n_lines = r_data.E;
    create_cache(c_cache, r_data);
    unsigned long long int address;
    char instr;
    int size;

    FILE *file;
    file = fopen(tracefile,"r");

    if (file != NULL){
        while (fscanf(file, " %c %llx,%d", &instr, &address, &size) == 3){
            switch(instr){

                case 'L':
                    cache_sim(c_cache, c_hme, r_data, address);
                break;
                case 'S':
                    cache_sim(c_cache, c_hme, r_data, address);
                break;
                case 'M':
                    cache_sim(c_cache, c_hme, r_data, address);
                    cache_sim(c_cache, c_hme, r_data, address);
                break;
                default:
                break;
            }
        }
    }

    printSummary(c_hme.eval[0].hits, c_hme.eval[0].misses, c_hme.eval[0].evictions);
    empty_cache(c_cache, r_data);
    fclose(file);
    return 0;
}

2 个答案:

答案 0 :(得分:0)

您正在使用结构的调用( void ...)函数。 调用者(main())看到的结构不会改变;只有本地副本。示例(使用int结构成员而不是指针):

void (D1::*)()

结果:

void (D12::*)()

更新:与(最小化)原始程序相同:

#include <stdio.h>

typedef struct {
        int val;
        } omg;

void wtf(omg this);

/* function to change the value of this ??? */
void wtf(omg this)
{
this.val = 42;
}

/* let's call it ... */
int main(void) {

omg jesus = {0};

wtf( jesus);
printf("%d\n", jesus.val);

return 0;
}

结果:

plasser@pisbak:$ cc -Wall omg.c
plasser@pisbak:$ ./a.out
0
plasser@pisbak:$ 

答案 1 :(得分:-1)

我的逐出功能正在为一条线路中的一条线路返回一个无效索引(令人遗憾)。另外,我错误地访问了一些成员(使用 - &gt;而不是。)。