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
)
31 ssize_t str_len
= *pstr_len
;
32 size_t buflen
, needed
, space
;
46 buflen
= talloc_get_size(buf
);
48 if (buflen
> str_len
) {
49 start
= buf
+ str_len
;
50 space
= buflen
- str_len
;
57 printlen
= vsnprintf(start
, space
, fmt
, ap2
);
64 needed
= str_len
+ printlen
+ 1;
66 if (needed
> buflen
) {
67 buflen
= MAX(128, buflen
);
69 while (buflen
< needed
) {
73 tmpbuf
= talloc_realloc(NULL
, buf
, char, buflen
);
80 vsnprintf(buf
+ str_len
, buflen
- str_len
, fmt
, ap2
);
83 *pstr_len
= (needed
- 1);
90 static char *talloc_asprintf_append_largebuf(char *buf
, ssize_t
*pstr_len
,
96 buf
= talloc_vasprintf_append_largebuf(buf
, pstr_len
, fmt
, ap
);
101 struct talloc_report_str_state
{
106 static void talloc_report_str_helper(const void *ptr
, int depth
, int max_depth
,
107 int is_ref
, void *private_data
)
109 struct talloc_report_str_state
*state
= private_data
;
110 const char *name
= talloc_get_name(ptr
);
112 if (ptr
== state
->s
) {
117 state
->s
= talloc_asprintf_append_largebuf(
118 state
->s
, &state
->str_len
,
119 "%*sreference to: %s\n", depth
*4, "", name
);
124 state
->s
= talloc_asprintf_append_largebuf(
125 state
->s
, &state
->str_len
,
126 "%stalloc report on '%s' "
127 "(total %6lu bytes in %3lu blocks)\n",
128 (max_depth
< 0 ? "full " :""), name
,
129 (unsigned long)talloc_total_size(ptr
),
130 (unsigned long)talloc_total_blocks(ptr
));
134 if (strcmp(name
, "char") == 0) {
136 * Print out the first 50 bytes of the string
138 state
->s
= talloc_asprintf_append_largebuf(
139 state
->s
, &state
->str_len
,
140 "%*s%-30s contains %6lu bytes in %3lu blocks "
141 "(ref %d): %*s\n", depth
*4, "", name
,
142 (unsigned long)talloc_total_size(ptr
),
143 (unsigned long)talloc_total_blocks(ptr
),
144 talloc_reference_count(ptr
),
145 MIN(50, talloc_get_size(ptr
)),
150 state
->s
= talloc_asprintf_append_largebuf(
151 state
->s
, &state
->str_len
,
152 "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
154 (unsigned long)talloc_total_size(ptr
),
155 (unsigned long)talloc_total_blocks(ptr
),
156 talloc_reference_count(ptr
), ptr
);
159 char *talloc_report_str(TALLOC_CTX
*mem_ctx
, TALLOC_CTX
*root
)
161 struct talloc_report_str_state state
;
163 state
.s
= talloc_strdup(mem_ctx
, "");
164 if (state
.s
== NULL
) {
169 talloc_report_depth_cb(root
, 0, -1, talloc_report_str_helper
, &state
);
171 if (state
.str_len
== -1) {
172 talloc_free(state
.s
);
176 return talloc_realloc(mem_ctx
, state
.s
, char, state
.str_len
+1);