Exception Handling in VC

Source: Internet
Author: User

When reading chapter 11 of software debugging, I felt that exception handling is very important in VC. In the past, code writing by myself or reading code written by people around me rarely used exception handling, but recently I am exposed to code written by foreigners, exception Handling is provided in almost every key code block, although the Exception Handling Code simply writes information about the exception to the Event Viewer, however, this has already helped us find bugs and understand system running conditions. As a result, I have summarized my learning experience in this chapter for your sharing.

First, let's look at the data structure prediction_record defined by window to describe the exception. The details are as follows:

Typedef struct _ exception_record {

DWORD exceptioncode; // Exception Code

DWORD exceptionflags; // exception flag

Struct _ exception_record * exceptionrecord; // another related exception

PVOID ExceptionAddress; // address where an exception occurs

DWORD NumberParameters; // number of elements in the parameter Array

ULONG_PTR predictioninformation [prediction_maximum_parameters]; // parameter Array

}

We should be very familiar with the ExcptionCode. The most common is prediction_access_violation, with a value of 0xC0000005L, which means illegal access. Most of the Crash problems we encounter come from this.

After learning about the exception structure, let's see how exceptions are distributed:

Exception distribution includes exception distribution in user mode and exception distribution in kernel mode. This section only describes exception distribution in user mode. KiDispatchException is a kernel function that is the hub for distributing windows exceptions. Its function prototype is KiDispatchException (IN PEXCEPTION_RECORD ExceptionRecord,

IN PKEXCEPTION_FRAME ExceptionFrame,

IN PKTRAP_FRAME TrapFrame,

IN KPPROCESSOR_MODE previusmode,

In boolen FirstChange );

The predictionrecord parameter refers to the _ prediction_record structure described above. I will not go into details about other parameters. I will focus on the last parameter FirstChange. I believe that those who have used windbg will always find the FirstChange parameter, in fact, exceptions can be distributed up to two times during the distribution process, which is taken from software debugging and clearly shows the distribution exception process of kiDispatchException. The left side is the user State, and the right side is the kernel state.

As shown in, when the FirstChange variable is TRUE, DbgkForwardException is called and distributed to the debugging subsystem. That is, when a debugger exists, it is distributed to the debugger first, so when we use windbg, we often find the First Change field. If the function DbgForwardException returns FALSE, it means that no debugger is found and DbgkForwardException will be called for the second distribution. This distribution will look for abnormal processing blocks, this is generally the code of the _ exception {} field or the code of the catch {} field. We will discuss it later. If FALSE is returned this time, ZwTerminateThread will be called to terminate the current thread. A dialog box will pop up, containing some exception information, which is also very common. If it appears in the kernel status, a blue screen (BSOD) appears directly ).

The following describes the structured exception processing (SEH) and vectoring Exception Processing (VEH)

From the system perspective, SEH is a general term for exception distribution and handling mechanisms in windows operating systems. Its implementation is distributed across many modules and data structures in windows systems. From the programming point of view, SEH is a set of standards. With this specification, programmers can write processing code to reuse system exception handling facilities. It can be understood as an external interface of the operating system's exception mechanism, that is, how to use the Exception Handling Mechanism of windows in windows programs. (From Page 291 of software debugging)

Structured Exception Handling provides Termination Handling and Exception Handling. Taking VC ++ as an example, the final processing structure is as follows:

_ Try

{

// Protected body

}

_ Finally

{

// Final processing code
}

The purpose of final processing is to execute the code in the protected body. Unless exitthread or exitprocess is called, the final processing code will be executed. The final processing feature is suitable for resource release, including memory release, memory leakage prevention, and status recovery, including signal settings, to avoid deadlocks in multiple threads.

The execution process of final processing needs to be explained. If the code return exists in the protected body, it means to exit the function. How is the final block executed at this time? In fact, the compiler will define a local variable to save the return value, and then call the local expansion function named _ local_unwind2 in and out of the target code to call the Finally block code. Note: keywords with double underscores are defined by the compiler.

The exception handling method is as follows:

_ Try

{

// Protected code block

}

_ Limit T (filter expression)

{

// Exception Handling Block

}

Is it familiar? It is similar to the exception handling of C ++. the try-catch-throw structure of C ++ is as follows:

Try {
// Code that cocould throw an exception
}
[Catch (exception-Declaration ){
// Code that executes when exception-declaration is thrown
// In the try Block
}
[Catch (exception-Declaration ){
// Code that handles another exception type
}]...]
// The following syntax shows a throw expression:
Throw [expression]

I would like to introduce the two characteristics and different details, but by accident found that the predecessors have summarized, it blog address for http://blog.csdn.net/lingqinghua/archive/2005/12/21/558182.aspx

So I will not introduce the differences between seh and C ++. If you are interested, you can directly view his blog.

Now let's look at the filter expression of SEH. This expression can be a constant, conditional operator, comma expression, or other functions. But the result must be 0, 1,-1. The value of prediction_contionue_serarch is 0, indicating that this protection block does not handle this exception and the system will look for other exception handling blocks. The value of prediction_continue_execution is 1. The table type has handled this exception, and the program returns the exception occurrence point to continue execution. In this case, if the exception is not cleared, an exception may occur. This process is highly risky because it is difficult to find a perfect exception solution for the actual problem. Once the exception point is returned and the execution continues, the exception occurs again. Therefore, the VC compiler is not allowed to return prediction_continue_execution. If a return is forcibly returned, an exception occurs in EXECPTION_NONCONTINUABLE_EXCEPTION. The value of prediction_execute_handler is-1. It indicates that this is the expected exception of the protected block. When this exception occurs, the Exception Code of the block will be executed, and the execution will continue. Therefore, you can record the exception information in the exception handling block, including the register information.

Let's take a look at VEH (vectoring structure processing)

The basic idea of VEH is to receive and handle exceptions by registering callback functions. The prototype of the CALLBACK function is long callback VectoredHandler (PEXCEPTION_POINTERS ExceptionInfo );

Two windows API functions, AddVectoredExceptionHandler (ULONG FirstHandler, PVECTORD_EXCEPTION_HANDLER vectoredHandler) and RemoveVectoredExceptionHandler, are used to register and cancel callback functions respectively. The FirstHandler parameter is used to specify the call sequence of the callback function. If it is set to 0, it indicates that the callback function is called at the end. If it is set to 1, it indicates that the callback function is called first. If multiple callback functions are registered and FirstHandler is a non-zero value, the last registered callback function is called first.

For VEH examples, refer to page 304 of software debugging.

Finally, we will summarize the differences between VEH and SEH.

1. SEH can be used in user-state code or kernel-state code. However, VEH can only be used in user-state code. VEH must be used in Versions later than windows XP

2. If both VEH and SEH are registered, VEH takes priority.

3. SEH registration information is stored in the online process stack in a fixed structure, and VEH registration information is stored in the memory heap of the process. This reminds me of a problem. We can manually add VEH information to the process memory. When an exception occurs, VEH code will be executed. Can this destroy some programs. It's just whimsical. Hope you can give me some advice!

4. VEH is effective for the whole process, and SEH is dynamically built on the stack frame of the function, and will be canceled as the function returns.

5. SEH is the data structure and code generated by the compiler during compilation. The registration and cancellation of VEH are both explicitly completed through the system API and flexible ~

Thank you. Most of them are for reference to software debugging. I only have a little bit of experience. I hope I can help some people who are not very familiar with it!

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.