فرض کنید که از یک برنامهی native ویندوز برای تهیه تصاویر سایتها در یک برنامهی وب استفاده میکنید و صبح که به سایت سر زدهاید پیام در دسترس نبودن سایت قابل مشاهده است. مشکل از کجا است؟!
یک مثال ساده
برنامهی کنسول فوق را پس از فعال سازی Allow unsafe code در قسمت تنظیمات پروژه، کامپایل کرده و سپس آنرا خارج از VS.NET اجرا کنید. احتمالا انتظار دارید که قسمت catch این کد حداقل اجرا شود و سپس سطر «کلیدی را فشار دهید» ظاهر گردد. اما ... خیر! کل پروسه کرش کرده و هیچ پیام خطایی را دریافت نخواهید کرد. اگر به لاگهای ویندوز مراجعه کنید پیام زیر قابل مشاهده است:
و این نوع مسایل هنگام کار با کتابخانههای C و ++C زیاد ممکن است رخ دهند. نمونهی آن استفاده از WebControl دات نت است یا هر برنامهی native دیگری. در این حالت اگر برنامهی شما یک برنامهی وب باشد، عملا سایت از کار افتادهاست. به عبارتی پروسهی ویندوزی آن کرش کرده و بلافاصله از طرف ویندوز خاتمه یافته است.
چرا قسمت catch اجرا نشد؟
از دات نت 4 به بعد، زمانیکه دسترسی غیرمجازی به حافظه صورت گیرد، برای مثال دسترسی به یک pointer آزاد شده، استثنای حاصل، توسط برنامه catch نشده و اجازه داده میشود تا برنامه کلا کرش کند. به این نوع استثناءها Corrupted State Exceptions یا CSE گفته میشود. اگر نیاز به مدیریت آنها توسط برنامه باشد، باید به یکی از دو طریق زیر عمل کرد:
الف) از ویژگی HandleProcessCorruptedStateExceptions بر روی متد فراخوان کتابخانهی native باید استفاده شود. برای مثال در کدهای فوق خواهیم داشت:
ب) و یا فایل کانفیگ برنامه را ویرایش کرده و چند سطر ذیل را به آن اضافه کنید:
در این حالت مدیریت اینگونه خطاها در کل برنامه همانند برنامههای تا دات نت 3.5 خواهد شد.
یک مثال ساده
using System; namespace AccessViolationExceptionSample { class Program { private static unsafe void AccessViolation() { byte b = *(byte*)(8762765876); } static void Main(string[] args) { try { AccessViolation(); } catch (Exception ex) { Console.WriteLine(ex); } Console.WriteLine("Press a key..."); Console.ReadKey(); } } }
System.AccessViolationException. Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
چرا قسمت catch اجرا نشد؟
از دات نت 4 به بعد، زمانیکه دسترسی غیرمجازی به حافظه صورت گیرد، برای مثال دسترسی به یک pointer آزاد شده، استثنای حاصل، توسط برنامه catch نشده و اجازه داده میشود تا برنامه کلا کرش کند. به این نوع استثناءها Corrupted State Exceptions یا CSE گفته میشود. اگر نیاز به مدیریت آنها توسط برنامه باشد، باید به یکی از دو طریق زیر عمل کرد:
الف) از ویژگی HandleProcessCorruptedStateExceptions بر روی متد فراخوان کتابخانهی native باید استفاده شود. برای مثال در کدهای فوق خواهیم داشت:
[HandleProcessCorruptedStateExceptions] static void Main(string[] args) {
<?xml version="1.0" encoding="utf-8" ?> <configuration> <runtime> <legacyCorruptedStateExceptionsPolicy enabled="true" /> </runtime> </configuration>