StackOverflowException 해결

html-agility-pack stack-overflow

문제

HtmlAgilityPack을 사용하여 약 200,000 개의 HTML 문서를 구문 분석합니다.

이 문서의 내용을 예측할 수는 없지만 그러한 문서에서는 StackOverflowException 인해 응용 프로그램이 실패하게됩니다. 이 문서에는 다음 HTML이 포함되어 있습니다.

<ol>
    <li><li><li><li><li><li>...
</ol>

이와 같이 중첩 된 약 <li> 요소가 약 10,000 개 있습니다. HtmlAgilityPack이 HTML을 구문 분석하는 방식으로 인해 StackOverflowException 이 발생합니다.

불행히도 StackOverflowException은 .NET 2.0 이상에서는 catch 할 수 없습니다.

스레드의 스택 크기를 더 크게 설정하는 것에 대해 궁금해했지만 스택 크기를 더 크게 설정하면 프로그램이 더 많은 메모리를 사용하게됩니다. (프로그램이 HTML 처리를 위해 약 50 개의 스레드를 시작하므로 모든 스레드 증가 된 스택 크기를 가짐) 비슷한 상황을 다시 겪은 적이 있다면 수동으로 조정해야합니다.

내가 사용할 수있는 다른 해결 방법이 있습니까?

수락 된 답변

이상적으로 장기적인 해결책은 HtmlAgilityPack을 호출 스택 대신 힙 스택을 사용하도록 패치하는 것입니다. 그러나 이것은 나에게 너무 큰 사업 일 것입니다. 일시적으로 CodePlex 계정 세부 정보를 잃어 버렸지 만, 문제가 발생하면 문제 보고서를 제출할 것입니다. 또한이 문제는 HtmlAgilityPack을 사용하여 사용자가 제출 한 HTML을 위생적으로 처리하는 사이트에 서비스 거부 공격 (DoS) 공격 취약점을 나타낼 수 있습니다. 너무 많이 중첩 된 HTML 문서로 인해 w3wp.exe 프로세스가 중지 될 수 있습니다.

그 동안, 최선의 방법은 최대 스레드 스택 크기를 수동으로 무시하는 것입니다. 이전의 성명서에서 스택 크기가 크다는 것은 모든 스레드가 자동으로 메모리를 소비한다는 것을 의미합니다 (메모리 페이지가 늘어날 때마다 스레드 스택에 할당되는 것처럼 보입니다).

나는 <ol><li> 페이지의 복사본을 만들고 몇 가지 실험을했습니다. 스택 크기가 2^21 바이트 미만이지만 2^22 의 최대 크기가 성공했을 때 프로그램이 실패한 것으로 나타났습니다. 4MB이고 내 책에서 "허용되는"해킹으로 넘어갑니다.


인기 답변

나는 당신이 묘사 한 것과 똑같다고 믿는 오류를 패치했습니다. hap 프로젝트 사이트에 패치를 업로드했습니다 ...

http://www.codeplex.com/site/users/view/sjdirect (2012 년 3 월 8 일의 패치 참조)

또는 문제 및 결과에 대한 자세한 문서를 참조하십시오 ....

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

실제 수정은 ... 중첩 된 태그 톤에 의해 발생하는 StackOverflowExceptions을 방지하도록 설정할 수있는 HtmlDocument.OptionMaxNestedChildNodes가 추가되었습니다. "Document가 X 개 이상의 중첩 된 태그를 가지고 있는데, 이는 태그를 제대로 닫지 않은 페이지 때문일 가능성이 큽니다."라는 메시지와 함께 ApplicationException을 발생시킵니다.

패치 후 어떻게 사용하고 있습니까?

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);
}



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.