Skip to content

Commit 114f305

Browse files
[kernel][memheap]add memory heap track and memory heap check.
Signed-off-by: WillianChan <[email protected]>
1 parent e596921 commit 114f305

File tree

1 file changed

+186
-13
lines changed

1 file changed

+186
-13
lines changed

src/memheap.c

Lines changed: 186 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,45 @@
3535

3636
#define RT_MEMHEAP_SIZE RT_ALIGN(sizeof(struct rt_memheap_item), RT_ALIGN_SIZE)
3737
#define MEMITEM_SIZE(item) ((rt_ubase_t)item->next - (rt_ubase_t)item - RT_MEMHEAP_SIZE)
38+
#define MEMITEM(ptr) (struct rt_memheap_item*)((rt_uint8_t*)ptr - RT_MEMHEAP_SIZE)
39+
40+
#ifdef RT_USING_MEMTRACE
41+
rt_inline void rt_memheap_setname(struct rt_memheap_item *item, const char *name)
42+
{
43+
int index;
44+
rt_uint8_t* ptr;
45+
46+
ptr = (rt_uint8_t*)&(item->next_free);
47+
for (index = 0; index < sizeof(void*); index ++)
48+
{
49+
if (name[index] == '\0') break;
50+
ptr[index] = name[index];
51+
}
52+
if (name[index] == '\0') ptr[index] = '\0';
53+
else
54+
{
55+
ptr = (rt_uint8_t*)&(item->prev_free);
56+
for (index = 0; index < sizeof(void*) && (index + sizeof(void*))< RT_NAME_MAX; index ++)
57+
{
58+
if (name[sizeof(void*) + index] == '\0') break;
59+
ptr[index] = name[sizeof(void*) + index];
60+
}
61+
62+
if (name[sizeof(void*) + index] == '\0') ptr[index] = '\0';
63+
}
64+
}
65+
66+
void rt_mem_set_tag(void* ptr, const char* name)
67+
{
68+
struct rt_memheap_item* item;
69+
70+
if (ptr && name)
71+
{
72+
item = MEMITEM(ptr);
73+
rt_memheap_setname(item, name);
74+
}
75+
}
76+
#endif
3877

3978
/*
4079
* The initialized memory pool will be:
@@ -66,7 +105,7 @@ rt_err_t rt_memheap_init(struct rt_memheap *memheap,
66105

67106
/* initialize the free list header */
68107
item = &(memheap->free_header);
69-
item->magic = RT_MEMHEAP_MAGIC;
108+
item->magic = (RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED);
70109
item->pool_ptr = memheap;
71110
item->next = RT_NULL;
72111
item->prev = RT_NULL;
@@ -78,7 +117,7 @@ rt_err_t rt_memheap_init(struct rt_memheap *memheap,
78117

79118
/* initialize the first big memory block */
80119
item = (struct rt_memheap_item *)start_addr;
81-
item->magic = RT_MEMHEAP_MAGIC;
120+
item->magic = (RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED);
82121
item->pool_ptr = memheap;
83122
item->next = RT_NULL;
84123
item->prev = RT_NULL;
@@ -103,7 +142,7 @@ rt_err_t rt_memheap_init(struct rt_memheap *memheap,
103142
*/
104143
item = item->next;
105144
/* it's a used memory block */
106-
item->magic = RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED;
145+
item->magic = (RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED);
107146
item->pool_ptr = memheap;
108147
item->next = (struct rt_memheap_item *)start_addr;
109148
item->prev = (struct rt_memheap_item *)start_addr;
@@ -201,7 +240,7 @@ void *rt_memheap_alloc(struct rt_memheap *heap, rt_size_t size)
201240
new_ptr));
202241

203242
/* mark the new block as a memory block and freed. */
204-
new_ptr->magic = RT_MEMHEAP_MAGIC;
243+
new_ptr->magic = (RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED);
205244

206245
/* put the pool pointer into the new block. */
207246
new_ptr->pool_ptr = heap;
@@ -255,7 +294,7 @@ void *rt_memheap_alloc(struct rt_memheap *heap, rt_size_t size)
255294
}
256295

257296
/* Mark the allocated block as not available. */
258-
header_ptr->magic |= RT_MEMHEAP_USED;
297+
header_ptr->magic = (RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED);
259298

260299
/* release lock */
261300
rt_sem_release(&(heap->lock));
@@ -376,7 +415,7 @@ void *rt_memheap_realloc(struct rt_memheap *heap, void *ptr, rt_size_t newsize)
376415
next_ptr->prev));
377416

