GCC "AddressSanitizer: heap-buffer-overflow" 初始化结构时
GCC "AddressSanitizer: heap-buffer-overflow" when initializing struct
我一直在写一个VM/Interpreter组合的东西,我不知道如何准确描述它。
一切都按预期运行,现在在我有数百行代码之前,我想进入 Garba Collection,因为有些指针不知何故以某种方式丢失了。并不是说我没有删除指针,而是我创建了指针,但是它们在 interpreting/running 代码的过程中以某种方式丢失了。
所以,我想追踪他们。我以某种方式编写了自己的“内存管理器”,它只是一个 std::vector
,我在其中收集所有指针。
为了跟踪和分配指针,我有以下代码:
struct MemBlock {
bool free;
void* ptr;
size_t size;
};
std::vector<MemBlock*> mem;
size_t max_size;
size_t mem_size;
int count = 0;
void mem_init(size_t maxSize) {
max_size = size/sizeof(MemBlock*);
}
void* mem_alloc(size_t size) {
for (int i = 0; i < count; i++) {
MemBlock* block = mem[i];
if (block->free) {
mem_size -= block->size;
mem_size += size;
block->free = false;
block->ptr = malloc(size);
block->size = size;
if (block->ptr == nullptr) {
throw std::exception();
}
return block->ptr;
}
}
void* ptr = malloc(sizeof(size));
if (ptr == nullptr) {
throw PointerNullException();
}
MemBlock* block = (MemBlock*) malloc(sizeof(MemBlock));
*block = (MemBlock) {
false,
ptr,
size
};
mem_size += size;
count++;
mem.push_back(block);
return block->ptr;
}
但是,当我使用 mem_alloc()
并初始化指针内部的对象时:
Int* i = (Int*) mem_alloc(sizeof(Int));
*i = (Int) {}; // -- Here
i->value = atoi(advance().c_str());
GCC AdressSanitizer 显示以下错误:
==5939==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000098 at pc 0x555963d82fc5 bp 0x7fff4ec39070 sp 0x7fff4ec39060
WRITE of size 4 at 0x602000000098 thread T0
如果我删除所述行,那么它只会出现在下一行。指针确实指向一个有效的内存位置,否则它应该抛出异常。
当然,我确定我错过了 something/did 一些错误。
但我不知道是什么。我是这样学的,或者至少我是这样理解的...
编辑:
这将是一个最小的可重现示例:
#include <iostream>
#include <stdlib.h>
#include <vector>
struct Object {
const char* type;
};
template <typename T>
struct Primitive : Object {
T value;
};
struct Int : Primitive<int> {
const char* type = "int";
};
struct MemBlock {
bool free;
void* ptr;
size_t size;
};
std::vector<MemBlock*> mem;
size_t mem_size = 0;
int count = 0;
void* mem_alloc(size_t size) {
for (int i = 0; i < count; i++) {
MemBlock* block = mem[i];
if (block->free) {
mem_size -= block->size;
mem_size += size;
block->free = false;
block->ptr = malloc(size);
block->size = size;
if (block->ptr == nullptr) {
throw std::exception();
}
return block->ptr;
}
}
void* ptr = malloc(sizeof(size));
MemBlock* block = (MemBlock*) malloc(sizeof(MemBlock));
*block = (MemBlock) {
false,
ptr,
size
};
mem_size += size;
count++;
mem.push_back(block);
std::cout << "HI" << std::endl;
return block->ptr;
}
void mem_free(void* ptr) {
for (int i = 0; i < count; i++) {
MemBlock* block = mem[i];
if (block->ptr == ptr) {
free(ptr);
mem_size -= block->size;
block->size = 0;
block->ptr = nullptr;
block->free = true;
}
}
}
int main() {
// Create new Integer-Object
Int* i = (Int*) mem_alloc(sizeof(Int));
std::cout << "[Pointer]: " << i << std::endl;
*i = (Int) {};
i->value = 5;
std::cout << "[Value]: " << i->value << std::endl;
}
好吧,感谢 Retired Ninja and Richar Critten,我找到了解决方案。
在mem_alloc()
中我用sizeof(size)
给指针分配内存,这当然是错误的。我想经过几个小时的编码,我的脑子已经很不正常了。
不过我想这个问题现在已经解决了。
我一直在写一个VM/Interpreter组合的东西,我不知道如何准确描述它。
一切都按预期运行,现在在我有数百行代码之前,我想进入 Garba Collection,因为有些指针不知何故以某种方式丢失了。并不是说我没有删除指针,而是我创建了指针,但是它们在 interpreting/running 代码的过程中以某种方式丢失了。
所以,我想追踪他们。我以某种方式编写了自己的“内存管理器”,它只是一个 std::vector
,我在其中收集所有指针。
为了跟踪和分配指针,我有以下代码:
struct MemBlock {
bool free;
void* ptr;
size_t size;
};
std::vector<MemBlock*> mem;
size_t max_size;
size_t mem_size;
int count = 0;
void mem_init(size_t maxSize) {
max_size = size/sizeof(MemBlock*);
}
void* mem_alloc(size_t size) {
for (int i = 0; i < count; i++) {
MemBlock* block = mem[i];
if (block->free) {
mem_size -= block->size;
mem_size += size;
block->free = false;
block->ptr = malloc(size);
block->size = size;
if (block->ptr == nullptr) {
throw std::exception();
}
return block->ptr;
}
}
void* ptr = malloc(sizeof(size));
if (ptr == nullptr) {
throw PointerNullException();
}
MemBlock* block = (MemBlock*) malloc(sizeof(MemBlock));
*block = (MemBlock) {
false,
ptr,
size
};
mem_size += size;
count++;
mem.push_back(block);
return block->ptr;
}
但是,当我使用 mem_alloc()
并初始化指针内部的对象时:
Int* i = (Int*) mem_alloc(sizeof(Int));
*i = (Int) {}; // -- Here
i->value = atoi(advance().c_str());
GCC AdressSanitizer 显示以下错误:
==5939==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000098 at pc 0x555963d82fc5 bp 0x7fff4ec39070 sp 0x7fff4ec39060
WRITE of size 4 at 0x602000000098 thread T0
如果我删除所述行,那么它只会出现在下一行。指针确实指向一个有效的内存位置,否则它应该抛出异常。 当然,我确定我错过了 something/did 一些错误。
但我不知道是什么。我是这样学的,或者至少我是这样理解的...
编辑: 这将是一个最小的可重现示例:
#include <iostream>
#include <stdlib.h>
#include <vector>
struct Object {
const char* type;
};
template <typename T>
struct Primitive : Object {
T value;
};
struct Int : Primitive<int> {
const char* type = "int";
};
struct MemBlock {
bool free;
void* ptr;
size_t size;
};
std::vector<MemBlock*> mem;
size_t mem_size = 0;
int count = 0;
void* mem_alloc(size_t size) {
for (int i = 0; i < count; i++) {
MemBlock* block = mem[i];
if (block->free) {
mem_size -= block->size;
mem_size += size;
block->free = false;
block->ptr = malloc(size);
block->size = size;
if (block->ptr == nullptr) {
throw std::exception();
}
return block->ptr;
}
}
void* ptr = malloc(sizeof(size));
MemBlock* block = (MemBlock*) malloc(sizeof(MemBlock));
*block = (MemBlock) {
false,
ptr,
size
};
mem_size += size;
count++;
mem.push_back(block);
std::cout << "HI" << std::endl;
return block->ptr;
}
void mem_free(void* ptr) {
for (int i = 0; i < count; i++) {
MemBlock* block = mem[i];
if (block->ptr == ptr) {
free(ptr);
mem_size -= block->size;
block->size = 0;
block->ptr = nullptr;
block->free = true;
}
}
}
int main() {
// Create new Integer-Object
Int* i = (Int*) mem_alloc(sizeof(Int));
std::cout << "[Pointer]: " << i << std::endl;
*i = (Int) {};
i->value = 5;
std::cout << "[Value]: " << i->value << std::endl;
}
好吧,感谢 Retired Ninja and Richar Critten,我找到了解决方案。
在mem_alloc()
中我用sizeof(size)
给指针分配内存,这当然是错误的。我想经过几个小时的编码,我的脑子已经很不正常了。
不过我想这个问题现在已经解决了。