2011-09-20 42 views
5

Nếu tôi viết những dòng này:Tại sao .NET không ghi nhật ký ngăn xếp cho các ngoại lệ StackOverflow?

class Program 
{ 
    static void Main(string[] args) 
    { 
     throw new Exception("lol"); 
    } 
} 

và chạy exe từ dòng lệnh, tôi nhận được hai mục trong bản ghi sự kiện của tôi. Một là một lỗi ứng dụng cho biết có một ngoại lệ chưa được xử lý, và phần còn lại chứa dấu vết stack với nguồn như .NET Runtime.

Nếu tôi viết những dòng này:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Recurse4Evr(); 
    } 

    static void Recurse4Evr() 
    { 
     Recurse4Evr(); 
    } 
} 

tôi chỉ nhận được một mục trong bản ghi sự kiện của tôi, mà nói Lỗi Ứng dụng và rằng có một ngoại lệ stack overflow. Không có mục nhập thứ hai với dấu vết ngăn xếp, do đó, nó về cơ bản vô dụng.

Tại sao dấu vết ngăn xếp cũng không được ghi lại? Nếu tôi thiết lập DebugDiag và đính kèm nó vào quá trình của tôi và sau đó có một tràn ngăn xếp, DebugDiag có thể đăng nhập theo dõi ngăn xếp. Rõ ràng là dấu vết ngăn xếp có sẵn cho thế giới bên ngoài theo một cách nào đó. Nếu thời gian chạy là chấm dứt quá trình bởi vì nó phát hiện một stackoverflow, sau đó nó cũng biết những gì ngăn xếp được.

Trong các ứng dụng lớn có nhiều tương tác phức tạp, thường không thể tạo lại các điều kiện dẫn đến tràn ngăn xếp. Trong tình huống này, một dấu vết ngăn xếp là cách duy nhất để tìm ra những gì đã xảy ra. Tại sao microsoft quyết định không quan trọng để đăng nhập thông tin này? Có một quyết định thiết kế hợp pháp nào không rõ ràng không?

+4

Dự đoán của tôi là tạo ra ngăn xếp theo dõi trong quá trình yêu cầu các cuộc gọi chức năng, không thể hoạt động vì ngăn xếp tràn. Trình gỡ lỗi nhận được xung quanh điều này bằng cách có thể đi bộ ngăn xếp bằng cách sử dụng cấu trúc dữ liệu của riêng mình và (hy vọng) ngăn xếp lành mạnh. – siride

+0

Đây là một câu hỏi tuyệt vời! Tôi tự hỏi nếu nó đã làm với cách tràn ngăn xếp được phát hiện ... Sau. Net 2.0, nó có vẻ như là mặc dù bạn cũng không thể bắt nó, hoặc, vì vậy nó có vẻ như là mặc dù nó chơi bởi một bộ đặc biệt của các quy tắc. –

+0

bản sao có thể có của [C# bắt ngoại lệ tràn ngăn xếp] (http://stackoverflow.com/questions/1599219/c-catch-a-stack-overflow-exception) – balexandre

Trả lời

0

Điều này rõ ràng là không thể. Nếu bạn muốn một dấu vết ngăn xếp để bạn có thể tìm thấy mã vi phạm đã giết chết ứng dụng của bạn, bạn cần đính kèm một công cụ của bên thứ 3 như DebugDiag hoặc AdsPlus. Chúc may mắn, về cơ bản không có tài liệu cho những công cụ này.

1

Tràn ngăn xếp được coi là tình huống không thể khôi phục và thời gian chạy như vậy sẽ giết chết quá trình.

để tổng hợp:

from Damien_The_Unbeliever

Từ trang MSDN trên StackOverflowException s:

Trong các phiên bản trước của .NET Framework, ứng dụng của bạn có thể bắt một đối tượng StackOverflowException (ví dụ, để phục hồi từ đệ quy không bị chặn). Tuy nhiên, thực tế đó hiện không được khuyến khích vì mã bổ sung quan trọng được yêu cầu để bắt được một ngoại lệ tràn ngăn xếp đáng tin cậy và tiếp tục thực hiện chương trình.

Bắt đầu với .NET Framework phiên bản 2.0, một đối tượng StackOverflowException không thể bị chặn bởi khối try-catch và quá trình tương ứng được kết thúc theo mặc định. Do đó, người dùng nên viết mã của họ để phát hiện và ngăn chặn tràn ngăn xếp. Ví dụ, nếu ứng dụng của bạn phụ thuộc vào đệ quy, hãy sử dụng bộ đếm hoặc điều kiện trạng thái để chấm dứt vòng lặp đệ quy. Lưu ý rằng một ứng dụng lưu trữ thời gian chạy ngôn ngữ chung (CLR) có thể chỉ định rằng CLR dỡ bỏ miền ứng dụng nơi xảy ra tràn ngăn xếp ngăn xếp và để cho quá trình tương ứng tiếp tục. Để biết thêm thông tin, hãy xem Giao diện ICLRPolicyManager và Lưu trữ Thời gian chạy ngôn ngữ chung.


from JaredPar

Bắt đầu với 2,0 một ngoại lệ StackOverflow chỉ có thể được bắt gặp trong các trường hợp sau đây.

  1. Các CLR đang được chạy trong một môi trường tổ chức nơi chủ nhà đặc biệt cho phép ngoại lệ StackOverflow để được xử lý
  2. Ngoại lệ stackoverflow được ném theo mã người sử dụng và không phải do một tình huống thực tế stack overflow (Reference)
+0

Tôi không cố bắt nó. Tôi hỏi tại sao khi chương trình của bạn chấm dứt và nhật ký thời gian chạy có lỗi trong nhật ký sự kiện, tại sao nó không bao gồm dấu vết ngăn xếp. – dan

+0

cũng vậy, tôi nghĩ rằng "lời khuyên" của microsoft rất đơn giản. chắc chắn, nó có ý nghĩa cho các thuật toán đệ quy - tất nhiên bạn nên viết fibonacci theo cách lặp đi lặp lại. trường hợp của tôi không phải là một thuật toán đệ quy, đã xảy ra lỗi trong trình ghi nhật ký trong trình xử lý sự kiện ngoại lệ của tôi. logger đã ném, và sau đó xử lý sự kiện đã được kích hoạt một lần nữa, nó ném một lần nữa, vv Tôi chỉ có thể tìm thấy những gì gây ra tràn bằng cách sử dụng DebugDiag. Lời khuyên của microsoft về cơ bản là "không viết mã có lỗi". – dan

Các vấn đề liên quan