diff --git a/CHANGELOG.md b/CHANGELOG.md index a10e05c120e..96a9981cc5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] +### Fixed + +- Possible nil dereference panic in `go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace`. (#5965) + diff --git a/instrumentation/net/http/httptrace/otelhttptrace/clienttrace.go b/instrumentation/net/http/httptrace/otelhttptrace/clienttrace.go index 67e03f24810..6ef23721cb7 100644 --- a/instrumentation/net/http/httptrace/otelhttptrace/clienttrace.go +++ b/instrumentation/net/http/httptrace/otelhttptrace/clienttrace.go @@ -215,6 +215,10 @@ func (ct *clientTracer) start(hook, spanName string, attrs ...attribute.KeyValue func (ct *clientTracer) end(hook string, err error, attrs ...attribute.KeyValue) { if !ct.useSpans { + // sometimes end may be called without previous start + if ct.root == nil { + ct.root = trace.SpanFromContext(ct.Context) + } if err != nil { attrs = append(attrs, attribute.String(hook+".error", err.Error())) } diff --git a/instrumentation/net/http/httptrace/otelhttptrace/test/clienttrace_test.go b/instrumentation/net/http/httptrace/otelhttptrace/test/clienttrace_test.go index 846f4fd128f..685ea49ec7c 100644 --- a/instrumentation/net/http/httptrace/otelhttptrace/test/clienttrace_test.go +++ b/instrumentation/net/http/httptrace/otelhttptrace/test/clienttrace_test.go @@ -250,6 +250,22 @@ func TestEndBeforeStartCreatesSpan(t *testing.T) { require.Len(t, spans, 1) } +func TestEndBeforeStartWithoutSubSpansDoesNotPanic(t *testing.T) { + sr := tracetest.NewSpanRecorder() + tp := trace.NewTracerProvider(trace.WithSpanProcessor(sr)) + otel.SetTracerProvider(tp) + + ct := otelhttptrace.NewClientTrace(context.Background(), otelhttptrace.WithoutSubSpans()) + + require.NotPanics(t, func() { + ct.DNSDone(httptrace.DNSDoneInfo{}) + }) + + // no spans created because we were just using background context without span + // and Start wasn't called which would have started a span + require.Len(t, sr.Ended(), 0) +} + type clientTraceTestFixture struct { Address string URL string