Branch data Line data Source code
1 : : /*
2 : : SSSD
3 : :
4 : : Common utilities for check-based tests using talloc.
5 : :
6 : : Authors:
7 : : Martin Nagy <mnagy@redhat.com>
8 : :
9 : : Copyright (C) Red Hat, Inc 2009
10 : :
11 : : This program is free software; you can redistribute it and/or modify
12 : : it under the terms of the GNU General Public License as published by
13 : : the Free Software Foundation; either version 3 of the License, or
14 : : (at your option) any later version.
15 : :
16 : : This program is distributed in the hope that it will be useful,
17 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : GNU General Public License for more details.
20 : :
21 : : You should have received a copy of the GNU General Public License
22 : : along with this program. If not, see <http://www.gnu.org/licenses/>.
23 : : */
24 : :
25 : : #include <stdio.h>
26 : : #include <check.h>
27 : : #include "tests/common.h"
28 : : #include "util/util.h"
29 : : #include "util/dlinklist.h"
30 : :
31 : : TALLOC_CTX *global_talloc_context = NULL;
32 : :
33 : :
34 : : struct size_snapshot {
35 : : struct size_snapshot *prev;
36 : : struct size_snapshot *next;
37 : :
38 : : TALLOC_CTX *ctx;
39 : : size_t bytes_allocated;
40 : : };
41 : :
42 : : static struct size_snapshot *snapshot_stack;
43 : :
44 : : void
45 : 115 : _check_leaks(TALLOC_CTX *ctx, size_t bytes, const char *location)
46 : : {
47 : : size_t bytes_allocated;
48 : :
49 : 115 : bytes_allocated = talloc_total_size(ctx);
50 [ - + ]: 115 : if (bytes_allocated != bytes) {
51 : 0 : fprintf(stderr, "Leak report for %s:\n", location);
52 : 0 : talloc_report_full(ctx, stderr);
53 : 0 : fail("%s: memory leaks detected, %d bytes still allocated",
54 : : location, bytes_allocated - bytes);
55 : : }
56 : 115 : }
57 : :
58 : : void
59 : 66 : check_leaks_push(TALLOC_CTX *ctx)
60 : : {
61 : : struct size_snapshot *snapshot;
62 : :
63 : 66 : snapshot = talloc(NULL, struct size_snapshot);
64 : 66 : snapshot->ctx = ctx;
65 : 66 : snapshot->bytes_allocated = talloc_total_size(ctx);
66 [ + + ]: 66 : DLIST_ADD(snapshot_stack, snapshot);
67 : 66 : }
68 : :
69 : : void
70 : 66 : _check_leaks_pop(TALLOC_CTX *ctx, const char *location)
71 : : {
72 : : struct size_snapshot *snapshot;
73 : : TALLOC_CTX *old_ctx;
74 : : size_t bytes_allocated;
75 : :
76 [ - + ]: 66 : if (snapshot_stack == NULL) {
77 : 0 : fail("%s: trying to pop an empty stack");
78 : : }
79 : :
80 : 66 : snapshot = snapshot_stack;
81 [ + + ][ + - ]: 66 : DLIST_REMOVE(snapshot_stack, snapshot);
82 : :
83 : 66 : old_ctx = snapshot->ctx;
84 : 66 : bytes_allocated = snapshot->bytes_allocated;
85 : :
86 : 66 : fail_if(old_ctx != ctx, "Bad push/pop order");
87 : :
88 : 66 : talloc_zfree(snapshot);
89 : 66 : _check_leaks(old_ctx, bytes_allocated, location);
90 : 66 : }
91 : :
92 : : void
93 : 49 : leak_check_setup(void)
94 : : {
95 : 49 : talloc_enable_null_tracking();
96 : 49 : global_talloc_context = talloc_new(NULL);
97 : 49 : fail_unless(global_talloc_context != NULL, "talloc_new failed");
98 : 49 : check_leaks_push(global_talloc_context);
99 : 49 : }
100 : :
101 : : void
102 : 49 : leak_check_teardown(void)
103 : : {
104 : 49 : check_leaks_pop(global_talloc_context);
105 [ - + ]: 49 : if (snapshot_stack != NULL) {
106 : 0 : fail("Exiting with a non-empty stack");
107 : : }
108 : 49 : check_leaks(global_talloc_context, 0);
109 : 49 : }
|