当执行堆栈溢出时,会引发 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.
备注
在 .NET 5 及更高版本上,调用栈将输出到控制台。
备注
本文介绍如何使用 lldb 调试堆栈溢出。 如果在 Windows 上运行,建议使用 Visual Studio 或 Visual Studio Code 调试应用。
示例
运行配置为在发生故障时收集转储的应用
> 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
备注
.NET 6 为用于配置 .NET 运行时行为的环境变量标准化前缀 DOTNET_ 而不是 COMPlus_。 但是,COMPlus_ 前缀仍将继续正常工作。 如果使用的是早期版本的 .NET 运行时,则环境变量仍应该使用 COMPlus_ 前缀。
使用 dotnet-sos 安装 SOS 扩展
dotnet-sos install
在 lldb 中调试转储以查看失败的堆栈
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 命令找出 0x00007f59b40900cc 地址处的方法
(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”,了解能否找出错误。 如果仍不清楚,则可以在该代码区域中添加日志记录。
另请参阅
.NET 中的转储简介
调试 Linux 转储
适用于 .NET 的 SOS 调试扩展
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有