378417
/* mark the new block as a memory block and freed. */
379-
next_ptr->magic = RT_MEMHEAP_MAGIC;
418+
next_ptr->magic = (RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED);
380419

381420
/* put the pool pointer into the new block. */
382421
next_ptr->pool_ptr = heap;
@@ -441,7 +480,7 @@ void *rt_memheap_realloc(struct rt_memheap *heap, void *ptr, rt_size_t newsize)
441480
new_ptr));
442481

443482
/* mark the new block as a memory block and freed. */
444-
new_ptr->magic = RT_MEMHEAP_MAGIC;
483+
new_ptr->magic = (RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED);
445484
/* put the pool pointer into the new block. */
446485
new_ptr->pool_ptr = heap;
447486

@@ -512,8 +551,11 @@ void rt_memheap_free(void *ptr)
512551
ptr, header_ptr));
513552

514553
/* check magic */
515-
RT_ASSERT((header_ptr->magic & RT_MEMHEAP_MASK) == RT_MEMHEAP_MAGIC);
516-
RT_ASSERT(header_ptr->magic & RT_MEMHEAP_USED);
554+
if (header_ptr->magic != (RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED))
555+
{
556+
RT_DEBUG_LOG("bad magic:0x%08x @ memheap\n", header_ptr->magic);
557+
}
558+
RT_ASSERT(header_ptr->magic == (RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED));
517559
/* check whether this block of memory has been over-written. */
518560
RT_ASSERT((header_ptr->next->magic & RT_MEMHEAP_MASK) == RT_MEMHEAP_MAGIC);
519561

@@ -533,9 +575,9 @@ void rt_memheap_free(void *ptr)
533575
}
534576

535577
/* Mark the memory as available. */
536-
header_ptr->magic &= ~RT_MEMHEAP_USED;
578+
header_ptr->magic = (RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED);
537579
/* Adjust the available number of bytes. */
538-
heap->available_size = heap->available_size + MEMITEM_SIZE(header_ptr);
580+
heap->available_size += MEMITEM_SIZE(header_ptr);
539581

540582
/* Determine if the block can be merged with the previous neighbor. */
541583
if (!RT_MEMHEAP_IS_USED(header_ptr->prev))
@@ -544,7 +586,7 @@ void rt_memheap_free(void *ptr)
544586
header_ptr->prev));
545587

546588
/* adjust the available number of bytes. */
547-
heap->available_size = heap->available_size + RT_MEMHEAP_SIZE;
589+
heap->available_size += RT_MEMHEAP_SIZE;
548590

549591
/* yes, merge block with previous neighbor. */
550592
(header_ptr->prev)->next = header_ptr->next;
@@ -560,7 +602,7 @@ void rt_memheap_free(void *ptr)
560602
if (!RT_MEMHEAP_IS_USED(header_ptr->next))
561603
{
562604
/* adjust the available number of bytes. */
563-
heap->available_size = heap->available_size + RT_MEMHEAP_SIZE;
605+
heap->available_size += RT_MEMHEAP_SIZE;
564606

565607
/* merge block with next neighbor. */
566608
new_ptr = header_ptr->next;
@@ -595,6 +637,91 @@ void rt_memheap_free(void *ptr)
595637
}
596638
RTM_EXPORT(rt_memheap_free);
597639

