| 197 | } |
| 198 | |
| 199 | const void *memleak_get(struct htable *memtable, const uintptr_t **backtrace) |
| 200 | { |
| 201 | struct htable_iter it; |
| 202 | const tal_t *i, *p; |
| 203 | |
| 204 | /* Remove memtable itself */ |
| 205 | memleak_ptr(memtable, memtable); |
| 206 | |
| 207 | i = htable_first(memtable, &it); |
| 208 | if (!i) |
| 209 | return NULL; |
| 210 | |
| 211 | /* Delete from table (avoids parenting loops) */ |
| 212 | htable_delval(memtable, &it); |
| 213 | |
| 214 | /* Find ancestor, which is probably source of leak. */ |
| 215 | for (p = tal_parent(i); |
| 216 | htable_get(memtable, hash_ptr(p, NULL), ptr_match, p); |
| 217 | i = p, p = tal_parent(i)); |
| 218 | |
| 219 | /* Delete all children */ |
| 220 | remove_with_children(memtable, i); |
| 221 | |
| 222 | /* Does it have a child called "backtrace"? */ |
| 223 | for (*backtrace = tal_first(i); |
| 224 | *backtrace; |
| 225 | *backtrace = tal_next(*backtrace)) { |
| 226 | if (tal_name(*backtrace) |
| 227 | && streq(tal_name(*backtrace), "backtrace")) |
| 228 | break; |
| 229 | } |
| 230 | |
| 231 | return i; |
| 232 | } |
| 233 | |
| 234 | static int append_bt(void *data, uintptr_t pc) |
| 235 | { |
no test coverage detected