Aracılığıyla paylaş


StackOverflow hatalarını ayıklama

Çok fazla iç içe yöntem çağrısı içerdiğinden yürütme yığını taştığında bir StackOverflowException oluşturulur.

Örneğin, aşağıdaki gibi bir uygulamanız olduğunu varsayalım:

using System;

namespace temp
{
    class Program
    {
        static void Main(string[] args)
        {
            Main(args); // Oops, this recursion won't stop.
        }
    }
}

yöntemi Main , yığın alanı kalmayıncaya kadar sürekli olarak kendisini çağırır. Yığın alanı kalmadıktan sonra yürütme devam edemez ve bu nedenle bir StackOverflowExceptionoluşturur.

> dotnet run
Stack overflow.

Not

.NET 5 ve sonraki sürümlerde çağrı yığını konsoluna gönderilir.

Not

Bu makalede lldb ile yığın taşmasında hata ayıklama açıklanmaktadır. Windows üzerinde çalıştırıyorsanız, Visual Studio veya Visual Studio Code ile uygulamada hata ayıklamanızı öneririz.

Örnek

  1. Kilitlenmeyle ilgili dökümü toplamak için yapılandırılan uygulamayla uygulamayı çalıştırın

    > export DOTNET_DbgEnableMiniDump=1
    > dotnet run
    Stack overflow.
    Writing minidump with heap to file /tmp/coredump.6412
    Written 58191872 bytes (14207 pages) to core file
    

    Not

    .NET 6, .NET çalışma zamanı davranışını yapılandıran ortam değişkenleri yerine COMPlus_ ön eki DOTNET_ standartlaştırır. Ancak ön COMPlus_ ek çalışmaya devam eder. .NET çalışma zamanının önceki bir sürümünü kullanıyorsanız, yine de ortam değişkenleri için ön eki kullanmalısınız COMPlus_ .

  2. dotnet-sos kullanarak SOS uzantısını yükleme

    dotnet-sos install
    
  3. Başarısız yığını görmek için lldb'deki dökümde hata ayıklama

    lldb --core /temp/coredump.6412
    (lldb) bt
    ...
        frame #261930: 0x00007f59b40900cc
        frame #261931: 0x00007f59b40900cc
        frame #261932: 0x00007f59b40900cc
        frame #261933: 0x00007f59b40900cc
        frame #261934: 0x00007f59b40900cc
        frame #261935: 0x00007f5a2d4a080f libcoreclr.so`CallDescrWorkerInternal at unixasmmacrosamd64.inc:867
        frame #261936: 0x00007f5a2d3cc4c3 libcoreclr.so`MethodDescCallSite::CallTargetWorker(unsigned long const*, unsigned long*, int) at callhelpers.cpp:70
        frame #261937: 0x00007f5a2d3cc468 libcoreclr.so`MethodDescCallSite::CallTargetWorker(this=<unavailable>, pArguments=0x00007ffe8222e7b0, pReturnValue=0x0000000000000000, cbReturnValue=0) at callhelpers.cpp:604
        frame #261938: 0x00007f5a2d4b6182 libcoreclr.so`RunMain(MethodDesc*, short, int*, PtrArray**) [inlined] MethodDescCallSite::Call(this=<unavailable>, pArguments=<unavailable>) at callhelpers.h:468
    ...
    
  4. Üst çerçeve 0x00007f59b40900cc birkaç kez yinelenir. Adreste hangi yöntemin bulunduğunu 0x00007f59b40900cc bulmak için SOSip2md komutunu kullanın

    (lldb) ip2md 0x00007f59b40900cc
    MethodDesc:   00007f59b413ffa8
    Method Name:          temp.Program.Main(System.String[])
    Class:                00007f59b4181d40
    MethodTable:          00007f59b4190020
    mdToken:              0000000006000001
    Module:               00007f59b413dbf8
    IsJitted:             yes
    Current CodeAddr:     00007f59b40900a0
    Version History:
      ILCodeVersion:      0000000000000000
      ReJIT ID:           0
      IL Addr:            0000000000000000
         CodeAddr:           00007f59b40900a0  (MinOptJitted)
         NativeCodeVersion:  0000000000000000
    Source file:  /temp/Program.cs @ 9
    
  5. Belirtilen geçici yönteme göz atın. Program.Main(System.String[]) ve kaynak "/temp/Program.cs @ 9", neyi yanlış yaptığınıza karar vermenizi sağlar. Hala net değilse kodun bu alanına günlük kaydı ekleyebilirsiniz.

Ayrıca Bkz.