Skip to content

Commit cb764bb

Browse files
committed
[stdlib] Add err_context in heap_assert and updated linker.ld
1 parent 00de772 commit cb764bb

File tree

2 files changed

+39
-27
lines changed

2 files changed

+39
-27
lines changed

linker.ld

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ SECTIONS
33
.text ALIGN(8) : { *(.text) }
44
.data ALIGN(8) : {
55
*(.data)
6+
}
7+
.bss ALIGN(8) : {
68
*(.bss)
7-
}
9+
}
810
_heap_start = .;
911
}

src/usr/lib/stdlib.c

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ static union heap_entry {
199199

200200
extern void *get_current_esp(); // defined in stdlib.asm
201201
// symbol name is defined in linker.ld
202-
extern char _heap_start[];
202+
extern char _heap_start;
203203
static const int heap_stack_safety_gap =
204204
1024; // keep 1 kb free between stack and heap
205205
static int heap_initialized = 0; // false
@@ -218,22 +218,26 @@ int benchmark_get_heap_area() {
218218
return benchmark_heap_area;
219219
}
220220

221-
static inline void heap_panic(const char *msg) {
221+
static inline void heap_panic(const char *msg, const char *context) {
222222
printf("heap memory err: %s\n", msg);
223+
if (context) {
224+
printf("context: %s\n", context);
225+
}
223226
exit(-1);
224227
}
225228

226-
static inline void heap_assert(int is_not_panic, const char *msg) {
229+
static inline void heap_assert(int is_not_panic, const char *msg,
230+
const char *context) {
227231
if (!is_not_panic) {
228-
heap_panic(msg);
232+
heap_panic(msg, context);
229233
}
230234
return;
231235
}
232236

233237
static inline void heap_may_init() {
234238
if (!heap_initialized) {
235-
union heap_entry *first = &(((union heap_entry *)_heap_start)[0]);
236-
union heap_entry *last = &(((union heap_entry *)_heap_start)[1]);
239+
union heap_entry *first = &(((union heap_entry *)&_heap_start)[0]);
240+
union heap_entry *last = &(((union heap_entry *)&_heap_start)[1]);
237241
first->content.state = HEAP_BLOCK_FIRST;
238242
last->content.state = HEAP_BLOCK_LAST;
239243
first->content.prev_size = 0;
@@ -246,21 +250,23 @@ static inline void heap_may_init() {
246250
}
247251

248252
static inline union heap_entry *heap_next_block(union heap_entry *current,
249-
int verify_signature) {
253+
int verify_signature,
254+
const char *err_context) {
250255
union heap_entry *block = (((void *)current) + current->content.size);
251256
if (verify_signature) {
252257
heap_assert(block->content.signature == HEAP_ENTRY_SIGNATURE,
253-
"heap_next_block, invalid signature");
258+
"heap_next_block, invalid signature", err_context);
254259
}
255260
return block;
256261
}
257262

258263
static inline union heap_entry *heap_prev_block(union heap_entry *current,
259-
int verify_signature) {
264+
int verify_signature,
265+
const char *err_context) {
260266
union heap_entry *block = (((void *)current) - current->content.prev_size);
261267
if (verify_signature) {
262268
heap_assert(block->content.signature == HEAP_ENTRY_SIGNATURE,
263-
"heap_prev_block, invalid signature");
269+
"heap_prev_block, invalid signature", err_context);
264270
}
265271
return block;
266272
}
@@ -270,29 +276,30 @@ heap_block_from_usermemory(void *ptr, int verify_signature) {
270276
union heap_entry *block = ptr - HEAP_HEADER_SIZE;
271277
if (verify_signature) {
272278
heap_assert(block->content.signature == HEAP_ENTRY_SIGNATURE,
273-
"heap_block_from_usermemory, invalid signature");
279+
"heap_block_from_usermemory, invalid signature", NULL);
274280
}
275281
return block;
276282
}
277283

278284
static inline union heap_entry *heap_push_back(union heap_entry *olast,
279285
size_t new_size) {
280286
heap_assert(olast->content.state == HEAP_BLOCK_LAST,
281-
"heap_push_back not called on last");
287+
"heap_push_back not called on last", NULL);
282288
void *_heap_end = get_current_esp() - heap_stack_safety_gap;
283289

284290
olast->content.state = HEAP_BLOCK_FREE;
285291
olast->content.size = new_size;
286292

287-
union heap_entry *nlast = heap_next_block(olast, 0);
293+
union heap_entry *nlast = heap_next_block(olast, 0, NULL);
288294

289295
benchmark_heap_area =
290-
max(benchmark_heap_area, (int)nlast - (int)_heap_start);
296+
max(benchmark_heap_area, (int)nlast - (int)&_heap_start);
291297

292298
// panic if no memory to allocate
293299
// using nlast instead of heap_next_block(nlast) as diff
294300
// should be negligible compared to heap_stack_safety_gap.
295-
heap_assert(_heap_end > (void *)nlast, "failed to allocate more memory");
301+
heap_assert(_heap_end > (void *)nlast, "failed to allocate more memory",
302+
NULL);
296303

297304
// new last block
298305
nlast->content.state = HEAP_BLOCK_LAST;
@@ -305,7 +312,7 @@ static inline union heap_entry *heap_push_back(union heap_entry *olast,
305312
static inline union heap_entry *heap_freeblock_split(union heap_entry *node,
306313
size_t first_size) {
307314
heap_assert(node->content.state == HEAP_BLOCK_FREE,
308-
"heap_freeblock_split not called on free block");
315+
"heap_freeblock_split not called on free block", NULL);
309316

310317
// before: [ -------- old-free-block--------- ] [out-block]
311318
// after : [ new-first-block][new-second-block] [out-block]
@@ -314,17 +321,18 @@ static inline union heap_entry *heap_freeblock_split(union heap_entry *node,
314321
size_t second_block_size = old_size - first_size;
315322

316323
heap_assert(first_size <= old_size,
317-
"heap_freeblock_split !(first_size<=old_size)");
324+
"heap_freeblock_split !(first_size<=old_size)", NULL);
318325

319326
if (second_block_size < HEAP_HEADER_SIZE + 4) {
320327
// do not split block if second_block_data_size < 4
321328
return node;
322329
}
323330

324-
union heap_entry *out_block = heap_next_block(node, 1);
331+
union heap_entry *out_block =
332+
heap_next_block(node, 1, "heap_freeblock_split/out_block");
325333
node->content.size = first_size;
326334

327-
union heap_entry *second = heap_next_block(node, 0);
335+
union heap_entry *second = heap_next_block(node, 0, NULL);
328336
second->content.state = second->content.state;
329337
second->content.size = second_block_size;
330338
second->content.prev_size = node->content.size;
@@ -336,17 +344,19 @@ static inline union heap_entry *heap_freeblock_split(union heap_entry *node,
336344

337345
static inline union heap_entry *heap_freeblocks_merge(union heap_entry *node) {
338346
heap_assert(node->content.state == HEAP_BLOCK_FREE,
339-
"heap_freeblocks_merge not called on free block");
347+
"heap_freeblocks_merge not called on free block", NULL);
340348

341349
// before: [prev] [ node ] [next]
342350
// after : [prev] [ node ] [next] OR
343351
// after : [prev + node ] [next] OR
344352
// after : [prev] [ node + next] OR
345353
// after : [prev + node + next]
346354

347-
union heap_entry *prev = heap_prev_block(node, 1);
355+
union heap_entry *prev =
356+
heap_prev_block(node, 1, "heap_freeblocks_merge/prev");
348357

349-
union heap_entry *next = heap_next_block(node, 1);
358+
union heap_entry *next =
359+
heap_next_block(node, 1, "heap_freeblocks_merge/next");
350360
if (prev->content.state == HEAP_BLOCK_FREE) {
351361
// merge
352362
prev->content.size += node->content.size;
@@ -356,15 +366,16 @@ static inline union heap_entry *heap_freeblocks_merge(union heap_entry *node) {
356366
if (next->content.state == HEAP_BLOCK_FREE) {
357367
// merge
358368

359-
union heap_entry *next_2 = heap_next_block(next, 1);
369+
union heap_entry *next_2 =
370+
heap_next_block(next, 1, "heap_freeblocks_merge/next_2");
360371
node->content.size += next->content.size;
361372
next_2->content.prev_size = node->content.size;
362373
}
363374
return node;
364375
}
365376

366377
static inline union heap_entry *heap_get_free_block(size_t new_size) {
367-
union heap_entry *block = (union heap_entry *)_heap_start; // start
378+
union heap_entry *block = (union heap_entry *)&_heap_start; // start
368379
uint32_t most_appropriate_value = UINT_MAX;
369380
union heap_entry *most_appropriate_block = NULL;
370381
while (1) {
@@ -383,8 +394,7 @@ static inline union heap_entry *heap_get_free_block(size_t new_size) {
383394
#endif
384395
}
385396
}
386-
387-
block = heap_next_block(block, 1);
397+
block = heap_next_block(block, 1, "heap_get_free_block");
388398
}
389399
if (most_appropriate_block == NULL) {
390400
return heap_push_back(block, new_size);

0 commit comments

Comments
 (0)