Add kernel heap allocation tracing debug facility.
This commit is contained in:
parent
204576b7a8
commit
250b95616b
19 changed files with 336 additions and 45 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2012, 2013, 2014 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2011, 2012, 2013, 2014, 2022 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -36,4 +36,35 @@ typedef uintptr_t addr_t;
|
||||||
#define CPU X64
|
#define CPU X64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
|
||||||
|
struct kernel_allocation_site
|
||||||
|
{
|
||||||
|
struct __allocation_site allocation_site;
|
||||||
|
struct kernel_allocation_site* next;
|
||||||
|
bool registered;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct kernel_allocation_site* first_kernel_allocation_site;
|
||||||
|
|
||||||
|
#undef ALLOCATION_SITE
|
||||||
|
#define ALLOCATION_SITE \
|
||||||
|
({ \
|
||||||
|
static struct kernel_allocation_site site = \
|
||||||
|
{ { __FILE__, __LINE__, __func__, 0, 0 }, NULL, false }; \
|
||||||
|
if ( !site.registered ) \
|
||||||
|
{ \
|
||||||
|
site.registered = true; \
|
||||||
|
site.next = first_kernel_allocation_site; \
|
||||||
|
first_kernel_allocation_site = &site; \
|
||||||
|
} \
|
||||||
|
&site.allocation_site; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
void* operator new(size_t size, struct __allocation_site* allocation_site);
|
||||||
|
void* operator new[](size_t size, struct __allocation_site* allocation_site);
|
||||||
|
#define new new (ALLOCATION_SITE)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -103,6 +103,8 @@
|
||||||
#include "x86-family/vbox.h"
|
#include "x86-family/vbox.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct kernel_allocation_site* first_kernel_allocation_site = NULL;
|
||||||
|
|
||||||
// Keep the stack size aligned with $CPU/boot.s
|
// Keep the stack size aligned with $CPU/boot.s
|
||||||
const size_t STACK_SIZE = 64*1024;
|
const size_t STACK_SIZE = 64*1024;
|
||||||
extern "C" { __attribute__((aligned(16))) size_t stack[STACK_SIZE / sizeof(size_t)]; }
|
extern "C" { __attribute__((aligned(16))) size_t stack[STACK_SIZE / sizeof(size_t)]; }
|
||||||
|
|
|
@ -55,6 +55,51 @@ ssize_t sys_kernelinfo(const char* user_req, char* user_resp, size_t resplen)
|
||||||
char* req = GetStringFromUser(user_req);
|
char* req = GetStringFromUser(user_req);
|
||||||
if ( !req )
|
if ( !req )
|
||||||
return -1;
|
return -1;
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
if ( !strcmp(req, "allocations") )
|
||||||
|
{
|
||||||
|
delete[] req;
|
||||||
|
bool exhausted = false;
|
||||||
|
size_t total_needed = 0;
|
||||||
|
for ( struct kernel_allocation_site* site = first_kernel_allocation_site;
|
||||||
|
site;
|
||||||
|
site = site->next )
|
||||||
|
{
|
||||||
|
char str[256];
|
||||||
|
snprintf(str, sizeof(str), "%20zu B %zu allocations %s:%zu %s %c",
|
||||||
|
site->allocation_site.current_size,
|
||||||
|
site->allocation_site.allocations,
|
||||||
|
site->allocation_site.file,
|
||||||
|
site->allocation_site.line,
|
||||||
|
site->allocation_site.function,
|
||||||
|
site->next ? '\n' : '\0');
|
||||||
|
size_t stringlen = strlen(str);
|
||||||
|
total_needed += stringlen;
|
||||||
|
if ( exhausted )
|
||||||
|
continue;
|
||||||
|
if ( resplen < stringlen )
|
||||||
|
{
|
||||||
|
exhausted = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( !CopyToUser(user_resp, str, sizeof(char) * stringlen) )
|
||||||
|
return -1;
|
||||||
|
user_resp += stringlen;
|
||||||
|
resplen -= stringlen;
|
||||||
|
}
|
||||||
|
if ( !exhausted && !resplen )
|
||||||
|
exhausted = true;
|
||||||
|
if ( !exhausted )
|
||||||
|
{
|
||||||
|
char zero = '\0';
|
||||||
|
if ( !CopyToUser(user_resp, &zero, 1) )
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ( exhausted )
|
||||||
|
return errno = ERANGE, (ssize_t) total_needed;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
const char* str = KernelInfo(req);
|
const char* str = KernelInfo(req);
|
||||||
delete[] req;
|
delete[] req;
|
||||||
if ( !str )
|
if ( !str )
|
||||||
|
|
|
@ -24,6 +24,19 @@
|
||||||
#warning "security: -fcheck-new might not work on clang"
|
#warning "security: -fcheck-new might not work on clang"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
#undef new
|
||||||
|
|
||||||
|
void* operator new(size_t size, struct __allocation_site* allocation_site)
|
||||||
|
{
|
||||||
|
return malloc_trace(allocation_site, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* operator new[](size_t size, struct __allocation_site* allocation_site)
|
||||||
|
{
|
||||||
|
return malloc_trace(allocation_site, size);
|
||||||
|
}
|
||||||
|
#else
|
||||||
void* operator new(size_t size)
|
void* operator new(size_t size)
|
||||||
{
|
{
|
||||||
return malloc(size);
|
return malloc(size);
|
||||||
|
@ -33,6 +46,7 @@ void* operator new[](size_t size)
|
||||||
{
|
{
|
||||||
return malloc(size);
|
return malloc(size);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void operator delete(void* addr)
|
void operator delete(void* addr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -60,20 +60,6 @@ malloc/__heap_verify.o \
|
||||||
netinet/if_ether/etheraddr_broadcast.o \
|
netinet/if_ether/etheraddr_broadcast.o \
|
||||||
netinet/in/in6addr_any.o \
|
netinet/in/in6addr_any.o \
|
||||||
netinet/in/in6addr_loopback.o \
|
netinet/in/in6addr_loopback.o \
|
||||||
regex/regcomp.o \
|
|
||||||
regex/regerror.o \
|
|
||||||
regex/regexec.o \
|
|
||||||
regex/regfree.o \
|
|
||||||
sha2/sha224hl.o \
|
|
||||||
sha2/sha224.o \
|
|
||||||
sha2/sha256hl.o \
|
|
||||||
sha2/sha256.o \
|
|
||||||
sha2/sha384hl.o \
|
|
||||||
sha2/sha384.o \
|
|
||||||
sha2/sha512_256hl.o \
|
|
||||||
sha2/sha512_256.o \
|
|
||||||
sha2/sha512hl.o \
|
|
||||||
sha2/sha512.o \
|
|
||||||
signal/sigaddset.o \
|
signal/sigaddset.o \
|
||||||
signal/sigandset.o \
|
signal/sigandset.o \
|
||||||
signal/sigdelset.o \
|
signal/sigdelset.o \
|
||||||
|
@ -86,7 +72,6 @@ signal/sigorset.o \
|
||||||
ssp/__stack_chk_fail.o \
|
ssp/__stack_chk_fail.o \
|
||||||
stdio/asprintf.o \
|
stdio/asprintf.o \
|
||||||
stdio/cbprintf.o \
|
stdio/cbprintf.o \
|
||||||
stdio/cbscanf.o \
|
|
||||||
stdio/clearerr.o \
|
stdio/clearerr.o \
|
||||||
stdio/clearerr_unlocked.o \
|
stdio/clearerr_unlocked.o \
|
||||||
stdio/dprintf.o \
|
stdio/dprintf.o \
|
||||||
|
@ -116,8 +101,6 @@ stdio/fgets.o \
|
||||||
stdio/fgets_unlocked.o \
|
stdio/fgets_unlocked.o \
|
||||||
stdio/fileno_unlocked.o \
|
stdio/fileno_unlocked.o \
|
||||||
stdio/flockfile.o \
|
stdio/flockfile.o \
|
||||||
stdio/fmemopen.o \
|
|
||||||
stdio/fnewfile.o \
|
|
||||||
stdio/fparsemode.o \
|
stdio/fparsemode.o \
|
||||||
stdio/fprintf_unlocked.o \
|
stdio/fprintf_unlocked.o \
|
||||||
stdio/fputc.o \
|
stdio/fputc.o \
|
||||||
|
@ -128,8 +111,6 @@ stdio/fread.o \
|
||||||
stdio/fread_unlocked.o \
|
stdio/fread_unlocked.o \
|
||||||
stdio/fregister.o \
|
stdio/fregister.o \
|
||||||
stdio/fresetfile.o \
|
stdio/fresetfile.o \
|
||||||
stdio/fscanf.o \
|
|
||||||
stdio/fscanf_unlocked.o \
|
|
||||||
stdio/fseek.o \
|
stdio/fseek.o \
|
||||||
stdio/fseeko.o \
|
stdio/fseeko.o \
|
||||||
stdio/fseeko_unlocked.o \
|
stdio/fseeko_unlocked.o \
|
||||||
|
@ -142,28 +123,20 @@ stdio/funlockfile.o \
|
||||||
stdio/funregister.o \
|
stdio/funregister.o \
|
||||||
stdio/fwrite.o \
|
stdio/fwrite.o \
|
||||||
stdio/fwrite_unlocked.o \
|
stdio/fwrite_unlocked.o \
|
||||||
stdio/getdelim.o \
|
|
||||||
stdio/getline.o \
|
|
||||||
stdio/open_memstream.o \
|
|
||||||
stdio/rewind.o \
|
stdio/rewind.o \
|
||||||
stdio/setbuf.o \
|
stdio/setbuf.o \
|
||||||
stdio/setvbuf.o \
|
stdio/setvbuf.o \
|
||||||
stdio/setvbuf_unlocked.o \
|
stdio/setvbuf_unlocked.o \
|
||||||
stdio/snprintf.o \
|
stdio/snprintf.o \
|
||||||
stdio/sprintf.o \
|
stdio/sprintf.o \
|
||||||
stdio/sscanf.o \
|
|
||||||
stdio/ungetc.o \
|
stdio/ungetc.o \
|
||||||
stdio/ungetc_unlocked.o \
|
stdio/ungetc_unlocked.o \
|
||||||
stdio/vasprintf.o \
|
stdio/vasprintf.o \
|
||||||
stdio/vcbprintf.o \
|
stdio/vcbprintf.o \
|
||||||
stdio/vdprintf.o \
|
stdio/vdprintf.o \
|
||||||
stdio/vfprintf_unlocked.o \
|
stdio/vfprintf_unlocked.o \
|
||||||
stdio/vfscanf.o \
|
|
||||||
stdio/vfscanf_unlocked.o \
|
|
||||||
stdio/vcbscanf.o \
|
|
||||||
stdio/vsnprintf.o \
|
stdio/vsnprintf.o \
|
||||||
stdio/vsprintf.o \
|
stdio/vsprintf.o \
|
||||||
stdio/vsscanf.o \
|
|
||||||
stdlib/abort.o \
|
stdlib/abort.o \
|
||||||
stdlib/abs.o \
|
stdlib/abs.o \
|
||||||
stdlib/arc4random_buf.o \
|
stdlib/arc4random_buf.o \
|
||||||
|
@ -278,7 +251,6 @@ wchar/wcscmp.o \
|
||||||
wchar/wcscoll.o \
|
wchar/wcscoll.o \
|
||||||
wchar/wcscpy.o \
|
wchar/wcscpy.o \
|
||||||
wchar/wcscspn.o \
|
wchar/wcscspn.o \
|
||||||
wchar/wcsdup.o \
|
|
||||||
wchar/wcsftime.o \
|
wchar/wcsftime.o \
|
||||||
wchar/wcslcat.o \
|
wchar/wcslcat.o \
|
||||||
wchar/wcslcpy.o \
|
wchar/wcslcpy.o \
|
||||||
|
@ -329,6 +301,34 @@ wctype/towupper.o \
|
||||||
wctype/wctype.o \
|
wctype/wctype.o \
|
||||||
|
|
||||||
HOSTEDOBJS=\
|
HOSTEDOBJS=\
|
||||||
|
regex/regcomp.o \
|
||||||
|
regex/regerror.o \
|
||||||
|
regex/regexec.o \
|
||||||
|
regex/regfree.o \
|
||||||
|
sha2/sha224hl.o \
|
||||||
|
sha2/sha224.o \
|
||||||
|
sha2/sha256hl.o \
|
||||||
|
sha2/sha256.o \
|
||||||
|
sha2/sha384hl.o \
|
||||||
|
sha2/sha384.o \
|
||||||
|
sha2/sha512_256hl.o \
|
||||||
|
sha2/sha512_256.o \
|
||||||
|
sha2/sha512hl.o \
|
||||||
|
sha2/sha512.o \
|
||||||
|
stdio/cbscanf.o \
|
||||||
|
stdio/fscanf.o \
|
||||||
|
stdio/fscanf_unlocked.o \
|
||||||
|
stdio/sscanf.o \
|
||||||
|
stdio/vfscanf.o \
|
||||||
|
stdio/vfscanf_unlocked.o \
|
||||||
|
stdio/vcbscanf.o \
|
||||||
|
stdio/vsscanf.o \
|
||||||
|
stdio/fmemopen.o \
|
||||||
|
stdio/open_memstream.o \
|
||||||
|
stdio/getdelim.o \
|
||||||
|
stdio/getline.o \
|
||||||
|
stdio/fnewfile.o \
|
||||||
|
wchar/wcsdup.o \
|
||||||
blf/blowfish.o \
|
blf/blowfish.o \
|
||||||
$(CPUDIR)/fork.o \
|
$(CPUDIR)/fork.o \
|
||||||
$(CPUDIR)/setjmp.o \
|
$(CPUDIR)/setjmp.o \
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2013, 2014, 2015, 2016 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2012, 2013, 2014, 2015, 2016, 2022 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -117,6 +117,16 @@ struct heap_alloc
|
||||||
#warning "You need to implement HEAP_CHUNK_MAGIC for your native word width"
|
#warning "You need to implement HEAP_CHUNK_MAGIC for your native word width"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
#define MAGIC_IS_ALLOCATION_SITE(magic)( (((size_t) (magic)) & 0x3) == 0x2)
|
||||||
|
#define ALLOCATION_SITE_OF_MAGIC(magic) ((struct __allocation_site*) ((magic) & ~0x3UL))
|
||||||
|
#define MAGIC_OF_ALLOCATION_SITE(magic) (((size_t) (magic)) | 0x2)
|
||||||
|
#else
|
||||||
|
#define MAGIC_IS_ALLOCATION_SITE(magic) 0
|
||||||
|
#define ALLOCATION_SITE_OF_MAGIC(magic) NULL
|
||||||
|
#define MAGIC_OF_ALLOCATION_SITE(magic) NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The heap is split into a number of parts that each consists of a number of
|
/* The heap is split into a number of parts that each consists of a number of
|
||||||
of chunks (used and unused). The heap normally is just a single part, but if
|
of chunks (used and unused). The heap normally is just a single part, but if
|
||||||
the address space gets too fragmented, it may not be possible to extend the
|
the address space gets too fragmented, it may not be possible to extend the
|
||||||
|
@ -346,7 +356,8 @@ bool heap_chunk_is_used(struct heap_chunk* chunk)
|
||||||
{
|
{
|
||||||
assert(HEAP_IS_POINTER_ALIGNED(chunk, chunk->chunk_size));
|
assert(HEAP_IS_POINTER_ALIGNED(chunk, chunk->chunk_size));
|
||||||
|
|
||||||
return chunk->chunk_magic == HEAP_CHUNK_MAGIC;
|
return chunk->chunk_magic == HEAP_CHUNK_MAGIC ||
|
||||||
|
MAGIC_IS_ALLOCATION_SITE(chunk->chunk_magic);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns the trailing structure following the given chunk. */
|
/* Returns the trailing structure following the given chunk. */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2012, 2013, 2014, 2015 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2011, 2012, 2013, 2014, 2015, 2022 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -242,8 +242,14 @@ int vdprintf(int fildes, const char* __restrict format, __gnuc_va_list ap)
|
||||||
|
|
||||||
/* Functions copied from elsewhere. */
|
/* Functions copied from elsewhere. */
|
||||||
#if __USE_SORTIX
|
#if __USE_SORTIX
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
int asprintf_trace(struct __allocation_site*, char** __restrict, const char* __restrict, ...)
|
||||||
|
__attribute__((__format__ (printf, 3, 4)));
|
||||||
|
#define asprintf(a, ...) asprintf_trace(ALLOCATION_SITE, (a), __VA_ARGS__)
|
||||||
|
#else
|
||||||
int asprintf(char** __restrict, const char* __restrict, ...)
|
int asprintf(char** __restrict, const char* __restrict, ...)
|
||||||
__attribute__((__format__ (printf, 2, 3)));
|
__attribute__((__format__ (printf, 2, 3)));
|
||||||
|
#endif
|
||||||
void clearerr_unlocked(FILE* stream);
|
void clearerr_unlocked(FILE* stream);
|
||||||
int feof_unlocked(FILE* stream);
|
int feof_unlocked(FILE* stream);
|
||||||
int ferror_unlocked(FILE* stream);
|
int ferror_unlocked(FILE* stream);
|
||||||
|
@ -255,9 +261,15 @@ int fputc_unlocked(int c, FILE* stream);
|
||||||
int fputs_unlocked(const char* __restrict, FILE* __restrict stream);
|
int fputs_unlocked(const char* __restrict, FILE* __restrict stream);
|
||||||
size_t fread_unlocked(void* __restrict ptr, size_t size, size_t nitems, FILE* __restrict stream);
|
size_t fread_unlocked(void* __restrict ptr, size_t size, size_t nitems, FILE* __restrict stream);
|
||||||
size_t fwrite_unlocked(const void* __restrict ptr, size_t size, size_t nitems, FILE* __restrict stream);
|
size_t fwrite_unlocked(const void* __restrict ptr, size_t size, size_t nitems, FILE* __restrict stream);
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
int vasprintf_trace(struct __allocation_site*, char** __restrict, const char* __restrict, __gnuc_va_list)
|
||||||
|
__attribute__((__format__ (printf, 3, 0)));
|
||||||
|
#define vasprintf(a, ...) vasprintf_trace(ALLOCATION_SITE, (a), __VA_ARGS__)
|
||||||
|
#else
|
||||||
int vasprintf(char** __restrict, const char* __restrict, __gnuc_va_list)
|
int vasprintf(char** __restrict, const char* __restrict, __gnuc_va_list)
|
||||||
__attribute__((__format__ (printf, 2, 0)));
|
__attribute__((__format__ (printf, 2, 0)));
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Functions that are Sortix extensions. */
|
/* Functions that are Sortix extensions. */
|
||||||
#if __USE_SORTIX
|
#if __USE_SORTIX
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011-2017 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2011-2017, 2022 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -88,7 +88,12 @@ double atof(const char* value);
|
||||||
int atoi(const char*);
|
int atoi(const char*);
|
||||||
long atol(const char*);
|
long atol(const char*);
|
||||||
void* bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*));
|
void* bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*));
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
void* calloc_trace(struct __allocation_site*, size_t, size_t);
|
||||||
|
#define calloc(a, b) calloc_trace(ALLOCATION_SITE, (a), (b))
|
||||||
|
#else
|
||||||
void* calloc(size_t, size_t);
|
void* calloc(size_t, size_t);
|
||||||
|
#endif
|
||||||
char* canonicalize_file_name(const char* path);
|
char* canonicalize_file_name(const char* path);
|
||||||
char* canonicalize_file_name_at(int dirfd, const char* path);
|
char* canonicalize_file_name_at(int dirfd, const char* path);
|
||||||
int clearenv(void);
|
int clearenv(void);
|
||||||
|
@ -99,7 +104,12 @@ void free(void*);
|
||||||
char* getenv(const char*);
|
char* getenv(const char*);
|
||||||
long labs(long);
|
long labs(long);
|
||||||
ldiv_t ldiv(long, long);
|
ldiv_t ldiv(long, long);
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
void* malloc_trace(struct __allocation_site*, size_t);
|
||||||
|
#define malloc(a) malloc_trace(ALLOCATION_SITE, (a))
|
||||||
|
#else
|
||||||
void* malloc(size_t);
|
void* malloc(size_t);
|
||||||
|
#endif
|
||||||
int mblen(const char*, size_t);
|
int mblen(const char*, size_t);
|
||||||
size_t mbstowcs(wchar_t* __restrict, const char* __restrict, size_t);
|
size_t mbstowcs(wchar_t* __restrict, const char* __restrict, size_t);
|
||||||
int mbtowc(wchar_t *__restrict, const char* __restrict, size_t);
|
int mbtowc(wchar_t *__restrict, const char* __restrict, size_t);
|
||||||
|
@ -116,7 +126,12 @@ void qsort_r(void*, size_t, size_t, int (*)(const void*, const void*, void*), vo
|
||||||
__attribute__((__warning__("rand() isn't random, use arc4random()")))
|
__attribute__((__warning__("rand() isn't random, use arc4random()")))
|
||||||
#endif
|
#endif
|
||||||
int rand(void);
|
int rand(void);
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
void* realloc_trace(struct __allocation_site*, void*, size_t);
|
||||||
|
#define realloc(a, b) realloc_trace(ALLOCATION_SITE, (a), (b))
|
||||||
|
#else
|
||||||
void* realloc(void*, size_t);
|
void* realloc(void*, size_t);
|
||||||
|
#endif
|
||||||
char* realpath(const char* __restrict, char* __restrict);
|
char* realpath(const char* __restrict, char* __restrict);
|
||||||
int setenv(const char*, const char*, int);
|
int setenv(const char*, const char*, int);
|
||||||
#if !defined(__is_sortix_libc) /* not a warning inside libc */
|
#if !defined(__is_sortix_libc) /* not a warning inside libc */
|
||||||
|
@ -189,7 +204,12 @@ int posix_openpt(int);
|
||||||
uint32_t arc4random(void);
|
uint32_t arc4random(void);
|
||||||
void arc4random_buf(void*, size_t);
|
void arc4random_buf(void*, size_t);
|
||||||
uint32_t arc4random_uniform(uint32_t);
|
uint32_t arc4random_uniform(uint32_t);
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
void* reallocarray_trace(struct __allocation_site*, void*, size_t, size_t);
|
||||||
|
#define reallocarray(a, b, c) reallocarray_trace(ALLOCATION_SITE, (a), (b), (c))
|
||||||
|
#else
|
||||||
void* reallocarray(void*, size_t, size_t);
|
void* reallocarray(void*, size_t, size_t);
|
||||||
|
#endif
|
||||||
int ptsname_r(int, char*, size_t);
|
int ptsname_r(int, char*, size_t);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2012, 2013, 2014, 2017 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2011, 2012, 2013, 2014, 2017, 2022 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -91,8 +91,13 @@ void* memccpy(void* __restrict, const void* __restrict, int, size_t);
|
||||||
|
|
||||||
/* Functions from XOPEN 420 gone into POSIX 2008. */
|
/* Functions from XOPEN 420 gone into POSIX 2008. */
|
||||||
#if __USE_SORTIX || 420 <= __USE_XOPEN || 200809L <= __USE_POSIX
|
#if __USE_SORTIX || 420 <= __USE_XOPEN || 200809L <= __USE_POSIX
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
char* strdup_trace(struct __allocation_site*, const char*);
|
||||||
|
#define strdup(a) strdup_trace(ALLOCATION_SITE, (a))
|
||||||
|
#else
|
||||||
char* strdup(const char*);
|
char* strdup(const char*);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Functions from POSIX 2001. */
|
/* Functions from POSIX 2001. */
|
||||||
#if __USE_SORTIX || 200112L <= __USE_POSIX
|
#if __USE_SORTIX || 200112L <= __USE_POSIX
|
||||||
|
@ -111,7 +116,12 @@ char* strtok_r(char* __restrict, const char* __restrict, char** __restrict);
|
||||||
char* stpcpy(char* __restrict, const char* __restrict);
|
char* stpcpy(char* __restrict, const char* __restrict);
|
||||||
char* stpncpy(char* __restrict, const char* __restrict, size_t);
|
char* stpncpy(char* __restrict, const char* __restrict, size_t);
|
||||||
int strcoll_l(const char*, const char*, locale_t);
|
int strcoll_l(const char*, const char*, locale_t);
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
char* strndup_trace(struct __allocation_site*, const char*, size_t);
|
||||||
|
#define strndup(a, b) strndup_trace(ALLOCATION_SITE, (a), (b))
|
||||||
|
#else
|
||||||
char* strndup(const char*, size_t);
|
char* strndup(const char*, size_t);
|
||||||
|
#endif
|
||||||
size_t strnlen(const char*, size_t);
|
size_t strnlen(const char*, size_t);
|
||||||
#if __USE_SORTIX && __SORTIX_STDLIB_REDIRECTS
|
#if __USE_SORTIX && __SORTIX_STDLIB_REDIRECTS
|
||||||
const char* strsignal(int signum) __asm__ ("sortix_strsignal");
|
const char* strsignal(int signum) __asm__ ("sortix_strsignal");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2012, 2013, 2015 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2011, 2012, 2013, 2015, 2022 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -128,4 +128,24 @@
|
||||||
is updated to not rely on this macro. */
|
is updated to not rely on this macro. */
|
||||||
#undef __SORTIX_HAS_GETSERVBYNAME__
|
#undef __SORTIX_HAS_GETSERVBYNAME__
|
||||||
|
|
||||||
|
#if (defined(__is_sortix_libk) || defined(__is_sortix_kernel)) && \
|
||||||
|
defined(__TRACE_KMALLOC)
|
||||||
|
#undef __TRACE_ALLOCATION_SITES
|
||||||
|
#define __TRACE_ALLOCATION_SITES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
#include <stddef.h>
|
||||||
|
struct __allocation_site
|
||||||
|
{
|
||||||
|
const char* file;
|
||||||
|
size_t line;
|
||||||
|
const char* function;
|
||||||
|
size_t current_size;
|
||||||
|
size_t allocations;
|
||||||
|
};
|
||||||
|
#define __TRACE_ALLOCATION_SITES
|
||||||
|
#define ALLOCATION_SITE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2014, 2022 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -20,13 +20,24 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
int asprintf_trace(struct __allocation_site* allocation_site,
|
||||||
|
char** restrict result_ptr,
|
||||||
|
const char* restrict format,
|
||||||
|
...)
|
||||||
|
#else
|
||||||
int asprintf(char** restrict result_ptr,
|
int asprintf(char** restrict result_ptr,
|
||||||
const char* restrict format,
|
const char* restrict format,
|
||||||
...)
|
...)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
va_list list;
|
va_list list;
|
||||||
va_start(list, format);
|
va_start(list, format);
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
int result = vasprintf_trace(allocation_site, result_ptr, format, list);
|
||||||
|
#else
|
||||||
int result = vasprintf(result_ptr, format, list);
|
int result = vasprintf(result_ptr, format, list);
|
||||||
|
#endif
|
||||||
va_end(list);
|
va_end(list);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2015 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2014, 2015, 2022 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -27,6 +27,9 @@ struct vasprintf
|
||||||
char* buffer;
|
char* buffer;
|
||||||
size_t used;
|
size_t used;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
struct __allocation_site* allocation_site;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static size_t vasprintf_callback(void* ctx, const char* string, size_t length)
|
static size_t vasprintf_callback(void* ctx, const char* string, size_t length)
|
||||||
|
@ -39,7 +42,12 @@ static size_t vasprintf_callback(void* ctx, const char* string, size_t length)
|
||||||
size_t new_size = 2 * state->size;
|
size_t new_size = 2 * state->size;
|
||||||
if ( new_size < needed_size )
|
if ( new_size < needed_size )
|
||||||
new_size = needed_size;
|
new_size = needed_size;
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
char* new_buffer = (char*) realloc_trace(state->allocation_site,
|
||||||
|
state->buffer, new_size);
|
||||||
|
#else
|
||||||
char* new_buffer = (char*) realloc(state->buffer, new_size);
|
char* new_buffer = (char*) realloc(state->buffer, new_size);
|
||||||
|
#endif
|
||||||
if ( !new_buffer )
|
if ( !new_buffer )
|
||||||
{
|
{
|
||||||
free(state->buffer);
|
free(state->buffer);
|
||||||
|
@ -54,14 +62,26 @@ static size_t vasprintf_callback(void* ctx, const char* string, size_t length)
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
int vasprintf_trace(struct __allocation_site* allocation_site,
|
||||||
|
char** restrict result_ptr,
|
||||||
|
const char* restrict format,
|
||||||
|
va_list list)
|
||||||
|
#else
|
||||||
int vasprintf(char** restrict result_ptr,
|
int vasprintf(char** restrict result_ptr,
|
||||||
const char* restrict format,
|
const char* restrict format,
|
||||||
va_list list)
|
va_list list)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
struct vasprintf state;
|
struct vasprintf state;
|
||||||
state.used = 0;
|
state.used = 0;
|
||||||
state.size = 32;
|
state.size = 32;
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
state.allocation_site = allocation_site;
|
||||||
|
if ( !(state.buffer = (char*) malloc_trace(allocation_site, state.size)) )
|
||||||
|
#else
|
||||||
if ( !(state.buffer = (char*) malloc(state.size)) )
|
if ( !(state.buffer = (char*) malloc(state.size)) )
|
||||||
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
int result = vcbprintf(&state, vasprintf_callback, format, list);
|
int result = vcbprintf(&state, vasprintf_callback, format, list);
|
||||||
if ( !state.buffer )
|
if ( !state.buffer )
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2011, 2012, 2014, 2022 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -22,12 +22,21 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
void* calloc_trace(struct __allocation_site* allocation_site,
|
||||||
|
size_t nmemb, size_t size)
|
||||||
|
#else
|
||||||
void* calloc(size_t nmemb, size_t size)
|
void* calloc(size_t nmemb, size_t size)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if ( size && nmemb && SIZE_MAX / size < nmemb )
|
if ( size && nmemb && SIZE_MAX / size < nmemb )
|
||||||
return errno = ENOMEM, (void*) NULL;
|
return errno = ENOMEM, (void*) NULL;
|
||||||
size_t total = nmemb * size;
|
size_t total = nmemb * size;
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
void* result = malloc_trace(allocation_site, total);
|
||||||
|
#else
|
||||||
void* result = malloc(total);
|
void* result = malloc(total);
|
||||||
|
#endif
|
||||||
if ( !result )
|
if ( !result )
|
||||||
return NULL;
|
return NULL;
|
||||||
memset(result, 0, total);
|
memset(result, 0, total);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2012, 2013, 2014, 2015 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2011, 2012, 2013, 2014, 2015, 2022 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -39,6 +39,16 @@ void free(void* addr)
|
||||||
// Retrieve the chunk that contains this allocation.
|
// Retrieve the chunk that contains this allocation.
|
||||||
struct heap_chunk* chunk = heap_data_to_chunk((uint8_t*) addr);
|
struct heap_chunk* chunk = heap_data_to_chunk((uint8_t*) addr);
|
||||||
|
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
if ( MAGIC_IS_ALLOCATION_SITE(chunk->chunk_magic) )
|
||||||
|
{
|
||||||
|
struct __allocation_site* allocation_site =
|
||||||
|
ALLOCATION_SITE_OF_MAGIC(chunk->chunk_magic);
|
||||||
|
allocation_site->current_size -= chunk->chunk_size;
|
||||||
|
allocation_site->allocations--;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Return the chunk to the heap.
|
// Return the chunk to the heap.
|
||||||
heap_insert_chunk(chunk);
|
heap_insert_chunk(chunk);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2012, 2013, 2014, 2015 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2011, 2012, 2013, 2014, 2015, 2022 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -31,7 +31,12 @@
|
||||||
|
|
||||||
#if !defined(HEAP_GUARD_DEBUG)
|
#if !defined(HEAP_GUARD_DEBUG)
|
||||||
|
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
void* malloc_trace(struct __allocation_site* allocation_site,
|
||||||
|
size_t original_size)
|
||||||
|
#else
|
||||||
void* malloc(size_t original_size)
|
void* malloc(size_t original_size)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if ( !heap_size_has_bin(original_size) )
|
if ( !heap_size_has_bin(original_size) )
|
||||||
return errno = ENOMEM, (void*) NULL;
|
return errno = ENOMEM, (void*) NULL;
|
||||||
|
@ -89,6 +94,12 @@ void* malloc(size_t original_size)
|
||||||
if ( heap_can_split_chunk(result_chunk, chunk_size) )
|
if ( heap_can_split_chunk(result_chunk, chunk_size) )
|
||||||
heap_split_chunk(result_chunk, chunk_size);
|
heap_split_chunk(result_chunk, chunk_size);
|
||||||
|
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
allocation_site->current_size += result_chunk->chunk_size;
|
||||||
|
allocation_site->allocations++;
|
||||||
|
result_chunk->chunk_magic = MAGIC_OF_ALLOCATION_SITE(allocation_site);
|
||||||
|
#endif
|
||||||
|
|
||||||
__heap_verify();
|
__heap_verify();
|
||||||
__heap_unlock();
|
__heap_unlock();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2012, 2013, 2014, 2015 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2011, 2012, 2013, 2014, 2015, 2022 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -31,10 +31,20 @@
|
||||||
|
|
||||||
#if !defined(HEAP_GUARD_DEBUG)
|
#if !defined(HEAP_GUARD_DEBUG)
|
||||||
|
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
void* realloc_trace(struct __allocation_site* new_allocation_site,
|
||||||
|
void* ptr,
|
||||||
|
size_t requested_size)
|
||||||
|
#else
|
||||||
void* realloc(void* ptr, size_t requested_size)
|
void* realloc(void* ptr, size_t requested_size)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if ( !ptr )
|
if ( !ptr )
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
return malloc_trace(new_allocation_site, requested_size);
|
||||||
|
#else
|
||||||
return malloc(requested_size);
|
return malloc(requested_size);
|
||||||
|
#endif
|
||||||
|
|
||||||
if ( !heap_size_has_bin(requested_size) )
|
if ( !heap_size_has_bin(requested_size) )
|
||||||
return errno = ENOMEM, (void*) NULL;
|
return errno = ENOMEM, (void*) NULL;
|
||||||
|
@ -55,7 +65,14 @@ void* realloc(void* ptr, size_t requested_size)
|
||||||
// Retrieve the chunk that contains this allocation.
|
// Retrieve the chunk that contains this allocation.
|
||||||
struct heap_chunk* chunk = heap_data_to_chunk((uint8_t*) ptr);
|
struct heap_chunk* chunk = heap_data_to_chunk((uint8_t*) ptr);
|
||||||
|
|
||||||
assert(chunk->chunk_magic == HEAP_CHUNK_MAGIC);
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
assert(MAGIC_IS_ALLOCATION_SITE(chunk->chunk_magic));
|
||||||
|
struct __allocation_site* allocation_site =
|
||||||
|
ALLOCATION_SITE_OF_MAGIC(chunk->chunk_magic);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
assert(chunk->chunk_magic == HEAP_CHUNK_MAGIC ||
|
||||||
|
MAGIC_IS_ALLOCATION_SITE(chunk->chunk_magic));
|
||||||
assert(heap_chunk_to_post(chunk)->chunk_magic == HEAP_CHUNK_MAGIC);
|
assert(heap_chunk_to_post(chunk)->chunk_magic == HEAP_CHUNK_MAGIC);
|
||||||
assert(heap_chunk_to_post(chunk)->chunk_size == chunk->chunk_size);
|
assert(heap_chunk_to_post(chunk)->chunk_size == chunk->chunk_size);
|
||||||
|
|
||||||
|
@ -72,8 +89,17 @@ void* realloc(void* ptr, size_t requested_size)
|
||||||
if ( requested_chunk_size < chunk->chunk_size )
|
if ( requested_chunk_size < chunk->chunk_size )
|
||||||
{
|
{
|
||||||
assert(requested_chunk_size <= chunk->chunk_size);
|
assert(requested_chunk_size <= chunk->chunk_size);
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
allocation_site->current_size -= chunk->chunk_size;
|
||||||
|
allocation_site->allocations--;
|
||||||
|
#endif
|
||||||
if ( heap_can_split_chunk(chunk, requested_chunk_size) )
|
if ( heap_can_split_chunk(chunk, requested_chunk_size) )
|
||||||
heap_split_chunk(chunk, requested_chunk_size);
|
heap_split_chunk(chunk, requested_chunk_size);
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
allocation_site->current_size += chunk->chunk_size;
|
||||||
|
allocation_site->allocations++;
|
||||||
|
chunk->chunk_magic = MAGIC_OF_ALLOCATION_SITE(allocation_site);
|
||||||
|
#endif
|
||||||
__heap_verify();
|
__heap_verify();
|
||||||
__heap_unlock();
|
__heap_unlock();
|
||||||
return heap_chunk_to_data(chunk);
|
return heap_chunk_to_data(chunk);
|
||||||
|
@ -88,11 +114,20 @@ void* realloc(void* ptr, size_t requested_size)
|
||||||
!heap_chunk_is_used(right) &&
|
!heap_chunk_is_used(right) &&
|
||||||
requested_chunk_size <= chunk->chunk_size + right->chunk_size )
|
requested_chunk_size <= chunk->chunk_size + right->chunk_size )
|
||||||
{
|
{
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
allocation_site->current_size -= chunk->chunk_size;
|
||||||
|
allocation_site->allocations--;
|
||||||
|
#endif
|
||||||
heap_remove_chunk(right);
|
heap_remove_chunk(right);
|
||||||
heap_chunk_format((uint8_t*) chunk, chunk->chunk_size + right->chunk_size);
|
heap_chunk_format((uint8_t*) chunk, chunk->chunk_size + right->chunk_size);
|
||||||
assert(requested_chunk_size <= chunk->chunk_size);
|
assert(requested_chunk_size <= chunk->chunk_size);
|
||||||
if ( heap_can_split_chunk(chunk, requested_chunk_size) )
|
if ( heap_can_split_chunk(chunk, requested_chunk_size) )
|
||||||
heap_split_chunk(chunk, requested_chunk_size);
|
heap_split_chunk(chunk, requested_chunk_size);
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
allocation_site->current_size += chunk->chunk_size;
|
||||||
|
allocation_site->allocations++;
|
||||||
|
chunk->chunk_magic = MAGIC_OF_ALLOCATION_SITE(allocation_site);
|
||||||
|
#endif
|
||||||
__heap_verify();
|
__heap_verify();
|
||||||
__heap_unlock();
|
__heap_unlock();
|
||||||
return heap_chunk_to_data(chunk);
|
return heap_chunk_to_data(chunk);
|
||||||
|
@ -108,7 +143,11 @@ void* realloc(void* ptr, size_t requested_size)
|
||||||
|
|
||||||
assert(orignal_ptr_size < requested_size);
|
assert(orignal_ptr_size < requested_size);
|
||||||
|
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
void* result = malloc_trace(allocation_site, requested_size);
|
||||||
|
#else
|
||||||
void* result = malloc(requested_size);
|
void* result = malloc(requested_size);
|
||||||
|
#endif
|
||||||
if ( !result )
|
if ( !result )
|
||||||
return (void*) NULL;
|
return (void*) NULL;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2014, 2022 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -21,9 +21,18 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
void* reallocarray_trace(struct __allocation_site* allocation_site,
|
||||||
|
void* ptr, size_t nmemb, size_t size)
|
||||||
|
#else
|
||||||
void* reallocarray(void* ptr, size_t nmemb, size_t size)
|
void* reallocarray(void* ptr, size_t nmemb, size_t size)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if ( size && nmemb && SIZE_MAX / size < nmemb )
|
if ( size && nmemb && SIZE_MAX / size < nmemb )
|
||||||
return errno = ENOMEM, (void*) NULL;
|
return errno = ENOMEM, (void*) NULL;
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
return realloc_trace(allocation_site, ptr, nmemb * size);
|
||||||
|
#else
|
||||||
return realloc(ptr, nmemb * size);
|
return realloc(ptr, nmemb * size);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2011, 2012, 2014, 2022 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -20,10 +20,18 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
char* strdup_trace(struct __allocation_site* allocation_site, const char* input)
|
||||||
|
#else
|
||||||
char* strdup(const char* input)
|
char* strdup(const char* input)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
size_t input_length = strlen(input);
|
size_t input_length = strlen(input);
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
char* result = (char*) malloc_trace(allocation_site, input_length + 1);
|
||||||
|
#else
|
||||||
char* result = (char*) malloc(input_length + 1);
|
char* result = (char*) malloc(input_length + 1);
|
||||||
|
#endif
|
||||||
if ( !result )
|
if ( !result )
|
||||||
return NULL;
|
return NULL;
|
||||||
memcpy(result, input, input_length + 1);
|
memcpy(result, input, input_length + 1);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2011, 2012, 2014, 2022 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -20,10 +20,19 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
char* strndup_trace(struct __allocation_site* allocation_site,
|
||||||
|
const char* input, size_t n)
|
||||||
|
#else
|
||||||
char* strndup(const char* input, size_t n)
|
char* strndup(const char* input, size_t n)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
size_t input_size = strnlen(input, n);
|
size_t input_size = strnlen(input, n);
|
||||||
|
#ifdef __TRACE_ALLOCATION_SITES
|
||||||
|
char* result = (char*) malloc_trace(allocation_site, input_size + 1);
|
||||||
|
#else
|
||||||
char* result = (char*) malloc(input_size + 1);
|
char* result = (char*) malloc(input_size + 1);
|
||||||
|
#endif
|
||||||
if ( !result )
|
if ( !result )
|
||||||
return NULL;
|
return NULL;
|
||||||
memcpy(result, input, input_size);
|
memcpy(result, input, input_size);
|
||||||
|
|
Loading…
Reference in a new issue