Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
При переполнении стека выполнения возникает ошибка StackOverflowException, так как в нём содержится слишком много вложенных вызовов методов. Часто это происходит, так как методы вызывает друг друга рекурсивно.
Например, предположим, что у вас есть приложение, как показано ниже.
using System;
namespace temp
{
class Program
{
static void Main(string[] args)
{
Main(args); // Oops, this recursion won't stop.
}
}
}
Метод Main будет рекурсивно вызывать себя, пока не закончится свободное место в стеке. После отсутствия дополнительного пространства стека выполнение не может продолжаться, поэтому он вызовет StackOverflowException.
> dotnet run
Stack overflow.
at temp.Program.Main(System.String[])
at temp.Program.Main(System.String[])
at temp.Program.Main(System.String[])
at temp.Program.Main(System.String[])
at temp.Program.Main(System.String[])
at temp.Program.Main(System.String[])
<this output repeats many more times>
Когда вы видите, что программа завершает работу с таким выводом, вы можете найти исходный код повторяющихся методов и исследовать логику, которая приводит к большому количеству вызовов.
Использование отладчика
Часто бывает достаточно только увидеть вышеупомянутый стек вызовов на консоли, чтобы определить проблемный код. Однако если проблема по-прежнему неясна, вы можете продолжить отладку.
В этом примере создается основной дамп при возникновении ошибки StackOverflowException, а затем загружается дамп в lldb (общий отладчик командной строки Linux) и выполняет его отладку.
Запустите приложение, настроенное для сбора дампа при сбое.
> 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Установите расширение SOS с помощью dotnet-sos.
dotnet-sos installОткройте дамп в lldb и используйте команду
bt(backtrace) для отображения стека.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 ...Верхний кадр
0x00007f59b40900ccповторяется несколько раз. Используйте команду SOS , чтобы узнать, какой управляемый метод расположен в адресеip2md.(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Перейдите к указанному методу temp.Program.Main(System.String[]) и проверьте исходник "/temp/Program.cs @ 9", чтобы понять, что код делает неправильно. Если требуется дополнительная информация, для проверки процесса можно использовать дополнительные команды отладчика или SOS.