Add conditionally compiled mechanism to "show buffers" to give a list of the currently allocated buffers, with a trace for each one of the calls that led to its creation.
This commit is contained in:
parent
72072778de
commit
1fc6b00211
@ -35,7 +35,9 @@
|
||||
* 15/07/2014 Mark Riddoch Addition of properties
|
||||
* 28/08/2014 Mark Riddoch Adition of tail pointer to speed
|
||||
* the gwbuf_append process
|
||||
*
|
||||
* 09/11/2015 Martin Brampton Add buffer tracing (conditional compilation),
|
||||
* accessed by "show buffers" maxadmin command
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
@ -47,6 +49,13 @@
|
||||
#include <log_manager.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(BUFFER_TRACE)
|
||||
#include <hashtable.h>
|
||||
#include <execinfo.h>
|
||||
|
||||
static HASHTABLE *buffer_hashtable = NULL;
|
||||
#endif
|
||||
|
||||
/** Defined in log_manager.cc */
|
||||
extern int lm_enabled_logfiles_bitmask;
|
||||
extern size_t log_ses_count[];
|
||||
@ -56,6 +65,12 @@ static buffer_object_t* gwbuf_remove_buffer_object(
|
||||
GWBUF* buf,
|
||||
buffer_object_t* bufobj);
|
||||
|
||||
#if defined(BUFFER_TRACE)
|
||||
static void gwbuf_add_to_hashtable(GWBUF *buf);
|
||||
static int bhashfn (void *key);
|
||||
static int bcmpfn (void *key1, void *key2);
|
||||
static void gwbuf_remove_from_hashtable(GWBUF *buf);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Allocate a new gateway buffer structure of size bytes.
|
||||
@ -119,9 +134,111 @@ retblock:
|
||||
"Error : Memory allocation failed due to %s.",
|
||||
strerror_r(errno, errbuf, sizeof(errbuf)))));
|
||||
}
|
||||
#if defined(BUFFER_TRACE)
|
||||
else
|
||||
{
|
||||
gwbuf_add_to_hashtable(rval);
|
||||
}
|
||||
#endif
|
||||
return rval;
|
||||
}
|
||||
|
||||
#if defined(BUFFER_TRACE)
|
||||
/**
|
||||
* Store a trace of buffer creation
|
||||
*
|
||||
* @param buf The buffer to record
|
||||
*/
|
||||
static void
|
||||
gwbuf_add_to_hashtable(GWBUF *buf)
|
||||
{
|
||||
void *array[16];
|
||||
size_t size, i, total;
|
||||
char **strings;
|
||||
char *tracetext;
|
||||
|
||||
size = backtrace (array, 16);
|
||||
strings = backtrace_symbols (array, size);
|
||||
total = (2 * size) + 1;
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
total += strlen(strings[i]);
|
||||
}
|
||||
tracetext = (char *)malloc(total);
|
||||
if (tracetext)
|
||||
{
|
||||
char *ptr = tracetext;
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
sprintf(ptr, "\t%s\n", strings[i]);
|
||||
ptr += (strlen(strings[i]) + 2);
|
||||
}
|
||||
free (strings);
|
||||
|
||||
if (NULL == buffer_hashtable)
|
||||
{
|
||||
buffer_hashtable = hashtable_alloc(10000, bhashfn, bcmpfn);
|
||||
hashtable_memory_fns(buffer_hashtable,NULL,NULL,NULL,(HASHMEMORYFN)free);
|
||||
}
|
||||
hashtable_add(buffer_hashtable, buf, (void *)tracetext);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash a buffer (address) to an integer
|
||||
*
|
||||
* @param key The pointer to the buffer
|
||||
*/
|
||||
static int
|
||||
bhashfn(void *key)
|
||||
{
|
||||
return (int)((uintptr_t) key % INT_MAX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two buffer keys (pointers)
|
||||
*
|
||||
* @param key1 The pointer to the first buffer
|
||||
* @param key2 The pointer to the second buffer
|
||||
*/
|
||||
static int
|
||||
bcmpfn(void *key1, void *key2)
|
||||
{
|
||||
return key1 == key2 ? 0 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a buffer from the store of buffer traces
|
||||
*
|
||||
* @param buf The buffer to be removed
|
||||
*/
|
||||
static void
|
||||
gwbuf_remove_from_hashtable(GWBUF *buf)
|
||||
{
|
||||
hashtable_delete(buffer_hashtable, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print all buffer traces via a given print DCB
|
||||
*
|
||||
* @param pdcb Print DCB for output
|
||||
*/
|
||||
void
|
||||
dprintAllBuffers(void *pdcb)
|
||||
{
|
||||
void *buf;
|
||||
char *backtrace;
|
||||
HASHITERATOR *buffers = hashtable_iterator(buffer_hashtable);
|
||||
while (NULL != (buf = hashtable_next(buffers)))
|
||||
{
|
||||
dcb_printf((DCB *)pdcb, "Buffer: %p\n", (void *)buf);
|
||||
backtrace = hashtable_fetch(buffer_hashtable, buf);
|
||||
dcb_printf((DCB *)pdcb, "%s", backtrace);
|
||||
}
|
||||
hashtable_iterator_free(buffers);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Free a gateway buffer
|
||||
*
|
||||
@ -162,6 +279,9 @@ BUF_PROPERTY *prop;
|
||||
buf->hint = buf->hint->next;
|
||||
hint_free(h);
|
||||
}
|
||||
#if defined(BUFFER_TRACE)
|
||||
gwbuf_remove_from_hashtable(buf);
|
||||
#endif
|
||||
free(buf);
|
||||
}
|
||||
|
||||
@ -201,6 +321,9 @@ GWBUF *rval;
|
||||
rval->tail = rval;
|
||||
rval->next = NULL;
|
||||
CHK_GWBUF(rval);
|
||||
#if defined(BUFFER_TRACE)
|
||||
gwbuf_add_to_hashtable(rval);
|
||||
#endif
|
||||
return rval;
|
||||
}
|
||||
|
||||
@ -268,6 +391,9 @@ GWBUF *gwbuf_clone_portion(
|
||||
clonebuf->next = NULL;
|
||||
clonebuf->tail = clonebuf;
|
||||
CHK_GWBUF(clonebuf);
|
||||
#if defined(BUFFER_TRACE)
|
||||
gwbuf_add_to_hashtable(clonebuf);
|
||||
#endif
|
||||
return clonebuf;
|
||||
|
||||
}
|
||||
|
@ -43,6 +43,7 @@
|
||||
* 03/10/2014 Martin Brampton Pointer arithmetic standard conformity
|
||||
* Add more buffer handling macros
|
||||
* Add gwbuf_rtrim (handle chains)
|
||||
* 09/11/2014 Martin Brampton Add dprintAllBuffers (conditional compilation)
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
@ -52,7 +53,6 @@
|
||||
#include <spinlock.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
EXTERN_C_BLOCK_BEGIN
|
||||
|
||||
/**
|
||||
@ -202,6 +202,9 @@ void gwbuf_add_buffer_object(GWBUF* buf,
|
||||
void* data,
|
||||
void (*donefun_fp)(void *));
|
||||
void* gwbuf_get_buffer_object_data(GWBUF* buf, bufobj_id_t id);
|
||||
#if defined(BUFFER_TRACE)
|
||||
extern void dprintAllBuffers(void *pdcb);
|
||||
#endif
|
||||
EXTERN_C_BLOCK_END
|
||||
|
||||
|
||||
|
@ -43,7 +43,8 @@
|
||||
* 29/05/14 Mark Riddoch Add Filter support
|
||||
* 16/10/14 Mark Riddoch Add show eventq
|
||||
* 05/03/15 Massimiliano Pinto Added enable/disable feedback
|
||||
* 27/05/15 Martin Brampton Add show persistent [server]
|
||||
* 27/05/15 Martin Brampton Add show persistent [server]
|
||||
* 06/11/15 Martin Brampton Add show buffers (conditional compilation)
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
@ -60,6 +61,7 @@
|
||||
#include <atomic.h>
|
||||
#include <server.h>
|
||||
#include <spinlock.h>
|
||||
#include <buffer.h>
|
||||
#include <dcb.h>
|
||||
#include <poll.h>
|
||||
#include <users.h>
|
||||
@ -107,6 +109,12 @@ static void telnetdShowUsers(DCB *);
|
||||
* The subcommands of the show command
|
||||
*/
|
||||
struct subcommand showoptions[] = {
|
||||
#if defined(BUFFER_TRACE)
|
||||
{ "buffers", 0, dprintAllBuffers,
|
||||
"Show all buffers with backtrace",
|
||||
"Show all buffers with backtrace",
|
||||
{0, 0, 0} },
|
||||
#endif
|
||||
{ "dcbs", 0, dprintAllDCBs,
|
||||
"Show all descriptor control blocks (network connections)",
|
||||
"Show all descriptor control blocks (network connections)",
|
||||
|
Loading…
x
Reference in New Issue
Block a user