summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@diac24.net>2019-12-02 16:20:00 +0100
committerDavid Lamparter <equinox@diac24.net>2020-04-01 06:53:26 +0200
commit767439c55858d65bf6f5776b7fcd36cc1132565c (patch)
treed6eb0daa9975f6ff20eca5b69955af23a7db97ad
parent0bdeb5e58d8fdf8b0f30461a388768112b0e080c (diff)
lib: mark some allocations as "active at exit"
In some cases we really don't want to clean up things even when exiting (i.e. to keep the logging subsystem going.) This adds a flag on MGROUPs to indicate that. [v2: add "(active at exit)" marker text to debug memstats-at-exit] Signed-off-by: David Lamparter <equinox@diac24.net>
-rw-r--r--lib/memory.c3
-rw-r--r--lib/memory.h14
-rw-r--r--lib/zlog_targets.c16
3 files changed, 26 insertions, 7 deletions
diff --git a/lib/memory.c b/lib/memory.c
index 149e294d50..3a29404827 100644
--- a/lib/memory.c
+++ b/lib/memory.c
@@ -163,7 +163,8 @@ static int qmem_exit_walker(void *arg, struct memgroup *mg, struct memtype *mt)
} else if (mt->n_alloc) {
char size[32];
- eda->error++;
+ if (!mg->active_at_exit)
+ eda->error++;
snprintf(size, sizeof(size), "%10zu", mt->size);
fprintf(eda->fp, "%s: memstats: %-30s: %6zu * %s\n",
eda->prefix, mt->name, mt->n_alloc,
diff --git a/lib/memory.h b/lib/memory.h
index e4e05faa4f..13f2f9b11a 100644
--- a/lib/memory.h
+++ b/lib/memory.h
@@ -17,6 +17,7 @@
#ifndef _QUAGGA_MEMORY_H
#define _QUAGGA_MEMORY_H
+#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <frratomic.h>
@@ -48,6 +49,8 @@ struct memgroup {
struct memgroup *next, **ref;
struct memtype *types, **insert;
const char *name;
+ /* ignore group on dumping memleaks at exit */
+ bool active_at_exit;
};
/* macro usage:
@@ -76,7 +79,7 @@ struct memgroup {
*/
#define DECLARE_MGROUP(name) extern struct memgroup _mg_##name;
-#define DEFINE_MGROUP(mname, desc) \
+#define _DEFINE_MGROUP(mname, desc, ...) \
struct memgroup _mg_##mname \
__attribute__((section(".data.mgroups"))) = { \
.name = desc, \
@@ -84,6 +87,7 @@ struct memgroup {
.next = NULL, \
.insert = NULL, \
.ref = NULL, \
+ __VA_ARGS__ \
}; \
static void _mginit_##mname(void) __attribute__((_CONSTRUCTOR(1000))); \
static void _mginit_##mname(void) \
@@ -99,7 +103,13 @@ struct memgroup {
if (_mg_##mname.next) \
_mg_##mname.next->ref = _mg_##mname.ref; \
*_mg_##mname.ref = _mg_##mname.next; \
- }
+ } \
+ /* end */
+
+#define DEFINE_MGROUP(mname, desc) \
+ _DEFINE_MGROUP(mname, desc, )
+#define DEFINE_MGROUP_ACTIVEATEXIT(mname, desc) \
+ _DEFINE_MGROUP(mname, desc, .active_at_exit = true)
#define DECLARE_MTYPE(name) \
extern struct memtype MTYPE_##name[1]; \
diff --git a/lib/zlog_targets.c b/lib/zlog_targets.c
index ff9cd1e5fe..85991b0dde 100644
--- a/lib/zlog_targets.c
+++ b/lib/zlog_targets.c
@@ -26,10 +26,18 @@
#include "zlog.h"
#include "zlog_targets.h"
-DEFINE_MTYPE_STATIC(LIB, LOG_FD, "log file target")
-DEFINE_MTYPE_STATIC(LIB, LOG_FD_NAME, "log file name")
-DEFINE_MTYPE_STATIC(LIB, LOG_FD_ROTATE, "log file rotate helper")
-DEFINE_MTYPE_STATIC(LIB, LOG_SYSL, "syslog target")
+/* these allocations are intentionally left active even when doing full exit
+ * cleanup, in order to keep the logging subsystem fully functional until the
+ * absolute end.
+ */
+
+DECLARE_MGROUP(LOG)
+DEFINE_MGROUP_ACTIVEATEXIT(LOG, "logging subsystem")
+
+DEFINE_MTYPE_STATIC(LOG, LOG_FD, "log file target")
+DEFINE_MTYPE_STATIC(LOG, LOG_FD_NAME, "log file name")
+DEFINE_MTYPE_STATIC(LOG, LOG_FD_ROTATE, "log file rotate helper")
+DEFINE_MTYPE_STATIC(LOG, LOG_SYSL, "syslog target")
struct zlt_fd {
struct zlog_target zt;