mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-08 20:56:13 +00:00
Add compilation flag to enable/disable heap corruption check (#2766)
Heap corruption check in ems memory allocator is enabled by default to improve the security, but it may impact the performance a lot, this PR adds cmake variable and compiler flag to enable/disable it.
This commit is contained in:
parent
fc03bc073e
commit
40d33d806b
|
@ -315,6 +315,11 @@
|
||||||
#define BH_ENABLE_GC_VERIFY 0
|
#define BH_ENABLE_GC_VERIFY 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Heap corruption check, enabled by default */
|
||||||
|
#ifndef BH_ENABLE_GC_CORRUPTION_CHECK
|
||||||
|
#define BH_ENABLE_GC_CORRUPTION_CHECK 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Enable global heap pool if heap verification is enabled */
|
/* Enable global heap pool if heap verification is enabled */
|
||||||
#if BH_ENABLE_GC_VERIFY != 0
|
#if BH_ENABLE_GC_VERIFY != 0
|
||||||
#define WASM_ENABLE_GLOBAL_HEAP_POOL 1
|
#define WASM_ENABLE_GLOBAL_HEAP_POOL 1
|
||||||
|
|
|
@ -24,19 +24,23 @@ hmu_is_in_heap(void *hmu, gc_uint8 *heap_base_addr, gc_uint8 *heap_end_addr)
|
||||||
static bool
|
static bool
|
||||||
remove_tree_node(gc_heap_t *heap, hmu_tree_node_t *p)
|
remove_tree_node(gc_heap_t *heap, hmu_tree_node_t *p)
|
||||||
{
|
{
|
||||||
hmu_tree_node_t *q = NULL, **slot = NULL, *parent;
|
hmu_tree_node_t *q = NULL, **slot = NULL;
|
||||||
hmu_tree_node_t *root = heap->kfc_tree_root;
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
|
hmu_tree_node_t *root = heap->kfc_tree_root, *parent;
|
||||||
gc_uint8 *base_addr = heap->base_addr;
|
gc_uint8 *base_addr = heap->base_addr;
|
||||||
gc_uint8 *end_addr = base_addr + heap->current_size;
|
gc_uint8 *end_addr = base_addr + heap->current_size;
|
||||||
|
#endif
|
||||||
|
|
||||||
bh_assert(p);
|
bh_assert(p);
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
parent = p->parent;
|
parent = p->parent;
|
||||||
if (!parent || p == root /* p can not be the ROOT node */
|
if (!parent || p == root /* p can not be the ROOT node */
|
||||||
|| !hmu_is_in_heap(p, base_addr, end_addr)
|
|| !hmu_is_in_heap(p, base_addr, end_addr)
|
||||||
|| (parent != root && !hmu_is_in_heap(parent, base_addr, end_addr))) {
|
|| (parent != root && !hmu_is_in_heap(parent, base_addr, end_addr))) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* get the slot which holds pointer to node p */
|
/* get the slot which holds pointer to node p */
|
||||||
if (p == p->parent->right) {
|
if (p == p->parent->right) {
|
||||||
|
@ -67,9 +71,11 @@ remove_tree_node(gc_heap_t *heap, hmu_tree_node_t *p)
|
||||||
/* move right child up*/
|
/* move right child up*/
|
||||||
*slot = p->right;
|
*slot = p->right;
|
||||||
if (p->right) {
|
if (p->right) {
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(p->right, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(p->right, base_addr, end_addr)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
p->right->parent = p->parent;
|
p->right->parent = p->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,9 +86,11 @@ remove_tree_node(gc_heap_t *heap, hmu_tree_node_t *p)
|
||||||
if (!p->right) {
|
if (!p->right) {
|
||||||
/* move left child up*/
|
/* move left child up*/
|
||||||
*slot = p->left;
|
*slot = p->left;
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(p->left, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(p->left, base_addr, end_addr)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/* p->left can never be NULL unless it is corrupted. */
|
/* p->left can never be NULL unless it is corrupted. */
|
||||||
p->left->parent = p->parent;
|
p->left->parent = p->parent;
|
||||||
|
|
||||||
|
@ -92,14 +100,18 @@ remove_tree_node(gc_heap_t *heap, hmu_tree_node_t *p)
|
||||||
|
|
||||||
/* both left & right exist, find p's predecessor at first*/
|
/* both left & right exist, find p's predecessor at first*/
|
||||||
q = p->left;
|
q = p->left;
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(q, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(q, base_addr, end_addr)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
while (q->right) {
|
while (q->right) {
|
||||||
q = q->right;
|
q = q->right;
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(q, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(q, base_addr, end_addr)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove from the tree*/
|
/* remove from the tree*/
|
||||||
|
@ -111,15 +123,19 @@ remove_tree_node(gc_heap_t *heap, hmu_tree_node_t *p)
|
||||||
q->left = p->left;
|
q->left = p->left;
|
||||||
q->right = p->right;
|
q->right = p->right;
|
||||||
if (q->left) {
|
if (q->left) {
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(q->left, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(q->left, base_addr, end_addr)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
q->left->parent = q;
|
q->left->parent = q;
|
||||||
}
|
}
|
||||||
if (q->right) {
|
if (q->right) {
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(q->right, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(q->right, base_addr, end_addr)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
q->right->parent = q;
|
q->right->parent = q;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,27 +143,35 @@ remove_tree_node(gc_heap_t *heap, hmu_tree_node_t *p)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
fail:
|
fail:
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
unlink_hmu(gc_heap_t *heap, hmu_t *hmu)
|
unlink_hmu(gc_heap_t *heap, hmu_t *hmu)
|
||||||
{
|
{
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
gc_uint8 *base_addr, *end_addr;
|
gc_uint8 *base_addr, *end_addr;
|
||||||
|
#endif
|
||||||
gc_size_t size;
|
gc_size_t size;
|
||||||
|
|
||||||
bh_assert(gci_is_heap_valid(heap));
|
bh_assert(gci_is_heap_valid(heap));
|
||||||
bh_assert(hmu && (gc_uint8 *)hmu >= heap->base_addr
|
bh_assert(hmu && (gc_uint8 *)hmu >= heap->base_addr
|
||||||
&& (gc_uint8 *)hmu < heap->base_addr + heap->current_size);
|
&& (gc_uint8 *)hmu < heap->base_addr + heap->current_size);
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (hmu_get_ut(hmu) != HMU_FC) {
|
if (hmu_get_ut(hmu) != HMU_FC) {
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
base_addr = heap->base_addr;
|
base_addr = heap->base_addr;
|
||||||
end_addr = base_addr + heap->current_size;
|
end_addr = base_addr + heap->current_size;
|
||||||
|
#endif
|
||||||
size = hmu_get_size(hmu);
|
size = hmu_get_size(hmu);
|
||||||
|
|
||||||
if (HMU_IS_FC_NORMAL(size)) {
|
if (HMU_IS_FC_NORMAL(size)) {
|
||||||
|
@ -156,10 +180,12 @@ unlink_hmu(gc_heap_t *heap, hmu_t *hmu)
|
||||||
hmu_normal_node_t *node = heap->kfc_normal_list[node_idx].next;
|
hmu_normal_node_t *node = heap->kfc_normal_list[node_idx].next;
|
||||||
|
|
||||||
while (node) {
|
while (node) {
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(node, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(node, base_addr, end_addr)) {
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
node_next = get_hmu_normal_node_next(node);
|
node_next = get_hmu_normal_node_next(node);
|
||||||
if ((hmu_t *)node == hmu) {
|
if ((hmu_t *)node == hmu) {
|
||||||
if (!node_prev) /* list head */
|
if (!node_prev) /* list head */
|
||||||
|
@ -205,7 +231,9 @@ hmu_set_free_size(hmu_t *hmu)
|
||||||
bool
|
bool
|
||||||
gci_add_fc(gc_heap_t *heap, hmu_t *hmu, gc_size_t size)
|
gci_add_fc(gc_heap_t *heap, hmu_t *hmu, gc_size_t size)
|
||||||
{
|
{
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
gc_uint8 *base_addr, *end_addr;
|
gc_uint8 *base_addr, *end_addr;
|
||||||
|
#endif
|
||||||
hmu_normal_node_t *np = NULL;
|
hmu_normal_node_t *np = NULL;
|
||||||
hmu_tree_node_t *root = NULL, *tp = NULL, *node = NULL;
|
hmu_tree_node_t *root = NULL, *tp = NULL, *node = NULL;
|
||||||
uint32 node_idx;
|
uint32 node_idx;
|
||||||
|
@ -219,8 +247,10 @@ gci_add_fc(gc_heap_t *heap, hmu_t *hmu, gc_size_t size)
|
||||||
<= heap->base_addr + heap->current_size);
|
<= heap->base_addr + heap->current_size);
|
||||||
bh_assert(!(size & 7));
|
bh_assert(!(size & 7));
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
base_addr = heap->base_addr;
|
base_addr = heap->base_addr;
|
||||||
end_addr = base_addr + heap->current_size;
|
end_addr = base_addr + heap->current_size;
|
||||||
|
#endif
|
||||||
|
|
||||||
hmu_set_ut(hmu, HMU_FC);
|
hmu_set_ut(hmu, HMU_FC);
|
||||||
hmu_set_size(hmu, size);
|
hmu_set_size(hmu, size);
|
||||||
|
@ -228,10 +258,12 @@ gci_add_fc(gc_heap_t *heap, hmu_t *hmu, gc_size_t size)
|
||||||
|
|
||||||
if (HMU_IS_FC_NORMAL(size)) {
|
if (HMU_IS_FC_NORMAL(size)) {
|
||||||
np = (hmu_normal_node_t *)hmu;
|
np = (hmu_normal_node_t *)hmu;
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(np, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(np, base_addr, end_addr)) {
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
node_idx = size >> 3;
|
node_idx = size >> 3;
|
||||||
set_hmu_normal_node_next(np, heap->kfc_normal_list[node_idx].next);
|
set_hmu_normal_node_next(np, heap->kfc_normal_list[node_idx].next);
|
||||||
|
@ -265,10 +297,12 @@ gci_add_fc(gc_heap_t *heap, hmu_t *hmu, gc_size_t size)
|
||||||
}
|
}
|
||||||
tp = tp->left;
|
tp = tp->left;
|
||||||
}
|
}
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(tp, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(tp, base_addr, end_addr)) {
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -321,15 +355,19 @@ alloc_hmu(gc_heap_t *heap, gc_size_t size)
|
||||||
bh_assert(node_idx >= init_node_idx);
|
bh_assert(node_idx >= init_node_idx);
|
||||||
|
|
||||||
p = normal_head->next;
|
p = normal_head->next;
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(p, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(p, base_addr, end_addr)) {
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
normal_head->next = get_hmu_normal_node_next(p);
|
normal_head->next = get_hmu_normal_node_next(p);
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (((gc_int32)(uintptr_t)hmu_to_obj(p) & 7) != 0) {
|
if (((gc_int32)(uintptr_t)hmu_to_obj(p) & 7) != 0) {
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((gc_size_t)node_idx != (uint32)init_node_idx
|
if ((gc_size_t)node_idx != (uint32)init_node_idx
|
||||||
/* with bigger size*/
|
/* with bigger size*/
|
||||||
|
@ -365,10 +403,12 @@ alloc_hmu(gc_heap_t *heap, gc_size_t size)
|
||||||
bh_assert(root);
|
bh_assert(root);
|
||||||
tp = root->right;
|
tp = root->right;
|
||||||
while (tp) {
|
while (tp) {
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(tp, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(tp, base_addr, end_addr)) {
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (tp->size < size) {
|
if (tp->size < size) {
|
||||||
tp = tp->right;
|
tp = tp->right;
|
||||||
|
@ -462,10 +502,12 @@ gc_alloc_vo_internal(void *vheap, gc_size_t size, const char *file, int line)
|
||||||
/* integer overflow */
|
/* integer overflow */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (heap->is_heap_corrupted) {
|
if (heap->is_heap_corrupted) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, allocate memory failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, allocate memory failed.\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
os_mutex_lock(&heap->lock);
|
os_mutex_lock(&heap->lock);
|
||||||
|
|
||||||
|
@ -522,10 +564,12 @@ gc_realloc_vo_internal(void *vheap, void *ptr, gc_size_t size, const char *file,
|
||||||
/* integer overflow */
|
/* integer overflow */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (heap->is_heap_corrupted) {
|
if (heap->is_heap_corrupted) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, allocate memory failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, allocate memory failed.\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (obj_old) {
|
if (obj_old) {
|
||||||
hmu_old = obj_to_hmu(obj_old);
|
hmu_old = obj_to_hmu(obj_old);
|
||||||
|
@ -647,10 +691,12 @@ gc_free_vo_internal(void *vheap, gc_object_t obj, const char *file, int line)
|
||||||
return GC_SUCCESS;
|
return GC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (heap->is_heap_corrupted) {
|
if (heap->is_heap_corrupted) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, free memory failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, free memory failed.\n");
|
||||||
return GC_ERROR;
|
return GC_ERROR;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
hmu = obj_to_hmu(obj);
|
hmu = obj_to_hmu(obj);
|
||||||
|
|
||||||
|
@ -767,11 +813,13 @@ gci_dump(gc_heap_t *heap)
|
||||||
else if (ut == HMU_FC)
|
else if (ut == HMU_FC)
|
||||||
inuse = 'F';
|
inuse = 'F';
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (size == 0 || size > (uint32)((uint8 *)end - (uint8 *)cur)) {
|
if (size == 0 || size > (uint32)((uint8 *)end - (uint8 *)cur)) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, heap dump failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, heap dump failed.\n");
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
os_printf("#%d %08" PRIx32 " %" PRIx32 " %d %d"
|
os_printf("#%d %08" PRIx32 " %" PRIx32 " %d %d"
|
||||||
" %c %" PRId32 "\n",
|
" %c %" PRId32 "\n",
|
||||||
|
@ -788,8 +836,12 @@ gci_dump(gc_heap_t *heap)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (cur != end) {
|
if (cur != end) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, heap dump failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, heap dump failed.\n");
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
bh_assert(cur == end);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -271,9 +271,11 @@ typedef struct gc_heap_struct {
|
||||||
size[left] <= size[cur] < size[right] */
|
size[left] <= size[cur] < size[right] */
|
||||||
hmu_tree_node_t *kfc_tree_root;
|
hmu_tree_node_t *kfc_tree_root;
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
/* whether heap is corrupted, e.g. the hmu nodes are modified
|
/* whether heap is corrupted, e.g. the hmu nodes are modified
|
||||||
by user */
|
by user */
|
||||||
bool is_heap_corrupted;
|
bool is_heap_corrupted;
|
||||||
|
#endif
|
||||||
|
|
||||||
gc_size_t init_size;
|
gc_size_t init_size;
|
||||||
gc_size_t highmark_size;
|
gc_size_t highmark_size;
|
||||||
|
|
|
@ -83,7 +83,9 @@ hmu_verify(void *vheap, hmu_t *hmu)
|
||||||
os_printf("Invalid padding for object created at %s:%d\n",
|
os_printf("Invalid padding for object created at %s:%d\n",
|
||||||
(prefix->file_name ? prefix->file_name : ""),
|
(prefix->file_name ? prefix->file_name : ""),
|
||||||
prefix->line_no);
|
prefix->line_no);
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,8 +133,11 @@ gc_destroy_with_pool(gc_handle_t handle)
|
||||||
hmu_t *cur = (hmu_t *)heap->base_addr;
|
hmu_t *cur = (hmu_t *)heap->base_addr;
|
||||||
hmu_t *end = (hmu_t *)((char *)heap->base_addr + heap->current_size);
|
hmu_t *end = (hmu_t *)((char *)heap->base_addr + heap->current_size);
|
||||||
|
|
||||||
if (!heap->is_heap_corrupted
|
if (
|
||||||
&& (hmu_t *)((char *)cur + hmu_get_size(cur)) != end) {
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
|
!heap->is_heap_corrupted &&
|
||||||
|
#endif
|
||||||
|
(hmu_t *)((char *)cur + hmu_get_size(cur)) != end) {
|
||||||
os_printf("Memory leak detected:\n");
|
os_printf("Memory leak detected:\n");
|
||||||
gci_dump(heap);
|
gci_dump(heap);
|
||||||
ret = GC_ERROR;
|
ret = GC_ERROR;
|
||||||
|
@ -186,10 +189,12 @@ gc_migrate(gc_handle_t handle, char *pool_buf_new, gc_size_t pool_buf_size)
|
||||||
if (offset == 0)
|
if (offset == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (heap->is_heap_corrupted) {
|
if (heap->is_heap_corrupted) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
|
||||||
return GC_ERROR;
|
return GC_ERROR;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
heap->base_addr = (uint8 *)base_addr_new;
|
heap->base_addr = (uint8 *)base_addr_new;
|
||||||
|
|
||||||
|
@ -211,11 +216,13 @@ gc_migrate(gc_handle_t handle, char *pool_buf_new, gc_size_t pool_buf_size)
|
||||||
while (cur < end) {
|
while (cur < end) {
|
||||||
size = hmu_get_size(cur);
|
size = hmu_get_size(cur);
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (size <= 0 || size > (uint32)((uint8 *)end - (uint8 *)cur)) {
|
if (size <= 0 || size > (uint32)((uint8 *)end - (uint8 *)cur)) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return GC_ERROR;
|
return GC_ERROR;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (hmu_get_ut(cur) == HMU_FC && !HMU_IS_FC_NORMAL(size)) {
|
if (hmu_get_ut(cur) == HMU_FC && !HMU_IS_FC_NORMAL(size)) {
|
||||||
tree_node = (hmu_tree_node_t *)cur;
|
tree_node = (hmu_tree_node_t *)cur;
|
||||||
|
@ -238,11 +245,15 @@ gc_migrate(gc_handle_t handle, char *pool_buf_new, gc_size_t pool_buf_size)
|
||||||
cur = (hmu_t *)((char *)cur + size);
|
cur = (hmu_t *)((char *)cur + size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (cur != end) {
|
if (cur != end) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return GC_ERROR;
|
return GC_ERROR;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
bh_assert(cur == end);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -250,9 +261,13 @@ gc_migrate(gc_handle_t handle, char *pool_buf_new, gc_size_t pool_buf_size)
|
||||||
bool
|
bool
|
||||||
gc_is_heap_corrupted(gc_handle_t handle)
|
gc_is_heap_corrupted(gc_handle_t handle)
|
||||||
{
|
{
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
gc_heap_t *heap = (gc_heap_t *)handle;
|
gc_heap_t *heap = (gc_heap_t *)handle;
|
||||||
|
|
||||||
return heap->is_heap_corrupted ? true : false;
|
return heap->is_heap_corrupted ? true : false;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if BH_ENABLE_GC_VERIFY != 0
|
#if BH_ENABLE_GC_VERIFY != 0
|
||||||
|
|
|
@ -10,6 +10,14 @@ if (WAMR_BUILD_GC_VERIFY EQUAL 1)
|
||||||
add_definitions (-DBH_ENABLE_GC_VERIFY=1)
|
add_definitions (-DBH_ENABLE_GC_VERIFY=1)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
if (NOT DEFINED WAMR_BUILD_GC_CORRUPTION_CHECK)
|
||||||
|
set (WAMR_BUILD_GC_CORRUPTION_CHECK 1)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (WAMR_BUILD_GC_CORRUPTION_CHECK EQUAL 0)
|
||||||
|
add_definitions (-DBH_ENABLE_GC_CORRUPTION_CHECK=0)
|
||||||
|
endif ()
|
||||||
|
|
||||||
file (GLOB_RECURSE source_all
|
file (GLOB_RECURSE source_all
|
||||||
${MEM_ALLOC_DIR}/ems/*.c
|
${MEM_ALLOC_DIR}/ems/*.c
|
||||||
${MEM_ALLOC_DIR}/tlsf/*.c
|
${MEM_ALLOC_DIR}/tlsf/*.c
|
||||||
|
|
Loading…
Reference in New Issue
Block a user