Страницы

Поиск по вопросам

среда, 25 декабря 2019 г.

Возникновение ошибок в другом домене приложения c#

#c_sharp #cross_domain


Если загрузить сборку приложения в отдельный домен, то в случае появления не обрабатываемых
исключений "Stack overflow exception", повреждения памяти, будет ли главный домен приложения
работать, или он положит весь процесс?
    


Ответы

Ответ 1



Starting with the .NET Framework version 2.0, a StackOverflowException object cannot be caught by a try-catch block and the corresponding process is terminated by default. Consequently, users are advised to write their code to detect and prevent a stack overflow. For example, if your application depends on recursion, use a counter or a state condition to terminate the recursive loop. Note that an application that hosts the common language runtime (CLR) can specify that the CLR unload the application domain where the stack overflow exception occurs and let the corresponding process continue. For more information, see ICLRPolicyManager Interface and Hosting the Common Language Runtime. Начиная с версии 2,0 переполнение стека можно перехватить только если оно брошено пользователем. Получается, что если верить вот этому ответу, то даже переполнение в другом домене убивает процесс, аргументируя это тем, что возможно все место в стеке закончилось и ничего сделать не получится. Есть еще вот такая статья на хабре, где проделываются хаки через WinApi, которые позволяют не умереть процессу, но это рисковое дело... Статья рекомендует так же использовать RuntimeHelpers, например есть такой метод RuntimeHelpers.ProbeForSufficientStack, который проверяет возможность выделения памяти. Еще в 7,2 появились Span и stackallock/trystackalloc, которые позволяют безопасно размещать данные в стеке: Span span; if (CanAllocateOnStack(size)) span = stackalloc byte[size]; else span = new byte[size]; UPD По поводу варианта с отдельным потоком: static void Main(string[] args) { var thread=new Thread(() => { Recursive(); }); try { thread.Start(); while (thread.IsAlive) { } } catch (Exception e) { Console.WriteLine(e); throw; } } static void Recursive() { Recursive(); } Процесс все равно погибает целиком. Вот тут мой вопрос на эту тему. UPD2 Как вариант, можно использовать StackTrace().FrameCount, но если у нас нету доступа к исходникам, то воткнуть его в рекурсию мы не сможем, что бы проверять время от времени и вываливаться на пороге переполнения стека.

Комментариев нет:

Отправить комментарий