Windows Phone App dump file instance analysis-System. ExecutionEngineException,

Source: Internet
Author: User

Windows Phone App dump file instance analysis-System. ExecutionEngineException,
Preface

Before starting this article, let's talk about how to find the correct exception context address from the Dump of the highly optimized Release version, and manually recover the first scene of the exception.

1. What is the exception context?

In a windows operating system, each thread has its own thread context to save the required information, including the value of the current Register. The exception context we need to find here is the value of the current Register (also called the register context) that the exception distributor saves for us when an exception occurs. This information is combined with the analysis of the assembly code, we can further find the cause of the exception. We can find the definition of the register context struct in winnt. h. We will not explain it here.

2. in Windbg, the cxr + Context Address command can help us recover the first-hand information of the register when an exception occurs, so we only need to find the Address of this Context and then we can submit it to this command for processing.

3. How do I find the address for saving the context?

When we use windbg to open the dump file, we will see the call stack mode similar to the following:

This official exception distributor is helping us save the context. Let's take a look at the RtlDispatchException function declaration. Here we use the "x" command:

As you can see, the second parameter of this function is the context address we are looking.

4. With this context address, we can use the ". cxr" command to restore it. The second parameter is 00c2e168. Run the ". cxr 00c2e168" command.

5. Is this value true? Restored the context when an exception occurred. Let's take a look at the changes in the call stack.

The value of this stack and register looks so strange that we have doubts about the above address!

6. think about it. The dump file comes from the Release version App. the compiler will perform a lot of optimization in the executable file that generates the release version, in this case, function calls use our registers to transmit parameters to the maximum extent, instead of @ esp + 0x? . Now let's go back to RtlDispatchException and check it again.

7. Use ". frame + index" to jump to the stack frame specified in the call stack, and run the "dv" command to view local variables.

This time, we can clearly see the content in registers r6 and r9, which is exactly the result of code optimization. The compiler optimized the code by using the r6 and r9 registers instead of the "Stack operation" for passing parameters.

8. Use ". cxr" and "k" again. This time we can see the first scene of a real exception.

It turns out that ldr commands attempt to load an empty address, causing problems.

Now we have learned how to identify the correct context address in the highly optimized release version. Next we will continue to look for the cause of program crash.

Locate exception Context

1. We have found the real exception context. Let's take a look at this call stack.

2. Let's take a look at the FontFileReference: What did ReleaseFragment do? Use the command "uf Module name! Function Name "to decompile this function.

3. view the content in the stack frame corresponding to this function again to help us understand the assembly code above, ". frame + frame index"

4. Run the "dt Module name" command! Class Name to view the FontFileReference memory Layout

Analysis and speculation

1. from the call stack, we can see that the following statement triggers an exception. The command here is loading the Register. The address stored in the load r3 register, but r3 = 0. We can't help but ask, why is r3 0, and what should it be in r3?

2. Key Analysis register, r3. Here, I would like to share with you my experiences in Reading Assembly commands. In fact, we don't use every line of analysis every time. The simple method is to find the key commands! In this case, I listed the following commands as key commands:

Why do we need to take these lines as key commands? This is because "r0, #0x10" and blx appear here. Here, "r0, #0x10" indicates "r0 + 0x10", and "blx" indicates calling subfunctions. Combined with the structure of the FontFileReference class, we can reasonably guess that the address in r0 should point to the this pointer, so r0 + 0x10 is the member variable "stream _" in the FontFileReference class _".

We already know that r0 contains the this pointer, and r3 points to the COM Object stream _ Of The ComPtr <IDWriteFontFileStream> type. So what about r3 + 0x10, the definition of IDWriteFontFileStream can be found in dwrite. you can also use "dt/v" to display it in h.

We know that the first three functions of the COM interface inherited from IUnknown must be QueryInterfacy, Release, and AddRef. Then r3 + 0x10 is the ReleaseFileFragment function. The layout is roughly as follows:

Here, we need to explain why we need to make a "Guess" instead of directly calling the "dt this" command to directly view the current FontFileReference object? Because this dump is generated in the release version, a lot of information is invalid:

3. After the above analysis, we know that the main task of this assembly code is to call "stream _-> ReleaseFileFragement ". Comparison "! The information provided by the analyze-v command can be used to verify our guesses and draw a conclusion. It is precisely because the variable stream _ is null that causes an exception. Let's take a look at the useful information in this thread heap:

Analyze and locate our source code

The residual information in the stack also points to the content related to Font and FontFamily. From the native callstack, we cannot locate our code. This is used here "! CLRStack command to see the call information in our CLR code Stack:

The code of the red line is our own code. Open the code and check it:

From this code, we did not specify the FontFamily attribute when creating the TextBlock dynamically. This exception does not occur when programmers develop code and test. From the excel file we downloaded, this exception only occurs on the WP8.0 platform, in the past 30 days, the total number of flashback events is 4000. This number of times is very small compared to our APP activity. Therefore, we can infer that this bug should be a system problem. It is likely that the ref count increase or decrease operation of stream _ COM object occurs in some special situations where FontFamily is not specified, it causes stream _ to be released in advance. Since it is a system problem, what can we do? First, we can specify a FontFamily to block the control TextBlock. Second, add a try catch on the Render call in the CreateWideTileBackgroundImage function to capture the "System. ExecutionEngineException".

Summary

Although sometimes the problem is caused by the system, through analysis, we can still take some measures to deal with it in our code.

Related Article

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.