问题标签 [stack-overflow]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - StackOverflowException 没有递归或无限循环?
背景
我有一个DataGridView
正在使用的控件,我在下面添加了我的处理程序到DataGridView.CellFormatting
事件中,以便可以使某些单元格中的值更易于阅读。这个事件处理程序一直工作得很好,格式化所有值都没有问题。
然而,最近,我发现一个非常罕见的情况会导致一个不寻常的错误。我DataGridView
的项目到期日的列总是有一个int
值。0
表示事件永远不会到期,任何其他值都是到期日的 UTC 时间戳。对应的 MySQL db 列不允许空值。当用户从DataGridView
具有截止日期的一行移动到具有截止日期的另一DataGridView
行时(此时一切仍然正常),然后按下一个按钮,从数据库中重新加载数据(不发送更新,本质上是调用DataAdapter.Fill()
),程序生成一个StackOverflowException
**。
没有递归?
对我来说如此不寻常的是,我看不到递归或无限循环在哪里。我添加int cellFormatCallCount
为类成员,并在每次调用期间递增它,但在引发异常时,调试器将其值显示int
为 1,这是我所期望的,因为我没有受到印象并且递归正在发生。
有人可以帮助我吗?
如何查看堆栈跟踪?在 VS2008 中它说:
{Cannot evaluate expression because the current thread is in a stack overflow state.}
最好的祝福,
罗宾逊
c# - Structuremap Stackoverflow Exception
I keep getting a stackoverflow exception when I call "GetInstance" (the last line). All, yes ALL of my types implement ITracker. MultiTracker has a constructor with a single parameter, which is an array of ITracker's.
It seems like StructureMap is ignoring the fact that I told it that MultiTracker is the default class I want when requesting the type ITracker.
I just can't get it to work. Any thoughts?
asp.net - 使用 WinDbg 和 ADPlus 帮助捕获 StackOverflowException
简洁版本
我想要一个 ADPlus 脚本,它会在第一次出现 StackOverflowException 时执行完整的内存转储,然后再清理任何内容,并忽略所有其他异常类型。
日志版本
在发布新的 ASP.NET 代码后,我们开始出现间歇性 StackOverflowExceptions。我们已经在自上次已知良好安装后添加的修订版中寻找无限递归和所有常见的嫌疑人,但找不到任何东西。该网站将运行长达一个小时,然后崩溃。
我们使用了 WinDbg 和 SOS 并尝试使用 ADPlus 获取崩溃日志,使用以下命令:
-NoDumpOnFirst 的原因是我们只能在繁忙的服务器上在生产中重现此错误。为了对每个第一次机会异常(嘿,它发生)进行小型转储,调试器必须暂停 IIS 工作进程足够长的时间以写出 16 meg 文件,因此请求排队并且应用程序变得不稳定。因为错误可能需要长达一个小时才能抬起它丑陋的脑袋,所以这是有问题的。
因此,使用 -NoDumpOnFirst,我得到了一个转储文件,WinDbg 输出这些线程用于:
尝试打印异常表明没有堆栈跟踪,并且其他方法抱怨它是非托管代码。我的猜测是,由于转储是在进程死亡时创建的,因此所有线程都已被垃圾收集,并且没有信息可以获取。
我真的很想让调试器在 StackOverflowException 的第一次机会上执行完全转储并忽略所有其他异常类型。我知道 ADPlus 可以使用配置文件 - http://msdn.microsoft.com/en-us/library/cc409304.aspx - 但格式对我来说都是希腊语。谁能告诉我如何制作一个可以做到这一点的 ADPlus 脚本?
...当然,如果您查看上面的线程列表并且您确切地知道出了什么问题,或者如果我给您更多信息就可以弄清楚,您也可以告诉我。
解决尝试 1
谢谢 deemok 的回答,虽然不太正确,但这将我推向了正确的方向。Stack Overflow 的异常代码不正确(它是 sbo 不是 sov),(或者我当时认为,请参阅下面的 deemok 编辑)所以我尝试使用以下配置进行调试:
并使用以下命令:
我验证了输出的日志文件指示了正确的配置。诀窍是 adplus 的命令行参数按顺序执行,因此如果您从捕获第一次机会异常的配置开始,然后应用 -NoDumpOnFirst,则配置设置将被覆盖。如果最后使用 -c 应用配置,则其设置将胜出。
然而,最后,堆栈溢出被证明是无法捕获的。发生堆栈溢出,无法接收内存转储,然后在第二次机会进程结束事件上发生转储,再次所有内容都被垃圾收集,我无法获得任何有用的信息。
我试图短路进程结束异常,以防它参与并覆盖堆栈溢出,但随后发生了异常,我只是没有内存转储。
幸运的是,我通过检查代码偶然发现了答案。当然,这是一个循环方法调用的例子。
实际分辨率
这个问题早就解决了,但我很快就制作了一个会导致堆栈溢出的 ASP.NET 页面。(毕竟这并不难)并在下面尝试了 Axl 的回应。
XML 有点偏离 - Axl 只是忘记关闭</ADPlus>
标签(或者可能在复制粘贴中丢失了它),但这很容易修复,adplus 很友好地告诉我到底出了什么问题。
我将该脚本设置为针对我的测试堆栈溢出引发程序,将结果加载到 windbg 中,当我调用 !clrstack 时,我得到了一个非常清晰(而且很长)的循环调用彼此的方法列表。这一下子就发现问题了!下次堆栈溢出来敲我的门时,我会保留此页面的书签。
c++ - 大型二维数组给出分段错误
我正在 Linux 中编写一些 C++ 代码,其中我声明了一些 2D 数组,如下所示:
在编译过程中没有错误。当我执行时,它说“分段错误”。
文我把数组的大小从5000减少到50,程序运行正常。我怎样才能保护自己免受这个问题的影响?
security - 有没有办法绕过 SSP(StackSmashing Protection)/Propolice?
经过一些研究,我没有找到任何描述方法的论文(甚至没有不可靠的)。似乎 SSP (StackSmashing Protection)/Propolice
f# - 避免堆栈溢出(使用 F# 无限序列)
我有我为 f# 中的 morris seq 编写的这个“学习代码”,它遭受了我不知道如何避免的堆栈溢出。"morris" 返回一个无限的 "see and say" 序列(即 {{1}, {1,1}, {2,1}, {1,2,1,1}, {1,1,1 ,2,2,1}, {3,1,2,2,1,1},...})。
您可以使用 Seq.nth 选择第 n 次迭代,但您只能在遇到堆栈溢出之前完成此操作。我有一点递归是尾递归,它本质上构建了一组链接的枚举器。这不是问题所在。这是在第 4000 个序列上调用“枚举”的时候。请注意,对于 F# 1.9.6.16,之前的版本最高超过 14000)。这是因为链接序列的解析方式。序列是惰性的,因此“递归”是惰性的。也就是说, seq n 调用 seq n-1 ,后者调用 seq n-2 等等以获取第一项(第一个 # 是最坏的情况)。
我知道,[|0|] |> Seq.append str |> Seq.windowed 2
这使我的问题变得更糟,如果我消除它,我可以产生三倍的#。实际上,代码运行良好。morris 的第 3125 次迭代长度将超过 10^359 个字符。
我真正想要解决的问题是如何保留惰性 eval,并且对于我可以选择的迭代没有基于堆栈大小的限制。我正在寻找合适的 F# 习惯用法来根据内存大小进行限制。
2010 年 10 月更新
在更好地学习 F#,一点点 Haskell,思考和研究这个问题一年多之后,我终于可以回答我自己的问题了。但与难题一样,问题始于错误的问题。问题不在于序列的序列——这实际上是因为递归定义的序列。我的函数式编程技能现在稍微好一点,所以更容易看到下面的版本发生了什么,它仍然得到一个 stackoverflow
这基本上创建了一个非常长的 Seq 处理函数调用链来生成序列。F#自带的Seq模块就是不使用栈就不能跟链的。它对追加和递归定义的序列进行了优化,但该优化仅在递归实现追加时才有效。
所以这会起作用
这个会得到一个stackoverflow。
为了证明 F# 库是问题所在,我编写了自己的 Seq 模块,该模块使用延续实现了追加、成对、扫描和收集,现在我可以毫无问题地开始生成和打印 50,000 个序列(它永远不会完成,因为它已经结束了10^5697 位长)。
一些附加说明:
- Continuations 是我一直在寻找的习语,但在这种情况下,它们必须进入 F# 库,而不是我的代码。我从Tomas Petricek 的 Real-World Functional Programming一书中了解了 F# 中的延续。
- 我接受的惰性列表答案是另一个成语;懒惰的评价。在我重写的库中,我还必须利用惰性类型来避免 stackoverflow。
- 惰性列表版本是靠运气工作的(可能是设计使然,但这超出了我目前的能力范围)——它在构建和迭代时使用的活动模式匹配导致列表在所需的递归变得太深之前计算值,所以它很懒,但不是那么懒,它需要继续以避免stackoverflow。例如,当第二个序列需要第一个序列中的一个数字时,它已经被计算出来了。换句话说,LL 版本对于序列生成并不是严格的 JIT 惰性,只是列表管理。
mvvm - 我怎样才能避免这个无限循环?
感觉必须有一些半简单的解决方案,但我就是想不通。
编辑:前面的示例更清楚地显示了无限循环,但这提供了更多上下文。查看预编辑以快速了解问题。
以下 2 个类代表模型视图视图模型 ( MVVM ) 模式的视图模型。
.
除非要求,否则我不会费心展示模型(配方和类别),但它们基本上会处理业务逻辑(例如,将配方添加到类别也会添加链接的另一端,即如果类别包含食谱,那么食谱也包含在该类别中)并且基本上决定了事情的进展。ViewModel 为 WPF 数据绑定提供了一个很好的接口。这就是包装类的原因
由于无限循环在构造函数中并且它正在尝试创建新对象,因此我不能只设置一个布尔标志来防止这种情况发生,因为这两个对象都没有完成构造。
我在想的是(作为单例或传递给构造函数或两者兼而有之)a Dictionary<Recipe, RecipeViewModel>
,Dictionary<Category, CategoryViewModel>
它将延迟加载视图模型,但如果一个已经存在,则不会创建一个新的,但我还没有解决试图看看它是否会工作,因为它已经很晚了,我有点厌倦了在过去的 6 个小时左右处理这个问题。
不能保证这里的代码会编译,因为我取出了一堆与手头的问题无关的东西。
size - 如何通过监控堆栈大小来防止堆栈溢出?
许多 C/C++/Fortran 和其他程序员会遇到“堆栈溢出”错误。我的问题是,是否有工具、程序或简单的代码片段允许我们在程序运行时监控或检查堆栈的大小?这可能有助于查明堆栈在何处累积并最终导致溢出。
memory - 将内存从 2GB 升级到 4GB 可以防止 Stack Overflow 异常吗?
我的电脑有 2GB 的 RAM 内存。当我在 C# 2008 Express Edition 中形成一个包含 70.000 个项目的数组的 3D 网格对象时,我收到错误消息“堆栈溢出异常处理...”。如果我将 RAM 内存从 2GB 升级到 4GB,我可以克服这个错误消息吗?
delphi - 快速排序和堆栈溢出异常
我认为 QuickSort 在某些特定情况下可能会导致堆栈溢出异常。
在排序过程中有两种选择枢轴元素的基本方法 - 枢轴值可以是排序范围中间的元素或随机选择的元素(在排序范围内)。第二种方法(随机)是否比第一种方法更不容易发生堆栈溢出?你能告诉我吗?
这是我的快速排序(Delphi)版本:
提前感谢您的建议!
马吕斯。