Fouten in StackOverflow opsporen

A StackOverflowException wordt gegenereerd wanneer de uitvoeringsstack overloopt omdat deze te veel geneste methode-aanroepen bevat.

Stel dat u een app als volgt hebt:

using System;

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

De Main methode roept zichzelf continu aan totdat er geen stackruimte meer is. Zodra er geen stackruimte meer is, kan de uitvoering niet doorgaan en wordt er een gegooid StackOverflowException.

> dotnet run
Stack overflow.

Notitie

Op .NET 5 en hoger wordt de callstack uitgevoerd naar de console.

Notitie

In dit artikel wordt beschreven hoe u fouten opspoort in een stackoverloop met lldb. Als u windows gebruikt, raden we u aan om fouten in de app op te sporen met Visual Studio of Visual Studio Code.

Voorbeeld

  1. Voer de app uit met deze geconfigureerd voor het verzamelen van een dump bij crash

    > 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
    

    Notitie

    .NET 6 standaardiseert het voorvoegsel DOTNET_ in plaats van COMPlus_ voor omgevingsvariabelen die het gedrag van .NET-runtime configureren. Het COMPlus_ voorvoegsel blijft echter werken. Als u een eerdere versie van de .NET-runtime gebruikt, moet u nog steeds het COMPlus_ voorvoegsel voor omgevingsvariabelen gebruiken.

  2. De SOS-extensie installeren met dotnet-sos

    dotnet-sos install
    
  3. Fouten opsporen in de dump in lldb om de mislukte stack te zien

    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. Het bovenste frame 0x00007f59b40900cc wordt meerdere keren herhaald. Gebruik de SOS-opdrachtip2md om erachter te komen welke methode zich op het 0x00007f59b40900cc adres bevindt

    (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. Bekijk de aangegeven methode temp. Program.Main(System.String[]) en bron "/temp/Program.cs @ 9" om te zien of u erachter kunt komen wat u verkeerd hebt gedaan. Als het nog steeds niet duidelijk was, kunt u logboekregistratie toevoegen in dat gebied van de code.

Zie ook