我遇到了细分错误,我不知道为什么

时间:2020-11-12 21:19:46

标签: c virtual-machine

我正在从教程中编写虚拟机,但我不断遇到分段错误。 gdb并没有给我任何信息,因为它位于int main()中,但是我没有发现任何错误,当然,我对错误的地方视若无睹,因此,如果你们中的一个聪明人可以帮助我,那将是很好的< / p>

vm.c(我已修复缩进)

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
typedef struct OBJECT_t {
  uint8_t type;
  union {
    uint8_t  u8;
    int8_t   i8;
    uint32_t u32;
    int32_t  i32;
    void *ptr;
  };
} OBJECT;

typedef struct STACK_t {
  int top;
  int size;
  OBJECT *stack;
} STACK;
typedef uint8_t* (*instruction)(uint8_t *, STACK *);
STACK stack_new(int size) {
  STACK s;
  s.top = 0;
  s.size = size;
  s.stack = (OBJECT *)malloc(sizeof(OBJECT) * size);
  return s;
}
int stack_push(STACK *s, OBJECT o){
  s->stack[s->top++] = o;
  return s->top;
}
OBJECT stack_pop(STACK *s){
        return s->stack[--(s->top)];
}
OBJECT stack_peek(STACK *s) {
  return s->stack[s->top - 1];
}
void usage(){
  printf("usage: vm <file>\n");
  exit(1);
}
uint8_t *load_file(char *filename) {
  FILE *f;
  int size;
  uint8_t *code = NULL;
  struct stat st;
  if((f = fopen(filename, "r"))) {
    fstat(fileno(f), &st);
    code = (uint8_t *)malloc(st.st_size);
    fread((void *)code, 1, st.st_size, f);
  }else {
    printf("ERROR: cannot open file %s\n", filename);
    usage();
  }
  return code;
}
uint8_t *op_nop(uint8_t *ip, STACK *s){
  return ip + 1;
}
uint8_t *op_push_char(uint8_t *ip, STACK *s){
  OBJECT o;
  o.type = 'c';
  o.u8   = *(ip + 1);
  stack_push(s, o);
  return ip + 2;
}
uint8_t *op_emit(uint8_t *ip, STACK *s){
  OBJECT o = stack_pop(s);
  putchar(o.u8);
  return ip + 1;
}
int main(int argc, char **argv){
  uint8_t *code;
  uint8_t *ip;
  STACK data;
  instruction ops[256];
  if(argc != 2){
    usage();
  }
  for(int i=0;i<256;i++){
    ops[i] = op_nop;
  }
  ops['c'] = op_push_char;
  code = load_file(argv[1]);
  data = stack_new(1024);
  ip   = code;
  while(*ip != 'h'){
    ip = ops[*ip](ip, &data);
  }
  return 0;
}

我的程序 hello.sp

c
c!cdclcrcocwc coclclcecHeeeeeeeeeeeeeh

这是我的gdb输出

Program received signal SIGSEGV, Segmentation fault.
0x00000000004014a6 in main ()

1 个答案:

答案 0 :(得分:1)

解决问题注释中讨论的问题后

在编译时和进行链接时,请使用参数:-ggdb3,它将:

  1. 导致更大的目标文件和更大的可执行文件。

  2. 将具有gdb调试器的最大信息量。

除其他事项外,gdb将显示行号。

然后在发生崩溃时使用bt命令显示堆栈的追溯,因此您确切地知道代码是如何崩溃的。