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
;
43 buflen
= talloc_get_size(buf
);
45 if (buflen
> str_len
) {
46 start
= buf
+ str_len
;
47 space
= buflen
- str_len
;
54 printlen
= vsnprintf(start
, space
, fmt
, ap2
);
61 needed
= str_len
+ printlen
+ 1;
63 if (needed
> buflen
) {
64 buflen
= MAX(128, buflen
);
66 while (buflen
< needed
) {
70 tmpbuf
= talloc_realloc(NULL
, buf
, char, buflen
);
77 vsnprintf(buf
+ str_len
, buflen
- str_len
, fmt
, ap2
);
80 *pstr_len
= (needed
- 1);
87 static char *talloc_asprintf_append_largebuf(char *buf
, ssize_t
*pstr_len
,
93 buf
= talloc_vasprintf_append_largebuf(buf
, pstr_len
, fmt
, ap
);
98 struct talloc_report_str_state
{
103 static void talloc_report_str_helper(const void *ptr
, int depth
, int max_depth
,
104 int is_ref
, void *private_data
)
106 struct talloc_report_str_state
*state
= private_data
;
107 const char *name
= talloc_get_name(ptr
);
109 if (ptr
== state
->s
) {
114 state
->s
= talloc_asprintf_append_largebuf(
115 state
->s
, &state
->str_len
,
116 "%*sreference to: %s\n", depth
*4, "", name
);
121 state
->s
= talloc_asprintf_append_largebuf(
122 state
->s
, &state
->str_len
,
123 "%stalloc report on '%s' "
124 "(total %6lu bytes in %3lu blocks)\n",
125 (max_depth
< 0 ? "full " :""), name
,
126 (unsigned long)talloc_total_size(ptr
),
127 (unsigned long)talloc_total_blocks(ptr
));
131 if (strcmp(name
, "char") == 0) {
133 * Print out the first 50 bytes of the string
135 state
->s
= talloc_asprintf_append_largebuf(
136 state
->s
, &state
->str_len
,
137 "%*s%-30s contains %6lu bytes in %3lu blocks "
138 "(ref %d): %*s\n", depth
*4, "", name
,
139 (unsigned long)talloc_total_size(ptr
),
140 (unsigned long)talloc_total_blocks(ptr
),
141 talloc_reference_count(ptr
),
142 MIN(50, talloc_get_size(ptr
)),
147 state
->s
= talloc_asprintf_append_largebuf(
148 state
->s
, &state
->str_len
,
149 "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n",
151 (unsigned long)talloc_total_size(ptr
),
152 (unsigned long)talloc_total_blocks(ptr
),
153 talloc_reference_count(ptr
));
156 char *talloc_report_str(TALLOC_CTX
*mem_ctx
, TALLOC_CTX
*root
)
158 struct talloc_report_str_state state
;
160 state
.s
= talloc_strdup(mem_ctx
, "");
161 if (state
.s
== NULL
) {
166 talloc_report_depth_cb(root
, 0, -1, talloc_report_str_helper
, &state
);
168 if (state
.str_len
== -1) {
169 talloc_free(state
.s
);
173 return talloc_realloc(mem_ctx
, state
.s
, char, state
.str_len
+1);