Skip to content

Commit 55f870e

Browse files
committed
trace: double allocation if we run out.
This doesn't happen very often, but can with autoclean. However, we rarely traverse to the end, since we always expect to find what we're looking for, and we fill from the front. So even a large array (unless it's used) is fine. Subtle: when we injected a parent, we used "active_spans" as the (arbitrary) key. That can now change with reallocation, and so if that memory were reused we could have a key clash. So we use "&active_spans" which doesn't change. Signed-off-by: Rusty Russell <[email protected]>
1 parent 858e3b0 commit 55f870e

File tree

1 file changed

+15
-20
lines changed

1 file changed

+15
-20
lines changed

common/trace.c

+15-20
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#include <assert.h>
33
#include <ccan/endian/endian.h>
44
#include <ccan/err/err.h>
5-
#include <ccan/htable/htable.h>
65
#include <ccan/str/hex/hex.h>
76
#include <ccan/tal/str/str.h>
87
#include <ccan/tal/tal.h>
@@ -18,8 +17,6 @@
1817
#if HAVE_USDT
1918
#include <sys/sdt.h>
2019

21-
#define MAX_ACTIVE_SPANS 128
22-
2320
/* The traceperent format is defined in W3C Trace Context RFC[1].
2421
* Its format is defined as
2522
*
@@ -123,7 +120,7 @@ static void trace_inject_traceparent(void)
123120
current = trace_span_slot();
124121
assert(current);
125122

126-
init_span(current, trace_key(active_spans), "", NULL);
123+
init_span(current, trace_key(&active_spans), "", NULL);
127124
assert(current && !current->parent);
128125

129126
if (!hex_decode(traceparent + 3, 16, &trace_hi, sizeof(trace_hi))
@@ -145,7 +142,7 @@ static void trace_inject_traceparent(void)
145142
/** Quickly print out the entries in the `active_spans`. */
146143
static void trace_spans_print(void)
147144
{
148-
for (size_t j = 0; j < MAX_ACTIVE_SPANS; j++) {
145+
for (size_t j = 0; j < tal_count(active_spans); j++) {
149146
struct span *s = &active_spans[j], *parent = s->parent;
150147
TRACE_DBG(" > %zu: %s (key=%zu, parent=%s, "
151148
"parent_key=%zu)\n",
@@ -156,17 +153,17 @@ static void trace_spans_print(void)
156153

157154
/** Small helper to check for consistency in the linking. The idea is
158155
* that we should be able to reach the root (a span without a
159-
* `parent`) in less than `MAX_ACTIVE_SPANS` steps. */
156+
* `parent`) in less than the number of spans. */
160157
static void trace_check_tree(void)
161158
{
162159
/* `current` is either NULL or a valid entry. */
163160

164161
/* Walk the tree structure from leaves to their roots. It
165-
* should not take more than `MAX_ACTIVE_SPANS`. */
162+
* should not take more than the number of spans. */
166163
struct span *c;
167-
for (size_t i = 0; i < MAX_ACTIVE_SPANS; i++) {
164+
for (size_t i = 0; i < tal_count(active_spans); i++) {
168165
c = &active_spans[i];
169-
for (int j = 0; j < MAX_ACTIVE_SPANS; j++)
166+
for (int j = 0; j < tal_count(active_spans); j++)
170167
if (c->parent == NULL)
171168
break;
172169
else
@@ -189,7 +186,8 @@ static void trace_init(void)
189186
const char *dev_trace_file;
190187
if (active_spans)
191188
return;
192-
active_spans = calloc(MAX_ACTIVE_SPANS, sizeof(struct span));
189+
190+
active_spans = notleak(tal_arrz(NULL, struct span, 1));
193191

194192
current = NULL;
195193
dev_trace_file = getenv("CLN_DEV_TRACE_FILE");
@@ -213,7 +211,7 @@ static size_t trace_key(const void *key)
213211

214212
static struct span *trace_span_find(size_t key)
215213
{
216-
for (size_t i = 0; i < MAX_ACTIVE_SPANS; i++)
214+
for (size_t i = 0; i < tal_count(active_spans); i++)
217215
if (active_spans[i].key == key)
218216
return &active_spans[i];
219217

@@ -232,14 +230,12 @@ static struct span *trace_span_slot(void)
232230
* that, and we should get an empty slot. */
233231
struct span *s = trace_span_find(0);
234232

235-
/* Might end up here if we have more than MAX_ACTIVE_SPANS
236-
* concurrent spans. */
233+
/* In the unlikely case this fails, double it */
237234
if (!s) {
238-
fprintf(stderr, "%u: out of spans, disabling tracing\n", getpid());
239-
for (size_t i = 0; i < MAX_ACTIVE_SPANS; i++)
240-
trace_span_clear(&active_spans[i]);
241-
disable_trace = true;
242-
return NULL;
235+
TRACE_DBG("%u: out of %zu spans, doubling!\n",
236+
getpid(), tal_count(active_spans));
237+
tal_resizez(&active_spans, tal_count(active_spans) * 2);
238+
s = trace_span_find(0);
243239
}
244240
assert(s->parent == NULL);
245241

@@ -460,8 +456,7 @@ void trace_span_resume_(const void *key, const char *lbl)
460456

461457
void trace_cleanup(void)
462458
{
463-
free(active_spans);
464-
active_spans = NULL;
459+
active_spans = tal_free(active_spans);
465460
}
466461

467462
#else /* HAVE_USDT */

0 commit comments

Comments
 (0)