4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek/*
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek SSSD
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek Common utilities for check-based tests using talloc.
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek Authors:
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek Martin Nagy <mnagy@redhat.com>
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek Copyright (C) Red Hat, Inc 2009
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek This program is free software; you can redistribute it and/or modify
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek it under the terms of the GNU General Public License as published by
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek the Free Software Foundation; either version 3 of the License, or
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek (at your option) any later version.
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek This program is distributed in the hope that it will be useful,
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek but WITHOUT ANY WARRANTY; without even the implied warranty of
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek GNU General Public License for more details.
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek You should have received a copy of the GNU General Public License
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek along with this program. If not, see <http://www.gnu.org/licenses/>.
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek*/
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek#include <stdio.h>
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek#include "tests/common.h"
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek#include "util/util.h"
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek#include "util/dlinklist.h"
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub HrozekTALLOC_CTX *global_talloc_context = NULL;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozekchar leak_err_msg[256];
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozekstruct size_snapshot {
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek struct size_snapshot *prev;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek struct size_snapshot *next;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek TALLOC_CTX *ctx;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek size_t bytes_allocated;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek};
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozekstatic struct size_snapshot *snapshot_stack;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek#define _set_leak_err_msg(fmt, ...) do { \
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek snprintf(leak_err_msg, sizeof(leak_err_msg), \
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek fmt, ##__VA_ARGS__); \
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek} while(0);
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozekconst char *check_leaks_err_msg(void)
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek{
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek return leak_err_msg;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek}
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
f4bcfcb1b91bfa6a568c4c99c2b3d16cd86090c6Lukas Slebodnikstatic bool
f4bcfcb1b91bfa6a568c4c99c2b3d16cd86090c6Lukas Slebodnikcheck_leaks(TALLOC_CTX *ctx, size_t bytes, const char *location)
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek{
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek size_t bytes_allocated;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
24000ed5b08499b49595436b8a3b348fcd4012deLukas Slebodnik if (ctx == NULL) {
24000ed5b08499b49595436b8a3b348fcd4012deLukas Slebodnik return false;
24000ed5b08499b49595436b8a3b348fcd4012deLukas Slebodnik }
24000ed5b08499b49595436b8a3b348fcd4012deLukas Slebodnik
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek bytes_allocated = talloc_total_size(ctx);
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek if (bytes_allocated != bytes) {
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek fprintf(stderr, "Leak report for %s:\n", location);
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek talloc_report_full(ctx, stderr);
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek _set_leak_err_msg("%s: memory leaks detected, %zd bytes still allocated",
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek location, bytes_allocated - bytes);
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek return false;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek }
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek return true;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek}
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozekvoid
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozekcheck_leaks_push(TALLOC_CTX *ctx)
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek{
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek struct size_snapshot *snapshot;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek snapshot = talloc(NULL, struct size_snapshot);
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek snapshot->ctx = ctx;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek snapshot->bytes_allocated = talloc_total_size(ctx);
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek DLIST_ADD(snapshot_stack, snapshot);
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek}
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozekbool
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek_check_leaks_pop(TALLOC_CTX *ctx, const char *location)
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek{
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek struct size_snapshot *snapshot;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek TALLOC_CTX *old_ctx;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek size_t bytes_allocated;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
24000ed5b08499b49595436b8a3b348fcd4012deLukas Slebodnik if (ctx == NULL) {
24000ed5b08499b49595436b8a3b348fcd4012deLukas Slebodnik return false;
24000ed5b08499b49595436b8a3b348fcd4012deLukas Slebodnik }
24000ed5b08499b49595436b8a3b348fcd4012deLukas Slebodnik
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek if (snapshot_stack == NULL) {
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek _set_leak_err_msg("%s: trying to pop an empty stack", location);
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek return false;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek }
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek snapshot = snapshot_stack;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek DLIST_REMOVE(snapshot_stack, snapshot);
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek old_ctx = snapshot->ctx;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek bytes_allocated = snapshot->bytes_allocated;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek if (old_ctx != ctx) {
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek _set_leak_err_msg("Bad push/pop order");
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek return false;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek }
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek talloc_zfree(snapshot);
f4bcfcb1b91bfa6a568c4c99c2b3d16cd86090c6Lukas Slebodnik return check_leaks(old_ctx, bytes_allocated, location);
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek}
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozekbool
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozekleak_check_setup(void)
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek{
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek talloc_enable_null_tracking();
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek global_talloc_context = talloc_new(NULL);
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek if (global_talloc_context == NULL) {
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek _set_leak_err_msg("talloc_new failed");
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek return false;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek }
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek check_leaks_push(global_talloc_context);
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek return true;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek}
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozekbool
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozekleak_check_teardown(void)
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek{
e36226da4d7d0e8000a25ab310383318e00d58d1Sumit Bose bool res;
20a2be57d764f58c4a6532310331e26a3273ada8Lukas Slebodnik res = check_leaks_pop(global_talloc_context);
20a2be57d764f58c4a6532310331e26a3273ada8Lukas Slebodnik if (!res) {
20a2be57d764f58c4a6532310331e26a3273ada8Lukas Slebodnik _set_leak_err_msg("check_leaks_pop failed in leak_check_teardown");
20a2be57d764f58c4a6532310331e26a3273ada8Lukas Slebodnik }
20a2be57d764f58c4a6532310331e26a3273ada8Lukas Slebodnik
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek if (snapshot_stack != NULL) {
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek _set_leak_err_msg("Exiting with a non-empty stack");
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek return false;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek }
f4bcfcb1b91bfa6a568c4c99c2b3d16cd86090c6Lukas Slebodnik res = check_leaks(global_talloc_context, 0, __location__);
e36226da4d7d0e8000a25ab310383318e00d58d1Sumit Bose talloc_disable_null_tracking();
e36226da4d7d0e8000a25ab310383318e00d58d1Sumit Bose talloc_free(global_talloc_context);
e36226da4d7d0e8000a25ab310383318e00d58d1Sumit Bose return res;
4139a7a731f2831963a42b26aac111422be28792Jakub Hrozek}