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
;
50 buflen
= talloc_get_size(buf
);
52 if (buflen
> str_len
) {
53 start
= buf
+ str_len
;
54 space
= buflen
- str_len
;
61 printlen
= vsnprintf(start
, space
, fmt
, ap2
);
68 needed
= str_len
+ printlen
+ 1;
70 if (needed
> buflen
) {
71 buflen
= MAX(128, buflen
);
73 while (buflen
< needed
) {
77 tmpbuf
= talloc_realloc(NULL
, buf
, char, buflen
);
84 vsnprintf(buf
+ str_len
, buflen
- str_len
, fmt
, ap2
);
87 *pstr_len
= (needed
- 1);
94 static char *talloc_asprintf_append_largebuf(char *buf
, ssize_t
*pstr_len
,
96 PRINTF_ATTRIBUTE(3,4);
98 static char *talloc_asprintf_append_largebuf(char *buf
, ssize_t
*pstr_len
,
104 buf
= talloc_vasprintf_append_largebuf(buf
, pstr_len
, fmt
, ap
);
109 struct talloc_report_str_state
{
114 static void talloc_report_str_helper(const void *ptr
, int depth
, int max_depth
,
115 int is_ref
, void *private_data
)
117 struct talloc_report_str_state
*state
= private_data
;
118 const char *name
= talloc_get_name(ptr
);
120 if (ptr
== state
->s
) {
125 state
->s
= talloc_asprintf_append_largebuf(
126 state
->s
, &state
->str_len
,
127 "%*sreference to: %s\n", depth
*4, "", name
);
132 state
->s
= talloc_asprintf_append_largebuf(
133 state
->s
, &state
->str_len
,
134 "%stalloc report on '%s' "
135 "(total %6lu bytes in %3lu blocks)\n",
136 (max_depth
< 0 ? "full " :""), name
,
137 (unsigned long)talloc_total_size(ptr
),
138 (unsigned long)talloc_total_blocks(ptr
));
142 if (strcmp(name
, "char") == 0) {
144 * Print out the first 50 bytes of the string
146 state
->s
= talloc_asprintf_append_largebuf(
147 state
->s
, &state
->str_len
,
148 "%*s%-30s contains %6lu bytes in %3lu blocks "
149 "(ref %zu): %*s\n", depth
*4, "", name
,
150 (unsigned long)talloc_total_size(ptr
),
151 (unsigned long)talloc_total_blocks(ptr
),
152 talloc_reference_count(ptr
),
153 (int)MIN(50, talloc_get_size(ptr
)),
158 state
->s
= talloc_asprintf_append_largebuf(
159 state
->s
, &state
->str_len
,
160 "%*s%-30s contains %6lu bytes in %3lu blocks (ref %zu) %p\n",
162 (unsigned long)talloc_total_size(ptr
),
163 (unsigned long)talloc_total_blocks(ptr
),
164 talloc_reference_count(ptr
), ptr
);
167 char *talloc_report_str(TALLOC_CTX
*mem_ctx
, TALLOC_CTX
*root
)
169 struct talloc_report_str_state state
;
171 state
.s
= talloc_strdup(mem_ctx
, "");
172 if (state
.s
== NULL
) {
177 talloc_report_depth_cb(root
, 0, -1, talloc_report_str_helper
, &state
);
179 if (state
.str_len
== -1) {
180 talloc_free(state
.s
);
184 return talloc_realloc(mem_ctx
, state
.s
, char, state
.str_len
+1);