2014-06-19 18 views
5

Tôi có hai ví dụ. Trong trường hợp đầu tiên, gỡ rối bắt ngoại lệ unhandled:Trường hợp ngoại lệ mất một phần của stacktrace trong bối cảnh try/catch

static void Main(string[] args) { 
    Exec(); 
} 
static void Exec() { 
    throw new Exception(); 
} 

Và ngoại trừ có đầy đủ stacktrace:

at ConsoleApplication28.Program.Exec() 
    at ConsoleApplication28.Program.Main(String[] args) 
    at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
    at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
    at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Threading.ThreadHelper.ThreadStart() 

Trường hợp thứ hai:

static void Main(string[] args) { 
    Exec(); 
} 
static void Exec() { 
    try { 
     throw new Exception(); 
    } 
    catch (Exception ex) { 
    } // Breakpoint 
} 

Tại breakpoint ngoại trừ có ngắn stacktrace:

at ConsoleApplication28.Program.Exec() 

Tại sao stacktraces được cắt theo phương pháp chứa trong trường hợp thứ hai, và làm thế nào để ngăn chặn nó? Tôi cần stacktrace đầy đủ cho bugreports, nếu không nó đôi khi không thể tìm thấy có vấn đề là, mà không có stacktrace đầy đủ.

+0

"Tôi cần stacktrace đầy đủ cho các báo cáo lỗi, nếu không đôi khi không thể tìm thấy vấn đề ở đây, không có stacktrace đầy đủ". Để trả lời một phần câu hỏi của bạn, bạn cần phải chèn cấu trúc try-catch ở đâu đó "ở trên", nơi có thể xảy ra ngoại lệ, có lẽ ngay ở đầu, trong phương thức Main() của bạn. Trong điều khoản bắt, bạn nên viết exceptionObject.ToString() vào một số tệp hoặc một cái gì đó để phân tích sau này. – RenniePet

Trả lời

3

Những gì bạn thấy trong trình gỡ lỗi Visual Studio là ngoại lệ không được xử lý mà quá trình Visual Studio Hosting đang bẫy (nghĩa là mọi thứ sau hai khung ngăn xếp đầu tiên là một phần của VS "máy chủ lưu trữ"). Nếu bạn vô hiệu hóa quá trình lưu trữ (Thuộc tính dự án-> Bật quy trình lưu trữ Visual Studio), bạn sẽ thấy dấu vết ngăn xếp "ngắn" trong cả hai trường hợp (mặc dù bạn sẽ không thấy khung ngăn xếp cho Main trong trường hợp thứ hai của bạn vì ngoại lệ được "xử lý", không được phép lan truyền lên đến Main). Dấu vết ngăn xếp ngắn hơn này là dấu vết ngăn xếp mà bạn sẽ thấy nếu bạn đang chạy ứng dụng bên ngoài trình gỡ rối.

Ngăn xếp hoạt động như bạn tưởng tượng - mỗi lần gọi phương thức đẩy khung ngăn xếp khác lên đó và ở cuối phương thức khung ngăn xếp của nó bị "bật" hoặc bị xóa khỏi ngăn xếp. Dấu vết ngăn xếp mà bạn nhìn thấy trên ngoại lệ bao gồm các khung ngăn xếp từ khung nơi ngoại lệ được ném, trở lại khung nơi ngoại lệ cuối cùng được xử lý, vì ngăn xếp là "không có gì".

+0

Bạn có thể muốn tổ chức lại câu trả lời này để chỉ ra rõ ràng phần nào của dấu vết ngăn xếp là do quá trình lưu trữ và đó là do khối catch. Sau đó, bạn có thể nhấn mạnh rằng các dấu vết ngăn xếp được tổng hợp khi ngoại lệ vượt qua các mức xếp chồng, do đó phần 'Main' chỉ đơn giản là chưa có. –

+0

Nhưng tại sao Main() không nằm trong stacktrace thứ hai? Tôi không hiểu. Tôi đã kiểm tra stacktrace tại điểm ngoại lệ của System.Diagnostics.StackTrace và Main() nằm trong đó. –

+2

Dấu vết ngăn xếp ngoại lệ là theo dõi ngăn xếp đến điểm mà ngoại lệ bị bắt. Rằng ngăn xếp theo dõi phát triển như các trường hợp ngoại lệ bong bóng lên các cấp của ngăn xếp cuộc gọi. Nó cho thấy, "dấu vết ngăn xếp cho đến nay", không phải là "ngăn xếp cuộc gọi trở lại phần đầu của chương trình" là gì. –

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