GCAllocationTick references an empty EventPipe stack on Linux x64

Đang mở
#137,240 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức phù hợp với người mới
35/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
csharp
Lĩnh vực
performance

Hướng nghiên cứu

Start with the captured .nettrace reproduction and the EventPipe stack parsing path in src/TraceEvent/EventPipe/StackCache.cs; compare how the event’s StackId=25 resolves to a zero-length entry. The report says the runtime stack-walk failure is unknown, so investigate the corresponding GC allocation tick stack emission in ep-rt-coreclr.cpp. Done means identifying why the stack is empty and confirming the behavior with a reproduction.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

area-Diagnostics-coreclr untriaged
Description

An EventPipe GCAllocationTick event from .NET 10.0.14 on Linux x64 references a stack entry containing zero instruction pointers. Nearly all other allocation ticks have stacks. This leaves an allocation sample without a caller even though the trace reports no dropped events, preventing a complete allocation-owner profile.

Reproduction Steps

This is a deterministic captured-trace reproduction; I have not isolated a minimal live workload that causes the empty stack.

  1. Download the public capture (artifact expires 2027-02-08):

    gh run download 42766418345 -R thomhurst/Relayer \
      -n frozen-concurrent-control-42766418345-1 -D capture
    
  2. Read capture/results/42306276036-profiled/1-baseline.nettrace in a console project referencing Microsoft.Diagnostics.Tracing.TraceEvent 3.1.21. Enable unsafe code and use:

    using System.Reflection;
    using Microsoft.Diagnostics.Tracing;
    
    unsafe class Program
    {
        static void Main(string[] args)
        {
            var field = typeof(TraceEvent).GetField("eventRecord",
                BindingFlags.Instance | BindingFlags.NonPublic)!;
            using var source = new EventPipeEventSource(args[0]);
            int ticks = 0;
            source.Clr.GCAllocationTick += ev =>
            {
                ticks++;
                // EVENT_RECORD layout on 64-bit platforms: ExtendedDataCount at byte 84.
                var record = (byte*)Pointer.Unbox(field.GetValue(ev)!);
                if (*(ushort*)(record + 84) == 0)
                    Console.WriteLine($"{ev.TimeStampRelativeMSec}ms " +
                        $"pid={ev.ProcessID} tid={ev.ThreadID} " +
                        $"type={ev.TypeName} amount={ev.AllocationAmount64}");
            };
            source.Process();
            Console.WriteLine($"ticks={ticks}");
        }
    }
    

    Output:

    1978.750716ms pid=3340 tid=3352 type=System.ArraySegment`1[System.Byte] amount=106600
    ticks=1998
    

The same offline reader with TraceEvent 4.0.0 produces identical output. No original application is needed to replay the captured event. Collection used dotnet-trace collect --profile gc-verbose --providers Relayer-FrozenMeasurement with a child process; the additional provider only emits interval markers.

Expected behavior

An allocation tick emitted during managed execution carries a managed caller stack usable for allocation attribution.

Actual behavior

One of 1998 allocation ticks has no stack extended data even before ETLX conversion. Inspecting the parsed EventPipe header for that event gives StackId=25, StackBytesSize=0, and a non-null StackBytes pointer. The stack cache resolves a stored zero-length entry; it is not an unresolved symbol or an ETLX-only lookup failure. TraceLog.EventsLost is zero. A second retained capture, results/42306276036-profiled/4-baseline.nettrace, has the same allocation type and weighted byte count with no stack.

Regression?

Unknown. This report does not establish that all allocation stacks are guaranteed or that the issue first appeared in .NET 10.

Configuration

Ubuntu 24.04, linux-x64; .NET SDK 10.0.403; runtime 10.0.14, commit 0427b9abbe. Offline replay tested with TraceEvent 3.1.21 and 4.0.0.

Other information

The TraceEvent 3.1.21 stack-block reader stores the serialized stack byte length. I also checked current PerfView main (4f3118c0fe7f624ae93a3249ae2ff7b6e1800e98) and runtime main (848b6c444a2c1205a16b6ad7afb9f4fba39b4048, including ep-rt-coreclr.cpp), current release notes, and existing open/closed issues; I did not find a matching fix. The precise runtime stack-walk failure remains unknown.

This was discovered while investigating allocation profiles in Relayer #349.

Please investigate why this GCAllocationTick references a zero-length stack.

Ngôn ngữ chính
C#
Star
18.4k
Fork
5.8k
Merge trung bình
2 ngày 19 giờ
Pull request đã merge (30 ngày)
590

Chuẩn bị môi trường

Mở trong Codespaces

Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của dotnet/runtime

Tất cả issue của dotnet/runtime

Issue tương tự

Thêm issue về C#

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.