【发布时间】:2018-01-26 07:16:14
【问题描述】:
所以我正在构建一个虚拟机,并试图使其尽可能跨平台,突然遇到一个奇怪的错误。我的机器有一条let 指令,它为机器内存中的一个变量分配内存,并为该变量分配一个值。简而言之,let 函数调用getAddress 来获取变量的地址。 getAddress 检查变量是否已经定义,并返回地址。如果变量未定义,getAddress 调用memallocate 为变量分配内存,并返回地址。这是函数的定义:
static uint16_t memallocate(Machine *m, char *symbol){
uint16_t allocationAddress = getFirstFree(*m);
SymbolTable *newSymbol = (SymbolTable *)malloc(sizeof(SymbolTable));
newSymbol->symbolName = strdup(symbol);
newSymbol->next = NULL;
newSymbol->mema = allocationAddress;
if(m->symbolTable==NULL){
m->symbolTable = newSymbol;
}
else{
SymbolTable *temp = m->symbolTable;
while(temp->next!=NULL)
temp = temp->next;
temp->next = newSymbol;
}
m->memory[allocationAddress].acquired = 1;
m->memory[allocationAddress].data.value = 0;
m->occupiedAddress++;
return allocationAddress;
}
uint16_t getAddress(Machine *m, char *symbol){
SymbolTable *table = m->symbolTable;
while(table!=NULL){
if(strcmp(symbol, table->symbolName)==0){
return table->mema;
}
table = table->next;
}
uint16_t address = memallocate(m, symbol); // Here is the segfault happening
return address;
}
这段代码在 Linux 上编译和运行得很好,但在 Windows 上,我在 memallocate 调用上遇到了段错误。由于memallocate 直接传递了getAddress 的参数,并且参数都是指针,所以它们不应该改变。但是在通过 CLion 进行调试时,我看到 memallocate 调用的参数乱七八糟,这表明某种堆栈违规(可能是)。同样,它只发生在 Windows 中。谁能告诉我我的代码出了什么问题?
该项目的完整代码可以在GitHub找到。
【问题讨论】:
-
16 位地址?
-
是的。该机器还模拟了一种类似 RAM 的存储形式。这是机器 RAM 的地址。
-
调用执行时你检查栈上的内容了吗?
-
你说的是gdb中的
bt吗?那么是的@odin -
嗯,我的意思更像是检查堆栈指针周围的区域,看看是否可以在堆栈的任何位置找到正确的参数。这样您就可以确定问题是否在于堆栈指针位于错误的位置。这是在 Windows 上编译为 64 位、32 位还是 16 位?
标签: c windows debugging segmentation-fault virtual-machine