首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >解决方法-解决StackOverflowException问题

解决方法-解决StackOverflowException问题
EN

Stack Overflow用户
提问于 2012-10-01 08:22:36
回答 3查看 1.9K关注 0票数 5

我使用HtmlAgilityPack解析大约200,000个超文本标记语言文档。

我无法预测这些文档的内容,但是其中一个文档会导致我的应用程序因StackOverflowException而失败。该文档包含以下HTML:

代码语言:javascript
复制
<ol>
    <li><li><li><li><li><li>...
</ol>

像这样嵌套的<li>元素大约有10,000个。由于HtmlAgilityPack解析超文本标记语言的方式,它会导致StackOverflowException

不幸的是,在.NET 2.0和更高版本中不能捕获StackOverflowException。

我确实想为线程的堆栈设置一个更大的大小,但是设置一个更大的堆栈大小是一个技巧:它会导致我的程序使用更多的内存(我的程序启动大约50个线程来处理HTML,所以所有这些线程都会增加堆栈大小),并且如果它再次遇到类似的情况,将需要手动调整。

有没有其他我可以采用的变通办法?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-10-01 09:00:29

理想情况下,长期的解决方案是为HtmlAgilityPack打补丁,使其使用堆栈而不是调用栈,但这对我来说太大了。我暂时丢失了我的CodePlex帐户详细信息,但当我找回它们时,我会就这个问题提交一份问题报告。我还注意到,这个问题可能会给任何使用HtmlAgilityPack清理用户提交的超文本标记语言的站点带来拒绝服务攻击漏洞--精心编制的过度嵌套的超文本标记语言文档将导致w3wp.exe进程死亡。

同时,我认为最好的方法是手动覆盖最大线程堆栈大小。我在前面的声明中错误地认为,更大的堆栈大小意味着所有线程都会自动消耗该内存(似乎内存页是随着线程堆栈的增长而分配的,而不是一次分配给所有线程堆栈)。

我复制了<ol><li>页面并运行了一些实验。我发现我的程序在堆栈大小小于2^21字节的时候失败了,但是2^22的最大大小成功了--也就是4MB,在我的书中被认为是一个“可接受的”黑客……就目前而言。

票数 2
EN

Stack Overflow用户

发布于 2013-03-09 04:55:19

我刚刚修补了一个错误,我相信这和你的描述是一样的。已将补丁上传到hap项目网站...

http://www.codeplex.com/site/users/view/sjdirect (参见2012年3月8日的补丁)

或在此处查看有关此问题和结果的更多文档...

https://code.google.com/p/abot/issues/detail?id=77

实际的修复是...添加了HtmlDocument.OptionMaxNestedChildNodes,可以设置它来防止由大量嵌套标签引起的StackOverflowExceptions。它将抛出一个ApplicationException,并显示消息"Document has more more X not。这很可能是因为页面没有正确结束标记。“

打完补丁后如何使用...

代码语言:javascript
复制
HtmlDocument hapDoc = new HtmlDocument();
hapDoc.OptionMaxNestedChildNodes = 5000;//This is what was added
string rawContent = GETTHECONTENTHERE
try
{
    hapDoc.LoadHtml(RawContent);    
}
catch (Exception e)
{
    //Instead of a stackoverflow exception you should end up here now
    hapDoc.LoadHtml("");
    _logger.Error(e);
}
票数 5
EN

Stack Overflow用户

发布于 2022-01-11 10:31:59

这应该是可行的:

代码语言:javascript
复制
HtmlDocument.MaxDepthLevel = 10000;
var doc = new HtmlDocument();
try
{
    doc.LoadHtml(document);
}
catch(Exception ex)
{
    Console.WriteLine("Exception while loading html: " + ex);
    yield break;
}
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12666282

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档