| 124 | } |
| 125 | |
| 126 | static void finish_report(const struct leak_detect *leaks) |
| 127 | { |
| 128 | struct htable *memtable; |
| 129 | const tal_t *i; |
| 130 | const uintptr_t *backtrace; |
| 131 | struct command *cmd; |
| 132 | struct lightningd *ld; |
| 133 | struct json_stream *response; |
| 134 | |
| 135 | /* If it timed out, we free ourselved and exit! */ |
| 136 | if (!leaks->cmd) { |
| 137 | tal_free(leaks); |
| 138 | return; |
| 139 | } |
| 140 | |
| 141 | /* Convenience variables */ |
| 142 | cmd = leaks->cmd; |
| 143 | ld = cmd->ld; |
| 144 | |
| 145 | /* Enter everything, except this cmd and its jcon */ |
| 146 | memtable = memleak_start(cmd); |
| 147 | |
| 148 | /* This command is not a leak! */ |
| 149 | memleak_ptr(memtable, cmd); |
| 150 | memleak_ignore_children(memtable, cmd); |
| 151 | |
| 152 | /* First delete known false positives. */ |
| 153 | memleak_scan_htable(memtable, &ld->topology->txwatches.raw); |
| 154 | memleak_scan_htable(memtable, &ld->topology->txowatches.raw); |
| 155 | memleak_scan_htable(memtable, &ld->htlcs_in.raw); |
| 156 | memleak_scan_htable(memtable, &ld->htlcs_out.raw); |
| 157 | memleak_scan_htable(memtable, &ld->htlc_sets.raw); |
| 158 | |
| 159 | /* Now delete ld and those which it has pointers to. */ |
| 160 | memleak_scan_obj(memtable, ld); |
| 161 | |
| 162 | response = json_stream_success(cmd); |
| 163 | json_array_start(response, "leaks"); |
| 164 | while ((i = memleak_get(memtable, &backtrace)) != NULL) { |
| 165 | const tal_t *p; |
| 166 | |
| 167 | json_object_start(response, NULL); |
| 168 | json_add_ptr(response, "value", i); |
| 169 | if (tal_name(i)) |
| 170 | json_add_string(response, "label", tal_name(i)); |
| 171 | |
| 172 | json_add_backtrace(response, backtrace); |
| 173 | json_array_start(response, "parents"); |
| 174 | for (p = tal_parent(i); p; p = tal_parent(p)) { |
| 175 | json_add_string(response, NULL, tal_name(p)); |
| 176 | p = tal_parent(p); |
| 177 | } |
| 178 | json_array_end(response); |
| 179 | json_object_end(response); |
| 180 | } |
| 181 | |
| 182 | for (size_t num_leakers = 0; |
| 183 | num_leakers < tal_count(leaks->leakers); |
no test coverage detected