[BACK]Return to memcheck.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / mit / expat / dist / tests

Annotation of src/external/mit/expat/dist/tests/memcheck.c, Revision 1.1.1.1.6.2

1.1.1.1.6.2! snj         1: /* Copyright (c) 2017 The Expat Maintainers
        !             2:  * Copying is permitted under the MIT license.  See the file COPYING
        !             3:  * for details.
        !             4:  *
        !             5:  * memcheck.c : debug allocators for the Expat test suite
        !             6:  */
        !             7:
        !             8: #include <stdio.h>
        !             9: #include <stdlib.h>
        !            10: #include "memcheck.h"
        !            11:
        !            12:
        !            13: /* Structures to keep track of what has been allocated.  Speed isn't a
        !            14:  * big issue for the tests this is required for, so we will use a
        !            15:  * doubly-linked list to make deletion easier.
        !            16:  */
        !            17:
        !            18: typedef struct allocation_entry {
        !            19:     struct allocation_entry * next;
        !            20:     struct allocation_entry * prev;
        !            21:     void * allocation;
        !            22:     size_t num_bytes;
        !            23: } AllocationEntry;
        !            24:
        !            25: static AllocationEntry *alloc_head = NULL;
        !            26: static AllocationEntry *alloc_tail = NULL;
        !            27:
        !            28: static AllocationEntry *find_allocation(void *ptr);
        !            29:
        !            30:
        !            31: /* Allocate some memory and keep track of it. */
        !            32: void *
        !            33: tracking_malloc(size_t size)
        !            34: {
        !            35:     AllocationEntry *entry = malloc(sizeof(AllocationEntry));
        !            36:
        !            37:     if (entry == NULL) {
        !            38:         printf("Allocator failure\n");
        !            39:         return NULL;
        !            40:     }
        !            41:     entry->num_bytes = size;
        !            42:     entry->allocation = malloc(size);
        !            43:     if (entry->allocation == NULL) {
        !            44:         free(entry);
        !            45:         return NULL;
        !            46:     }
        !            47:     entry->next = NULL;
        !            48:
        !            49:     /* Add to the list of allocations */
        !            50:     if (alloc_head == NULL) {
        !            51:         entry->prev = NULL;
        !            52:         alloc_head = alloc_tail = entry;
        !            53:     } else {
        !            54:         entry->prev = alloc_tail;
        !            55:         alloc_tail->next = entry;
        !            56:         alloc_tail = entry;
        !            57:     }
        !            58:
        !            59:     return entry->allocation;
        !            60: }
        !            61:
        !            62: static AllocationEntry *
        !            63: find_allocation(void *ptr)
        !            64: {
        !            65:     AllocationEntry *entry;
        !            66:
        !            67:     for (entry = alloc_head; entry != NULL; entry = entry->next) {
        !            68:         if (entry->allocation == ptr) {
        !            69:             return entry;
        !            70:         }
        !            71:     }
        !            72:     return NULL;
        !            73: }
        !            74:
        !            75: /* Free some memory and remove the tracking for it */
        !            76: void
        !            77: tracking_free(void *ptr)
        !            78: {
        !            79:     AllocationEntry *entry;
        !            80:
        !            81:     if (ptr == NULL) {
        !            82:         /* There won't be an entry for this */
        !            83:         return;
        !            84:     }
        !            85:
        !            86:     entry = find_allocation(ptr);
        !            87:     if (entry != NULL) {
        !            88:         /* This is the relevant allocation.  Unlink it */
        !            89:         if (entry->prev != NULL)
        !            90:             entry->prev->next = entry->next;
        !            91:         else
        !            92:             alloc_head = entry->next;
        !            93:         if (entry->next != NULL)
        !            94:             entry->next->prev = entry->prev;
        !            95:         else
        !            96:             alloc_tail = entry->next;
        !            97:         free(entry);
        !            98:     } else {
        !            99:         printf("Attempting to free unallocated memory at %p\n", ptr);
        !           100:     }
        !           101:     free(ptr);
        !           102: }
        !           103:
        !           104: /* Reallocate some memory and keep track of it */
        !           105: void *
        !           106: tracking_realloc(void *ptr, size_t size)
        !           107: {
        !           108:     AllocationEntry *entry;
        !           109:
        !           110:     if (ptr == NULL) {
        !           111:         /* By definition, this is equivalent to malloc(size) */
        !           112:         return tracking_malloc(size);
        !           113:     }
        !           114:     if (size == 0) {
        !           115:         /* By definition, this is equivalent to free(ptr) */
        !           116:         tracking_free(ptr);
        !           117:         return NULL;
        !           118:     }
        !           119:
        !           120:     /* Find the allocation entry for this memory */
        !           121:     entry = find_allocation(ptr);
        !           122:     if (entry == NULL) {
        !           123:         printf("Attempting to realloc unallocated memory at %p\n", ptr);
        !           124:         entry = malloc(sizeof(AllocationEntry));
        !           125:         if (entry == NULL) {
        !           126:             printf("Reallocator failure\n");
        !           127:             return NULL;
        !           128:         }
        !           129:         entry->allocation = realloc(ptr, size);
        !           130:         if (entry->allocation == NULL) {
        !           131:             free(entry);
        !           132:             return NULL;
        !           133:         }
        !           134:
        !           135:         /* Add to the list of allocations */
        !           136:         entry->next = NULL;
        !           137:         if (alloc_head == NULL) {
        !           138:             entry->prev = NULL;
        !           139:             alloc_head = alloc_tail = entry;
        !           140:         } else {
        !           141:             entry->prev = alloc_tail;
        !           142:             alloc_tail->next = entry;
        !           143:             alloc_tail = entry;
        !           144:         }
        !           145:     } else {
        !           146:         entry->allocation = realloc(ptr, size);
        !           147:         if (entry->allocation == NULL) {
        !           148:             /* Realloc semantics say the original is still allocated */
        !           149:             entry->allocation = ptr;
        !           150:             return NULL;
        !           151:         }
        !           152:     }
        !           153:
        !           154:     entry->num_bytes = size;
        !           155:     return entry->allocation;
        !           156: }
        !           157:
        !           158: int
        !           159: tracking_report(void)
        !           160: {
        !           161:     AllocationEntry *entry;
        !           162:
        !           163:     if (alloc_head == NULL)
        !           164:         return 1;
        !           165:
        !           166:     /* Otherwise we have allocations that haven't been freed */
        !           167:     for (entry = alloc_head; entry != NULL; entry = entry->next)
        !           168:     {
        !           169:         printf("Allocated %lu bytes at %p\n",
        !           170:                entry->num_bytes, entry->allocation);
        !           171:     }
        !           172:     return 0;
        !           173: }

CVSweb <webmaster@jp.NetBSD.org>