2 * talloc_report into a string
4 * Copyright Volker Lendecke <vl@samba.org> 2015
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "talloc_report.h"
24 * talloc_vasprintf into a buffer that doubles its size. The real string
25 * length is maintained in "pstr_len".
28 static char *talloc_vasprintf_append_largebuf(char *buf
, ssize_t
*pstr_len
,
29 const char *fmt
, va_list ap
)
30 PRINTF_ATTRIBUTE(3,0);
32 static char *talloc_vasprintf_append_largebuf(char *buf
, ssize_t
*pstr_len
,
33 const char *fmt
, va_list ap
)
35 ssize_t str_len
= *pstr_len
;
36 size_t buflen
, needed
, space
= 0;
37 char *start
= NULL
, *tmpbuf
= NULL
;
50 buflen
= talloc_get_size(buf
);
52 if (buflen
> (size_t)str_len
) {
53 start
= buf
+ str_len
;
54 space
= buflen
- str_len
;
60 printlen
= vsnprintf(start
, space
, fmt
, ap2
);
67 needed
= str_len
+ printlen
+ 1;
69 if (needed
> buflen
) {
70 buflen
= MAX(128, buflen
);
72 while (buflen
< needed
) {
76 tmpbuf
= talloc_realloc(NULL
, buf
, char, buflen
);
83 vsnprintf(buf
+ str_len
, buflen
- str_len
, fmt
, ap2
);
86 *pstr_len
= (needed
- 1);
93 static char *talloc_asprintf_append_largebuf(char *buf
, ssize_t
*pstr_len
,
95 PRINTF_ATTRIBUTE(3,4);
97 static char *talloc_asprintf_append_largebuf(char *buf
, ssize_t
*pstr_len
,
103 buf
= talloc_vasprintf_append_largebuf(buf
, pstr_len
, fmt
, ap
);
108 struct talloc_report_str_state
{
113 static void talloc_report_str_helper(const void *ptr
, int depth
, int max_depth
,
114 int is_ref
, void *private_data
)
116 struct talloc_report_str_state
*state
= private_data
;
117 const char *name
= talloc_get_name(ptr
);
119 if (ptr
== state
->s
) {
124 state
->s
= talloc_asprintf_append_largebuf(
125 state
->s
, &state
->str_len
,
126 "%*sreference to: %s\n", depth
*4, "", name
);
131 state
->s
= talloc_asprintf_append_largebuf(
132 state
->s
, &state
->str_len
,
133 "%stalloc report on '%s' "
134 "(total %6lu bytes in %3lu blocks)\n",
135 (max_depth
< 0 ? "full " :""), name
,
136 (unsigned long)talloc_total_size(ptr
),
137 (unsigned long)talloc_total_blocks(ptr
));
141 if (strcmp(name
, "char") == 0) {
143 * Print out the first 50 bytes of the string
145 state
->s
= talloc_asprintf_append_largebuf(
146 state
->s
, &state
->str_len
,
147 "%*s%-30s contains %6lu bytes in %3lu blocks "
148 "(ref %zu): %*s\n", depth
*4, "", name
,
149 (unsigned long)talloc_total_size(ptr
),
150 (unsigned long)talloc_total_blocks(ptr
),
151 talloc_reference_count(ptr
),
152 (int)MIN(50, talloc_get_size(ptr
)),
157 state
->s
= talloc_asprintf_append_largebuf(
158 state
->s
, &state
->str_len
,
159 "%*s%-30s contains %6lu bytes in %3lu blocks (ref %zu) %p\n",
161 (unsigned long)talloc_total_size(ptr
),
162 (unsigned long)talloc_total_blocks(ptr
),
163 talloc_reference_count(ptr
), ptr
);
166 char *talloc_report_str(TALLOC_CTX
*mem_ctx
, TALLOC_CTX
*root
)
168 struct talloc_report_str_state state
;
170 state
.s
= talloc_strdup(mem_ctx
, "");
171 if (state
.s
== NULL
) {
176 talloc_report_depth_cb(root
, 0, -1, talloc_report_str_helper
, &state
);
178 if (state
.str_len
== -1) {
179 talloc_free(state
.s
);
183 return talloc_realloc(mem_ctx
, state
.s
, char, state
.str_len
+1);