mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-04 00:25:29 +00:00
Refactor tracklines code (#45126)
This commit is contained in:
2
CHANGES
2
CHANGES
@@ -1,3 +1,5 @@
|
|||||||
|
4687. [func] Refactor tracklines code. [RT #45126]
|
||||||
|
|
||||||
4686. [bug] dnssec-settime -p could print a bogus warning about
|
4686. [bug] dnssec-settime -p could print a bogus warning about
|
||||||
key deletion scheduled before its inactivation when a
|
key deletion scheduled before its inactivation when a
|
||||||
key had an inactivation date set but no deletion date
|
key had an inactivation date set but no deletion date
|
||||||
|
@@ -745,6 +745,15 @@ isc__mem_register(void);
|
|||||||
* usually do not have to care about this function: it would call
|
* usually do not have to care about this function: it would call
|
||||||
* isc_lib_register(), which internally calls this function.
|
* isc_lib_register(), which internally calls this function.
|
||||||
*/
|
*/
|
||||||
|
void
|
||||||
|
isc__mem_printactive(isc_mem_t *mctx, FILE *file);
|
||||||
|
void
|
||||||
|
isc__mem_printallactive(FILE *file);
|
||||||
|
/*%<
|
||||||
|
* For internal use by the isc module and its unit tests, these functions
|
||||||
|
* print lists of active memory blocks for a single memory context or for
|
||||||
|
* all contexts.
|
||||||
|
*/
|
||||||
|
|
||||||
ISC_LANG_ENDDECLS
|
ISC_LANG_ENDDECLS
|
||||||
|
|
||||||
|
224
lib/isc/mem.c
224
lib/isc/mem.c
@@ -19,6 +19,7 @@
|
|||||||
#include <isc/bind9.h>
|
#include <isc/bind9.h>
|
||||||
#include <isc/json.h>
|
#include <isc/json.h>
|
||||||
#include <isc/magic.h>
|
#include <isc/magic.h>
|
||||||
|
#include <isc/hash.h>
|
||||||
#include <isc/mem.h>
|
#include <isc/mem.h>
|
||||||
#include <isc/msgs.h>
|
#include <isc/msgs.h>
|
||||||
#include <isc/once.h>
|
#include <isc/once.h>
|
||||||
@@ -47,7 +48,7 @@ LIBISC_EXTERNAL_DATA unsigned int isc_mem_defaultflags = ISC_MEMFLAG_DEFAULT;
|
|||||||
#define ALIGNMENT_SIZE 8U /*%< must be a power of 2 */
|
#define ALIGNMENT_SIZE 8U /*%< must be a power of 2 */
|
||||||
#define NUM_BASIC_BLOCKS 64 /*%< must be > 1 */
|
#define NUM_BASIC_BLOCKS 64 /*%< must be > 1 */
|
||||||
#define TABLE_INCREMENT 1024
|
#define TABLE_INCREMENT 1024
|
||||||
#define DEBUGLIST_COUNT 1024
|
#define DEBUG_TABLE_COUNT 65536
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Types.
|
* Types.
|
||||||
@@ -59,13 +60,14 @@ typedef struct isc__mempool isc__mempool_t;
|
|||||||
typedef struct debuglink debuglink_t;
|
typedef struct debuglink debuglink_t;
|
||||||
struct debuglink {
|
struct debuglink {
|
||||||
ISC_LINK(debuglink_t) link;
|
ISC_LINK(debuglink_t) link;
|
||||||
const void *ptr[DEBUGLIST_COUNT];
|
const void *ptr;
|
||||||
size_t size[DEBUGLIST_COUNT];
|
size_t size;
|
||||||
const char *file[DEBUGLIST_COUNT];
|
const char *file;
|
||||||
unsigned int line[DEBUGLIST_COUNT];
|
unsigned int line;
|
||||||
unsigned int count;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef ISC_LIST(debuglink_t) debuglist_t;
|
||||||
|
|
||||||
#define FLARG_PASS , file, line
|
#define FLARG_PASS , file, line
|
||||||
#define FLARG , const char *file, unsigned int line
|
#define FLARG , const char *file, unsigned int line
|
||||||
#else
|
#else
|
||||||
@@ -99,10 +101,6 @@ struct stats {
|
|||||||
#define MEM_MAGIC ISC_MAGIC('M', 'e', 'm', 'C')
|
#define MEM_MAGIC ISC_MAGIC('M', 'e', 'm', 'C')
|
||||||
#define VALID_CONTEXT(c) ISC_MAGIC_VALID(c, MEM_MAGIC)
|
#define VALID_CONTEXT(c) ISC_MAGIC_VALID(c, MEM_MAGIC)
|
||||||
|
|
||||||
#if ISC_MEM_TRACKLINES
|
|
||||||
typedef ISC_LIST(debuglink_t) debuglist_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* List of all active memory contexts. */
|
/* List of all active memory contexts. */
|
||||||
|
|
||||||
static ISC_LIST(isc__mem_t) contexts;
|
static ISC_LIST(isc__mem_t) contexts;
|
||||||
@@ -158,7 +156,7 @@ struct isc__mem {
|
|||||||
|
|
||||||
#if ISC_MEM_TRACKLINES
|
#if ISC_MEM_TRACKLINES
|
||||||
debuglist_t * debuglist;
|
debuglist_t * debuglist;
|
||||||
unsigned int debuglistcnt;
|
size_t debuglistcnt;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned int memalloc_failures;
|
unsigned int memalloc_failures;
|
||||||
@@ -203,14 +201,14 @@ struct isc__mempool {
|
|||||||
#define TRACE_OR_RECORD (ISC_MEM_DEBUGTRACE|ISC_MEM_DEBUGRECORD)
|
#define TRACE_OR_RECORD (ISC_MEM_DEBUGTRACE|ISC_MEM_DEBUGRECORD)
|
||||||
#define ADD_TRACE(a, b, c, d, e) \
|
#define ADD_TRACE(a, b, c, d, e) \
|
||||||
do { \
|
do { \
|
||||||
if ((isc_mem_debugging & TRACE_OR_RECORD) != 0 && \
|
if (ISC_UNLIKELY((isc_mem_debugging & TRACE_OR_RECORD) != 0 && \
|
||||||
b != NULL) \
|
b != NULL)) \
|
||||||
add_trace_entry(a, b, c, d, e); \
|
add_trace_entry(a, b, c, d, e); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#define DELETE_TRACE(a, b, c, d, e) \
|
#define DELETE_TRACE(a, b, c, d, e) \
|
||||||
do { \
|
do { \
|
||||||
if ((isc_mem_debugging & TRACE_OR_RECORD) != 0 && \
|
if (ISC_UNLIKELY((isc_mem_debugging & TRACE_OR_RECORD) != 0 && \
|
||||||
b != NULL) \
|
b != NULL)) \
|
||||||
delete_trace_entry(a, b, c, d, e); \
|
delete_trace_entry(a, b, c, d, e); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
@@ -382,11 +380,11 @@ static struct isc__mempoolmethods {
|
|||||||
/*!
|
/*!
|
||||||
* mctx must be locked.
|
* mctx must be locked.
|
||||||
*/
|
*/
|
||||||
static inline void
|
static void
|
||||||
add_trace_entry(isc__mem_t *mctx, const void *ptr, size_t size FLARG) {
|
add_trace_entry(isc__mem_t *mctx, const void *ptr, size_t size FLARG) {
|
||||||
debuglink_t *dl;
|
debuglink_t *dl;
|
||||||
unsigned int i;
|
isc_uint32_t hash;
|
||||||
size_t mysize = size;
|
isc_uint32_t idx;
|
||||||
|
|
||||||
if ((isc_mem_debugging & ISC_MEM_DEBUGTRACE) != 0)
|
if ((isc_mem_debugging & ISC_MEM_DEBUGTRACE) != 0)
|
||||||
fprintf(stderr, isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,
|
fprintf(stderr, isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,
|
||||||
@@ -398,25 +396,18 @@ add_trace_entry(isc__mem_t *mctx, const void *ptr, size_t size FLARG) {
|
|||||||
if (mctx->debuglist == NULL)
|
if (mctx->debuglist == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (mysize > mctx->max_size)
|
hash = isc_hash_function(&ptr, sizeof(ptr), ISC_TRUE, NULL);
|
||||||
mysize = mctx->max_size;
|
idx = hash % DEBUG_TABLE_COUNT;
|
||||||
|
|
||||||
dl = ISC_LIST_HEAD(mctx->debuglist[mysize]);
|
dl = ISC_LIST_TAIL(mctx->debuglist[idx]);
|
||||||
while (dl != NULL) {
|
if (ISC_LIKELY(dl != NULL && dl->ptr == NULL)) {
|
||||||
if (dl->count == DEBUGLIST_COUNT)
|
ISC_LIST_UNLINK(mctx->debuglist[idx], dl, link);
|
||||||
goto next;
|
dl->ptr = ptr;
|
||||||
for (i = 0; i < DEBUGLIST_COUNT; i++) {
|
dl->size = size;
|
||||||
if (dl->ptr[i] == NULL) {
|
dl->file = file;
|
||||||
dl->ptr[i] = ptr;
|
dl->line = line;
|
||||||
dl->size[i] = size;
|
ISC_LIST_PREPEND(mctx->debuglist[idx], dl, link);
|
||||||
dl->file[i] = file;
|
return;
|
||||||
dl->line[i] = line;
|
|
||||||
dl->count++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
next:
|
|
||||||
dl = ISC_LIST_NEXT(dl, link);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dl = malloc(sizeof(debuglink_t));
|
dl = malloc(sizeof(debuglink_t));
|
||||||
@@ -426,29 +417,22 @@ add_trace_entry(isc__mem_t *mctx, const void *ptr, size_t size FLARG) {
|
|||||||
mctx->maxmalloced = mctx->malloced;
|
mctx->maxmalloced = mctx->malloced;
|
||||||
|
|
||||||
ISC_LINK_INIT(dl, link);
|
ISC_LINK_INIT(dl, link);
|
||||||
for (i = 1; i < DEBUGLIST_COUNT; i++) {
|
dl->ptr = ptr;
|
||||||
dl->ptr[i] = NULL;
|
dl->size = size;
|
||||||
dl->size[i] = 0;
|
dl->file = file;
|
||||||
dl->file[i] = NULL;
|
dl->line = line;
|
||||||
dl->line[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
dl->ptr[0] = ptr;
|
ISC_LIST_PREPEND(mctx->debuglist[idx], dl, link);
|
||||||
dl->size[0] = size;
|
|
||||||
dl->file[0] = file;
|
|
||||||
dl->line[0] = line;
|
|
||||||
dl->count = 1;
|
|
||||||
|
|
||||||
ISC_LIST_PREPEND(mctx->debuglist[mysize], dl, link);
|
|
||||||
mctx->debuglistcnt++;
|
mctx->debuglistcnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static void
|
||||||
delete_trace_entry(isc__mem_t *mctx, const void *ptr, size_t size,
|
delete_trace_entry(isc__mem_t *mctx, const void *ptr, size_t size,
|
||||||
const char *file, unsigned int line)
|
const char *file, unsigned int line)
|
||||||
{
|
{
|
||||||
debuglink_t *dl;
|
debuglink_t *dl;
|
||||||
unsigned int i;
|
isc_uint32_t hash;
|
||||||
|
isc_uint32_t idx;
|
||||||
|
|
||||||
if ((isc_mem_debugging & ISC_MEM_DEBUGTRACE) != 0)
|
if ((isc_mem_debugging & ISC_MEM_DEBUGTRACE) != 0)
|
||||||
fprintf(stderr, isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,
|
fprintf(stderr, isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,
|
||||||
@@ -460,28 +444,19 @@ delete_trace_entry(isc__mem_t *mctx, const void *ptr, size_t size,
|
|||||||
if (mctx->debuglist == NULL)
|
if (mctx->debuglist == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (size > mctx->max_size)
|
hash = isc_hash_function(&ptr, sizeof(ptr), ISC_TRUE, NULL);
|
||||||
size = mctx->max_size;
|
idx = hash % DEBUG_TABLE_COUNT;
|
||||||
|
|
||||||
dl = ISC_LIST_HEAD(mctx->debuglist[size]);
|
dl = ISC_LIST_HEAD(mctx->debuglist[idx]);
|
||||||
while (dl != NULL) {
|
while (ISC_LIKELY(dl != NULL && dl->ptr != NULL)) {
|
||||||
for (i = 0; i < DEBUGLIST_COUNT; i++) {
|
if (ISC_UNLIKELY(dl->ptr == ptr)) {
|
||||||
if (dl->ptr[i] == ptr) {
|
ISC_LIST_UNLINK(mctx->debuglist[idx], dl, link);
|
||||||
dl->ptr[i] = NULL;
|
dl->ptr = NULL;
|
||||||
dl->size[i] = 0;
|
dl->size = 0;
|
||||||
dl->file[i] = NULL;
|
dl->file = NULL;
|
||||||
dl->line[i] = 0;
|
dl->line = 0;
|
||||||
|
ISC_LIST_APPEND(mctx->debuglist[idx], dl, link);
|
||||||
INSIST(dl->count > 0);
|
return;
|
||||||
dl->count--;
|
|
||||||
if (dl->count == 0) {
|
|
||||||
ISC_LIST_UNLINK(mctx->debuglist[size],
|
|
||||||
dl, link);
|
|
||||||
free(dl);
|
|
||||||
mctx->malloced -= sizeof(*dl);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
dl = ISC_LIST_NEXT(dl, link);
|
dl = ISC_LIST_NEXT(dl, link);
|
||||||
}
|
}
|
||||||
@@ -490,7 +465,7 @@ delete_trace_entry(isc__mem_t *mctx, const void *ptr, size_t size,
|
|||||||
* If we get here, we didn't find the item on the list. We're
|
* If we get here, we didn't find the item on the list. We're
|
||||||
* screwed.
|
* screwed.
|
||||||
*/
|
*/
|
||||||
INSIST(dl != NULL);
|
INSIST(0);
|
||||||
}
|
}
|
||||||
#endif /* ISC_MEM_TRACKLINES */
|
#endif /* ISC_MEM_TRACKLINES */
|
||||||
|
|
||||||
@@ -1016,19 +991,19 @@ isc_mem_createx2(size_t init_max_size, size_t target_size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if ISC_MEM_TRACKLINES
|
#if ISC_MEM_TRACKLINES
|
||||||
if ((isc_mem_debugging & ISC_MEM_DEBUGRECORD) != 0) {
|
if (ISC_UNLIKELY((isc_mem_debugging & ISC_MEM_DEBUGRECORD) != 0)) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
ctx->debuglist = (memalloc)(arg,
|
ctx->debuglist = (memalloc)(arg, (DEBUG_TABLE_COUNT *
|
||||||
(ctx->max_size+1) * sizeof(debuglist_t));
|
sizeof(debuglist_t)));
|
||||||
if (ctx->debuglist == NULL) {
|
if (ctx->debuglist == NULL) {
|
||||||
result = ISC_R_NOMEMORY;
|
result = ISC_R_NOMEMORY;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
for (i = 0; i <= ctx->max_size; i++)
|
for (i = 0; i < DEBUG_TABLE_COUNT; i++)
|
||||||
ISC_LIST_INIT(ctx->debuglist[i]);
|
ISC_LIST_INIT(ctx->debuglist[i]);
|
||||||
ctx->malloced += (ctx->max_size+1) * sizeof(debuglist_t);
|
ctx->malloced += DEBUG_TABLE_COUNT * sizeof(debuglist_t);
|
||||||
ctx->maxmalloced += (ctx->max_size+1) * sizeof(debuglist_t);
|
ctx->maxmalloced += DEBUG_TABLE_COUNT * sizeof(debuglist_t);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1075,28 +1050,24 @@ destroy(isc__mem_t *ctx) {
|
|||||||
INSIST(ISC_LIST_EMPTY(ctx->pools));
|
INSIST(ISC_LIST_EMPTY(ctx->pools));
|
||||||
|
|
||||||
#if ISC_MEM_TRACKLINES
|
#if ISC_MEM_TRACKLINES
|
||||||
if (ctx->debuglist != NULL) {
|
if (ISC_UNLIKELY(ctx->debuglist != NULL)) {
|
||||||
if (ctx->checkfree) {
|
debuglink_t *dl;
|
||||||
for (i = 0; i <= ctx->max_size; i++) {
|
for (i = 0; i < DEBUG_TABLE_COUNT; i++)
|
||||||
if (!ISC_LIST_EMPTY(ctx->debuglist[i]))
|
for (dl = ISC_LIST_HEAD(ctx->debuglist[i]);
|
||||||
|
dl != NULL;
|
||||||
|
dl = ISC_LIST_HEAD(ctx->debuglist[i])) {
|
||||||
|
if (ctx->checkfree && dl->ptr != NULL)
|
||||||
print_active(ctx, stderr);
|
print_active(ctx, stderr);
|
||||||
INSIST(ISC_LIST_EMPTY(ctx->debuglist[i]));
|
INSIST (!ctx->checkfree || dl->ptr == NULL);
|
||||||
}
|
|
||||||
} else {
|
ISC_LIST_UNLINK(ctx->debuglist[i],
|
||||||
debuglink_t *dl;
|
dl, link);
|
||||||
|
free(dl);
|
||||||
|
ctx->malloced -= sizeof(*dl);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i <= ctx->max_size; i++)
|
|
||||||
for (dl = ISC_LIST_HEAD(ctx->debuglist[i]);
|
|
||||||
dl != NULL;
|
|
||||||
dl = ISC_LIST_HEAD(ctx->debuglist[i])) {
|
|
||||||
ISC_LIST_UNLINK(ctx->debuglist[i],
|
|
||||||
dl, link);
|
|
||||||
free(dl);
|
|
||||||
ctx->malloced -= sizeof(*dl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(ctx->memfree)(ctx->arg, ctx->debuglist);
|
(ctx->memfree)(ctx->arg, ctx->debuglist);
|
||||||
ctx->malloced -= (ctx->max_size+1) * sizeof(debuglist_t);
|
ctx->malloced -= DEBUG_TABLE_COUNT * sizeof(debuglist_t);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
INSIST(ctx->references == 0);
|
INSIST(ctx->references == 0);
|
||||||
@@ -1210,7 +1181,9 @@ isc___mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
|
|||||||
*/
|
*/
|
||||||
*ctxp = NULL;
|
*ctxp = NULL;
|
||||||
|
|
||||||
if ((isc_mem_debugging & (ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0) {
|
if (ISC_UNLIKELY((isc_mem_debugging &
|
||||||
|
(ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0))
|
||||||
|
{
|
||||||
if ((isc_mem_debugging & ISC_MEM_DEBUGSIZE) != 0) {
|
if ((isc_mem_debugging & ISC_MEM_DEBUGSIZE) != 0) {
|
||||||
si = &(((size_info *)ptr)[-1]);
|
si = &(((size_info *)ptr)[-1]);
|
||||||
oldsize = si->u.size - ALIGNMENT_SIZE;
|
oldsize = si->u.size - ALIGNMENT_SIZE;
|
||||||
@@ -1300,7 +1273,8 @@ isc___mem_get(isc_mem_t *ctx0, size_t size FLARG) {
|
|||||||
|
|
||||||
REQUIRE(VALID_CONTEXT(ctx));
|
REQUIRE(VALID_CONTEXT(ctx));
|
||||||
|
|
||||||
if ((isc_mem_debugging & (ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0)
|
if (ISC_UNLIKELY((isc_mem_debugging &
|
||||||
|
(ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0))
|
||||||
return (isc__mem_allocate(ctx0, size FLARG_PASS));
|
return (isc__mem_allocate(ctx0, size FLARG_PASS));
|
||||||
|
|
||||||
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
|
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
|
||||||
@@ -1314,6 +1288,7 @@ isc___mem_get(isc_mem_t *ctx0, size_t size FLARG) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ADD_TRACE(ctx, ptr, size, file, line);
|
ADD_TRACE(ctx, ptr, size, file, line);
|
||||||
|
|
||||||
if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water) {
|
if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water) {
|
||||||
ctx->is_overmem = ISC_TRUE;
|
ctx->is_overmem = ISC_TRUE;
|
||||||
if (!ctx->hi_called)
|
if (!ctx->hi_called)
|
||||||
@@ -1344,7 +1319,9 @@ isc___mem_put(isc_mem_t *ctx0, void *ptr, size_t size FLARG) {
|
|||||||
REQUIRE(VALID_CONTEXT(ctx));
|
REQUIRE(VALID_CONTEXT(ctx));
|
||||||
REQUIRE(ptr != NULL);
|
REQUIRE(ptr != NULL);
|
||||||
|
|
||||||
if ((isc_mem_debugging & (ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0) {
|
if (ISC_UNLIKELY((isc_mem_debugging &
|
||||||
|
(ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0))
|
||||||
|
{
|
||||||
if ((isc_mem_debugging & ISC_MEM_DEBUGSIZE) != 0) {
|
if ((isc_mem_debugging & ISC_MEM_DEBUGSIZE) != 0) {
|
||||||
si = &(((size_info *)ptr)[-1]);
|
si = &(((size_info *)ptr)[-1]);
|
||||||
oldsize = si->u.size - ALIGNMENT_SIZE;
|
oldsize = si->u.size - ALIGNMENT_SIZE;
|
||||||
@@ -1403,7 +1380,7 @@ static void
|
|||||||
print_active(isc__mem_t *mctx, FILE *out) {
|
print_active(isc__mem_t *mctx, FILE *out) {
|
||||||
if (mctx->debuglist != NULL) {
|
if (mctx->debuglist != NULL) {
|
||||||
debuglink_t *dl;
|
debuglink_t *dl;
|
||||||
unsigned int i, j;
|
unsigned int i;
|
||||||
const char *format;
|
const char *format;
|
||||||
isc_boolean_t found;
|
isc_boolean_t found;
|
||||||
|
|
||||||
@@ -1415,23 +1392,21 @@ print_active(isc__mem_t *mctx, FILE *out) {
|
|||||||
format = isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,
|
format = isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,
|
||||||
ISC_MSG_PTRFILELINE,
|
ISC_MSG_PTRFILELINE,
|
||||||
"\tptr %p size %u file %s line %u\n");
|
"\tptr %p size %u file %s line %u\n");
|
||||||
for (i = 0; i <= mctx->max_size; i++) {
|
for (i = 0; i < DEBUG_TABLE_COUNT; i++) {
|
||||||
dl = ISC_LIST_HEAD(mctx->debuglist[i]);
|
dl = ISC_LIST_HEAD(mctx->debuglist[i]);
|
||||||
|
|
||||||
if (dl != NULL)
|
if (dl != NULL)
|
||||||
found = ISC_TRUE;
|
found = ISC_TRUE;
|
||||||
|
|
||||||
while (dl != NULL) {
|
while (dl != NULL) {
|
||||||
for (j = 0; j < DEBUGLIST_COUNT; j++)
|
if (dl->ptr != NULL)
|
||||||
if (dl->ptr[j] != NULL)
|
fprintf(out, format,
|
||||||
fprintf(out, format,
|
dl->ptr, dl->size,
|
||||||
dl->ptr[j],
|
dl->file, dl->line);
|
||||||
dl->size[j],
|
|
||||||
dl->file[j],
|
|
||||||
dl->line[j]);
|
|
||||||
dl = ISC_LIST_NEXT(dl, link);
|
dl = ISC_LIST_NEXT(dl, link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
fputs(isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,
|
fputs(isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,
|
||||||
ISC_MSG_NONE, "\tNone.\n"), out);
|
ISC_MSG_NONE, "\tNone.\n"), out);
|
||||||
@@ -1530,7 +1505,7 @@ mem_allocateunlocked(isc_mem_t *ctx0, size_t size) {
|
|||||||
size_info *si;
|
size_info *si;
|
||||||
|
|
||||||
size += ALIGNMENT_SIZE;
|
size += ALIGNMENT_SIZE;
|
||||||
if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0)
|
if (ISC_UNLIKELY((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0))
|
||||||
size += ALIGNMENT_SIZE;
|
size += ALIGNMENT_SIZE;
|
||||||
|
|
||||||
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0)
|
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0)
|
||||||
@@ -1540,7 +1515,7 @@ mem_allocateunlocked(isc_mem_t *ctx0, size_t size) {
|
|||||||
|
|
||||||
if (si == NULL)
|
if (si == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) {
|
if (ISC_UNLIKELY((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0)) {
|
||||||
si->u.ctx = ctx;
|
si->u.ctx = ctx;
|
||||||
si++;
|
si++;
|
||||||
}
|
}
|
||||||
@@ -1574,8 +1549,9 @@ isc___mem_allocate(isc_mem_t *ctx0, size_t size FLARG) {
|
|||||||
}
|
}
|
||||||
if (ctx->inuse > ctx->maxinuse) {
|
if (ctx->inuse > ctx->maxinuse) {
|
||||||
ctx->maxinuse = ctx->inuse;
|
ctx->maxinuse = ctx->inuse;
|
||||||
if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water &&
|
if (ISC_UNLIKELY(ctx->hi_water != 0U &&
|
||||||
(isc_mem_debugging & ISC_MEM_DEBUGUSAGE) != 0)
|
ctx->inuse > ctx->hi_water &&
|
||||||
|
(isc_mem_debugging & ISC_MEM_DEBUGUSAGE) != 0))
|
||||||
fprintf(stderr, "maxinuse = %lu\n",
|
fprintf(stderr, "maxinuse = %lu\n",
|
||||||
(unsigned long)ctx->inuse);
|
(unsigned long)ctx->inuse);
|
||||||
}
|
}
|
||||||
@@ -1612,7 +1588,9 @@ isc___mem_reallocate(isc_mem_t *ctx0, void *ptr, size_t size FLARG) {
|
|||||||
oldsize = (((size_info *)ptr)[-1]).u.size;
|
oldsize = (((size_info *)ptr)[-1]).u.size;
|
||||||
INSIST(oldsize >= ALIGNMENT_SIZE);
|
INSIST(oldsize >= ALIGNMENT_SIZE);
|
||||||
oldsize -= ALIGNMENT_SIZE;
|
oldsize -= ALIGNMENT_SIZE;
|
||||||
if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) {
|
if (ISC_UNLIKELY((isc_mem_debugging &
|
||||||
|
ISC_MEM_DEBUGCTX) != 0))
|
||||||
|
{
|
||||||
INSIST(oldsize >= ALIGNMENT_SIZE);
|
INSIST(oldsize >= ALIGNMENT_SIZE);
|
||||||
oldsize -= ALIGNMENT_SIZE;
|
oldsize -= ALIGNMENT_SIZE;
|
||||||
}
|
}
|
||||||
@@ -1636,7 +1614,7 @@ isc___mem_free(isc_mem_t *ctx0, void *ptr FLARG) {
|
|||||||
REQUIRE(VALID_CONTEXT(ctx));
|
REQUIRE(VALID_CONTEXT(ctx));
|
||||||
REQUIRE(ptr != NULL);
|
REQUIRE(ptr != NULL);
|
||||||
|
|
||||||
if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) {
|
if (ISC_UNLIKELY((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0)) {
|
||||||
si = &(((size_info *)ptr)[-2]);
|
si = &(((size_info *)ptr)[-2]);
|
||||||
REQUIRE(si->u.ctx == ctx);
|
REQUIRE(si->u.ctx == ctx);
|
||||||
size = si[1].u.size;
|
size = si[1].u.size;
|
||||||
@@ -2084,7 +2062,9 @@ isc___mempool_get(isc_mempool_t *mpctx0 FLARG) {
|
|||||||
UNLOCK(mpctx->lock);
|
UNLOCK(mpctx->lock);
|
||||||
|
|
||||||
#if ISC_MEM_TRACKLINES
|
#if ISC_MEM_TRACKLINES
|
||||||
if (((isc_mem_debugging & TRACE_OR_RECORD) != 0) && item != NULL) {
|
if (ISC_UNLIKELY(((isc_mem_debugging & TRACE_OR_RECORD) != 0) &&
|
||||||
|
item != NULL))
|
||||||
|
{
|
||||||
MCTXLOCK(mctx, &mctx->lock);
|
MCTXLOCK(mctx, &mctx->lock);
|
||||||
ADD_TRACE(mctx, item, mpctx->size, file, line);
|
ADD_TRACE(mctx, item, mpctx->size, file, line);
|
||||||
MCTXUNLOCK(mctx, &mctx->lock);
|
MCTXUNLOCK(mctx, &mctx->lock);
|
||||||
@@ -2113,7 +2093,7 @@ isc___mempool_put(isc_mempool_t *mpctx0, void *mem FLARG) {
|
|||||||
mpctx->allocated--;
|
mpctx->allocated--;
|
||||||
|
|
||||||
#if ISC_MEM_TRACKLINES
|
#if ISC_MEM_TRACKLINES
|
||||||
if ((isc_mem_debugging & TRACE_OR_RECORD) != 0) {
|
if (ISC_UNLIKELY((isc_mem_debugging & TRACE_OR_RECORD) != 0)) {
|
||||||
MCTXLOCK(mctx, &mctx->lock);
|
MCTXLOCK(mctx, &mctx->lock);
|
||||||
DELETE_TRACE(mctx, mem, mpctx->size, file, line);
|
DELETE_TRACE(mctx, mem, mpctx->size, file, line);
|
||||||
MCTXUNLOCK(mctx, &mctx->lock);
|
MCTXUNLOCK(mctx, &mctx->lock);
|
||||||
@@ -2343,7 +2323,7 @@ isc_mem_checkdestroyed(FILE *file) {
|
|||||||
LOCK(&contextslock);
|
LOCK(&contextslock);
|
||||||
if (!ISC_LIST_EMPTY(contexts)) {
|
if (!ISC_LIST_EMPTY(contexts)) {
|
||||||
#if ISC_MEM_TRACKLINES
|
#if ISC_MEM_TRACKLINES
|
||||||
if ((isc_mem_debugging & TRACE_OR_RECORD) != 0) {
|
if (ISC_UNLIKELY((isc_mem_debugging & TRACE_OR_RECORD) != 0)) {
|
||||||
isc__mem_t *ctx;
|
isc__mem_t *ctx;
|
||||||
|
|
||||||
for (ctx = ISC_LIST_HEAD(contexts);
|
for (ctx = ISC_LIST_HEAD(contexts);
|
||||||
@@ -2415,7 +2395,7 @@ xml_renderctx(isc__mem_t *ctx, summarystat_t *summary,
|
|||||||
#if ISC_MEM_TRACKLINES
|
#if ISC_MEM_TRACKLINES
|
||||||
if (ctx->debuglist != NULL) {
|
if (ctx->debuglist != NULL) {
|
||||||
summary->contextsize +=
|
summary->contextsize +=
|
||||||
(ctx->max_size + 1) * sizeof(debuglist_t) +
|
DEBUG_TABLE_COUNT * sizeof(debuglist_t) +
|
||||||
ctx->debuglistcnt * sizeof(debuglink_t);
|
ctx->debuglistcnt * sizeof(debuglink_t);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -2601,7 +2581,7 @@ json_renderctx(isc__mem_t *ctx, summarystat_t *summary, json_object *array) {
|
|||||||
#if ISC_MEM_TRACKLINES
|
#if ISC_MEM_TRACKLINES
|
||||||
if (ctx->debuglist != NULL) {
|
if (ctx->debuglist != NULL) {
|
||||||
summary->contextsize +=
|
summary->contextsize +=
|
||||||
(ctx->max_size + 1) * sizeof(debuglist_t) +
|
DEBUG_TABLE_COUNT * sizeof(debuglist_t) +
|
||||||
ctx->debuglistcnt * sizeof(debuglink_t);
|
ctx->debuglistcnt * sizeof(debuglink_t);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -15,9 +15,11 @@
|
|||||||
|
|
||||||
#include "isctest.h"
|
#include "isctest.h"
|
||||||
|
|
||||||
|
#include <isc/file.h>
|
||||||
#include <isc/mem.h>
|
#include <isc/mem.h>
|
||||||
#include <isc/print.h>
|
#include <isc/print.h>
|
||||||
#include <isc/result.h>
|
#include <isc/result.h>
|
||||||
|
#include <isc/stdio.h>
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
default_memalloc(void *arg, size_t size) {
|
default_memalloc(void *arg, size_t size) {
|
||||||
@@ -141,12 +143,160 @@ ATF_TC_BODY(isc_mem_inuse, tc) {
|
|||||||
isc_test_end();
|
isc_test_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ISC_MEM_TRACKLINES
|
||||||
|
ATF_TC(isc_mem_noflags);
|
||||||
|
ATF_TC_HEAD(isc_mem_noflags, tc) {
|
||||||
|
atf_tc_set_md_var(tc, "descr", "test mem with no flags");
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TC_BODY(isc_mem_noflags, tc) {
|
||||||
|
isc_result_t result;
|
||||||
|
isc_mem_t *mctx2 = NULL;
|
||||||
|
char buf[4096], *p, *q;
|
||||||
|
FILE *f;
|
||||||
|
void *ptr;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
result = isc_stdio_open("mem.output", "w", &f);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
result = isc_test_begin(NULL, ISC_TRUE);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
|
||||||
|
NULL, &mctx2, 0);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
isc_mem_debugging = 0;
|
||||||
|
ptr = isc_mem_get(mctx2, 2048);
|
||||||
|
ATF_CHECK(ptr != NULL);
|
||||||
|
isc__mem_printactive(mctx2, f);
|
||||||
|
isc_mem_put(mctx2, ptr, 2048);
|
||||||
|
isc_mem_destroy(&mctx2);
|
||||||
|
isc_stdio_close(f);
|
||||||
|
|
||||||
|
result = isc_stdio_open("mem.output", "r", &f);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
result = isc_stdio_read(buf, sizeof(buf), 1, f, &size);
|
||||||
|
isc_stdio_close(f);
|
||||||
|
isc_file_remove("mem.output");
|
||||||
|
|
||||||
|
p = strchr(buf, '\n');
|
||||||
|
p += 2;
|
||||||
|
q = strchr(p, '\n');
|
||||||
|
*q = '\0';
|
||||||
|
ATF_CHECK_STREQ(p, "None.");
|
||||||
|
|
||||||
|
isc_mem_debugging = ISC_MEM_DEBUGRECORD;
|
||||||
|
isc_test_end();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TC(isc_mem_recordflag);
|
||||||
|
ATF_TC_HEAD(isc_mem_recordflag, tc) {
|
||||||
|
atf_tc_set_md_var(tc, "descr", "test mem with record flag");
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TC_BODY(isc_mem_recordflag, tc) {
|
||||||
|
isc_result_t result;
|
||||||
|
isc_mem_t *mctx2 = NULL;
|
||||||
|
char buf[4096], *p;
|
||||||
|
FILE *f;
|
||||||
|
void *ptr;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
result = isc_stdio_open("mem.output", "w", &f);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
result = isc_test_begin(NULL, ISC_FALSE);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
|
||||||
|
NULL, &mctx2, 0);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
ptr = isc_mem_get(mctx2, 2048);
|
||||||
|
ATF_CHECK(ptr != NULL);
|
||||||
|
isc__mem_printactive(mctx2, f);
|
||||||
|
isc_mem_put(mctx2, ptr, 2048);
|
||||||
|
isc_mem_destroy(&mctx2);
|
||||||
|
isc_stdio_close(f);
|
||||||
|
|
||||||
|
result = isc_stdio_open("mem.output", "r", &f);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
result = isc_stdio_read(buf, sizeof(buf), 1, f, &size);
|
||||||
|
isc_stdio_close(f);
|
||||||
|
isc_file_remove("mem.output");
|
||||||
|
|
||||||
|
p = strchr(buf, '\n');
|
||||||
|
ATF_CHECK(strncmp(p + 2, "ptr ", 4) == 0);
|
||||||
|
p = strchr(p + 1, '\n');
|
||||||
|
ATF_CHECK(strlen(p) == 1);
|
||||||
|
|
||||||
|
isc_test_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TC(isc_mem_traceflag);
|
||||||
|
ATF_TC_HEAD(isc_mem_traceflag, tc) {
|
||||||
|
atf_tc_set_md_var(tc, "descr", "test mem with trace flag");
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TC_BODY(isc_mem_traceflag, tc) {
|
||||||
|
isc_result_t result;
|
||||||
|
isc_mem_t *mctx2 = NULL;
|
||||||
|
char buf[4096], *p;
|
||||||
|
FILE *f;
|
||||||
|
void *ptr;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
/* redirect stderr so we can check trace output */
|
||||||
|
f = freopen("mem.output", "w", stderr);
|
||||||
|
ATF_REQUIRE(f != NULL);
|
||||||
|
|
||||||
|
result = isc_test_begin(NULL, ISC_TRUE);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
|
||||||
|
NULL, &mctx2, 0);
|
||||||
|
isc_mem_debugging = ISC_MEM_DEBUGTRACE;
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
ptr = isc_mem_get(mctx2, 2048);
|
||||||
|
ATF_CHECK(ptr != NULL);
|
||||||
|
isc__mem_printactive(mctx2, f);
|
||||||
|
isc_mem_put(mctx2, ptr, 2048);
|
||||||
|
isc_mem_destroy(&mctx2);
|
||||||
|
isc_stdio_close(f);
|
||||||
|
|
||||||
|
result = isc_stdio_open("mem.output", "r", &f);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
result = isc_stdio_read(buf, sizeof(buf), 1, f, &size);
|
||||||
|
isc_stdio_close(f);
|
||||||
|
isc_file_remove("mem.output");
|
||||||
|
|
||||||
|
/* return stderr to TTY so we can see errors */
|
||||||
|
f = freopen("/dev/tty", "w", stderr);
|
||||||
|
|
||||||
|
ATF_CHECK(strncmp(buf, "add ", 4) == 0);
|
||||||
|
p = strchr(buf, '\n');
|
||||||
|
p = strchr(p + 1, '\n');
|
||||||
|
ATF_CHECK(strncmp(p + 2, "ptr ", 4) == 0);
|
||||||
|
p = strchr(p + 1, '\n');
|
||||||
|
ATF_CHECK(strncmp(p + 1, "del ", 4) == 0);
|
||||||
|
|
||||||
|
isc_mem_debugging = ISC_MEM_DEBUGRECORD;
|
||||||
|
isc_test_end();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Main
|
* Main
|
||||||
*/
|
*/
|
||||||
ATF_TP_ADD_TCS(tp) {
|
ATF_TP_ADD_TCS(tp) {
|
||||||
ATF_TP_ADD_TC(tp, isc_mem_total);
|
ATF_TP_ADD_TC(tp, isc_mem_total);
|
||||||
ATF_TP_ADD_TC(tp, isc_mem_inuse);
|
ATF_TP_ADD_TC(tp, isc_mem_inuse);
|
||||||
|
#if ISC_MEM_TRACKLINES
|
||||||
|
ATF_TP_ADD_TC(tp, isc_mem_noflags);
|
||||||
|
ATF_TP_ADD_TC(tp, isc_mem_recordflag);
|
||||||
|
ATF_TP_ADD_TC(tp, isc_mem_traceflag);
|
||||||
|
#endif
|
||||||
|
|
||||||
return (atf_no_error());
|
return (atf_no_error());
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user