640+
#ifdef RT_USING_FINSH
641+
static void _memheap_dump_tag(struct rt_memheap_item* item)
642+
{
643+
rt_uint8_t name[2 * sizeof(void*)];
644+
rt_uint8_t* ptr;
645+
646+
ptr = (rt_uint8_t*)&(item->next_free);
647+
rt_memcpy(name, ptr, sizeof(void*));
648+
ptr = (rt_uint8_t*)&(item->prev_free);
649+
rt_memcpy(&name[sizeof(void*)], ptr, sizeof(void*));
650+
651+
rt_kprintf("%.*s", 2 * sizeof(void*), name);
652+
}
653+
654+
int rt_memheap_dump(struct rt_memheap *heap)
655+
{
656+
struct rt_memheap_item *item, *end;
657+
658+
if (heap == RT_NULL) return 0;
659+
RT_ASSERT(rt_object_get_type(&heap->parent) == RT_Object_Class_MemHeap);
660+
661+
rt_kprintf("\n[%.*s] [0x%08x - 0x%08x]->\n", RT_NAME_MAX, heap->parent.name,
662+
(rt_ubase_t)heap->start_addr, (rt_ubase_t)heap->start_addr + heap->pool_size);
663+
rt_kprintf("------------------------------\n");
664+
665+
/* lock memheap */
666+
rt_sem_take(&(heap->lock), RT_WAITING_FOREVER);
667+
item = heap->block_list;
668+
669+
end = (struct rt_memheap_item *) ((rt_uint8_t *)heap->start_addr + heap->pool_size - RT_MEMHEAP_SIZE);
670+
671+
/* for each memory block */
672+
while ((rt_ubase_t)item < ((rt_ubase_t)end))
673+
{
674+
if (RT_MEMHEAP_IS_USED(item) && ((item->magic & RT_MEMHEAP_MASK) != RT_MEMHEAP_MAGIC))
675+
rt_kprintf("0x%08x", item + 1);
676+
677+
if (item->magic == (RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED))
678+
{
679+
rt_kprintf("0x%08x: %-8d ", item + 1, MEMITEM_SIZE(item));
680+
_memheap_dump_tag(item);
681+
rt_kprintf("\n");
682+
}
683+
else
684+
{
685+
rt_kprintf("0x%08x: %-8d <F>\n", item + 1, MEMITEM_SIZE(item));
686+
}
687+
688+
item = item->next;
689+
}
690+
rt_sem_release(&(heap->lock));
691+
692+
return 0;
693+
}
694+
695+
int memtrace(void)
696+
{
697+
int count = rt_object_get_length(RT_Object_Class_MemHeap);
698+
struct rt_memheap **heaps;
699+
700+
if (count > 0)
701+
{
702+
int index;
703+
extern int list_memheap(void);
704+
705+
heaps = (struct rt_memheap**)rt_malloc(sizeof(struct rt_memheap*) * count);
706+
if (heaps == RT_NULL) return 0;
707+
708+
list_memheap();
709+
710+
rt_kprintf("memheap header size: %d\n", RT_MEMHEAP_SIZE);
711+
count = rt_object_get_pointers(RT_Object_Class_MemHeap, (rt_object_t*)heaps, count);
712+
for (index = 0; index < count; index++)
713+
{
714+
rt_memheap_dump(heaps[index]);
715+
}
716+
717+
rt_free(heaps);
718+
}
719+
720+
return 0;
721+
}
722+
MSH_CMD_EXPORT(memtrace, dump memory trace information);
723+
#endif
724+
598725
#ifdef RT_USING_MEMHEAP_AS_HEAP
599726
static struct rt_memheap _heap;
600727

@@ -643,6 +770,24 @@ void *rt_malloc(rt_size_t size)
643770
}
644771
}
645772

773+
774+
#ifdef RT_USING_MEMTRACE
775+
if (ptr == RT_NULL)
776+
{
777+
RT_DEBUG_LOG("malloc[%d] => NULL", size);
778+
}
779+
else
780+
{
781+
struct rt_memheap_item *item = MEMITEM(ptr);
782+
if (rt_thread_self())
783+
rt_memheap_setname(item, rt_thread_self()->name);
784+
else
785+
rt_memheap_setname(item, "<null>");
786+
787+
RT_DEBUG_LOG("malloc => 0x%08x : %d", ptr, size);
788+
}
789+
#endif
790+
646791
return ptr;
647792
}
648793
RTM_EXPORT(rt_malloc);
@@ -691,6 +836,23 @@ void *rt_realloc(void *rmem, rt_size_t newsize)
691836
}
692837
}
693838

839+
#ifdef RT_USING_MEMTRACE
840+
if (new_ptr == RT_NULL)
841+
{
842+
RT_DEBUG_LOG("realloc[%d] => NULL", newsize);
843+
}
844+
else
845+
{
846+
struct rt_memheap_item *item = MEMITEM(new_ptr);
847+
if (rt_thread_self())
848+
rt_memheap_setname(item, rt_thread_self()->name);
849+
else
850+
rt_memheap_setname(item, "<null>");
851+
852+
RT_DEBUG_LOG("realloc => 0x%08x : %d", new_ptr, newsize);
853+
}
854+
#endif
855+
694856
return new_ptr;
695857
}
696858
RTM_EXPORT(rt_realloc);
@@ -708,6 +870,17 @@ void *rt_calloc(rt_size_t count, rt_size_t size)
708870
rt_memset(ptr, 0, total_size);
709871
}
710872

873+
#ifdef RT_USING_MEMTRACE
874+
if (ptr == RT_NULL)
875+
{
876+
RT_DEBUG_LOG("calloc[%d x %d] => NULL", count, size);
877+
}
878+
else
879+
{
880+
RT_DEBUG_LOG("calloc => 0x%08x : %d", ptr, count * size);
881+
}
882+
#endif
883+
711884
return ptr;
712885
}
713886
RTM_EXPORT(rt_calloc);

0 commit comments

Comments
 (0)