我正在从教程中编写虚拟机,但我不断遇到分段错误。 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 ()
答案 0 :(得分:1)
解决问题注释中讨论的问题后
在编译时和进行链接时,请使用参数:-ggdb3
,它将:
导致更大的目标文件和更大的可执行文件。
将具有gdb
调试器的最大信息量。
除其他事项外,gdb
将显示行号。
然后在发生崩溃时使用bt
命令显示堆栈的追溯,因此您确切地知道代码是如何崩溃的。