软件调试系列:.Net应用程序编译及执行过程

.Net应用程序编译及执行过程

与传统的Windows应用程序相比,.Net应用程序有很多不同的地方,尤其是在编译与执行期间。

首先来看一下编译过程,传统的Windows应用程序会被编译器直接编译成与特定机器相关的本地应用程序,这类程序则只能在特定操作系统及硬件系统上运行,而.Net应用程序在编译时只会被编译成MSIL(中间代码),在运行期间被即时编译成本地指令,从而可达到跨平台的效果,平台则与上层软件完全隔离。

正如先前所说,执行期间MSIL会被编译成本地代码,这有点像解释性编译语言,但却与解释性编译有很大不同,就在于会重用先前编译的本地代码,在每一次执行代码均会查看是否已经编译过,若没有编译成本地代码,则执行一次编译,若编译过,则重用先前的本地代码。

现在通过示例来看看即时编译过程,

测试代码如下:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace Simple

{

    class Program

    {

        class Calc

        {

            public int DataA { get; set; }

            public int DataB { get; set; }

            public int Add()

            {

                return DataA + DataB;

            }

        }

        static void Main(string[] args)

        {

            Calc oCalc = new Calc();

 

            oCalc.Add();

 

        }

    }

}

现在使用Windbg 运行该程序,并在oCalc.Add();前一行设置断点

WARNING: Whitespace at start of path element

WARNING: Path element is empty

CommandLine: E:\test\Simple\Simple\bin\Debug\Simple.exe

Symbol search path is:  ;E:\JustTestProjectE\C3C4项目\软件\pdb;;D:\symbols

Executable search path is: 

ModLoad: 00400000 00408000   Simple.exe

ModLoad: 77ec0000 77ffc000   ntdll.dll

ModLoad: 79000000 7904a000   C:\Windows\SYSTEM32\MSCOREE.DLL

ModLoad: 77de0000 77eb4000   C:\Windows\system32\KERNEL32.dll

ModLoad: 0dce0000 0dd2b000   C:\Windows\system32\KERNELBASE.dll

(52c.1388): Break instruction exception - code 80000003 (first chance)

eax=00000000 ebx=00000000 ecx=0012fb0c edx=77f06194 esi=fffffffe edi=00000000

eip=77f5e99e esp=0012fb28 ebp=0012fb54 iopl=0         nv up ei pl zr na pe nc

cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246

ntdll!LdrpDoDebuggerBreak+0x2c:

77f5e99e cc              int     3

0:000> !mbp Program.cs 24.

The CLR has not yet been initialized in the process.

Breakpoint resolution will be attempted when the CLR is initialized.

0:000> g

ModLoad: 77c60000 77d00000   C:\Windows\system32\ADVAPI32.dll

ModLoad: 6ff50000 6fffc000   C:\Windows\system32\msvcrt.dll

ModLoad: 02b20000 02b39000   C:\Windows\SYSTEM32\sechost.dll

ModLoad: 77bb0000 77c51000   C:\Windows\system32\RPCRT4.dll

ModLoad: 603b0000 60416000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscoreei.dll

ModLoad: 6de20000 6de77000   C:\Windows\system32\SHLWAPI.dll

ModLoad: 77b60000 77bae000   C:\Windows\system32\GDI32.dll

ModLoad: 77d10000 77dd9000   C:\Windows\system32\USER32.dll

ModLoad: 402c0000 402ca000   C:\Windows\system32\LPK.dll

ModLoad: 6f8e0000 6f97d000   C:\Windows\system32\USP10.dll

ModLoad: 41840000 4185f000   C:\Windows\system32\IMM32.DLL

ModLoad: 70990000 70a5c000   C:\Windows\system32\MSCTF.dll

ModLoad: 79140000 797af000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll

ModLoad: 79060000 7911e000   C:\Windows\system32\MSVCR100_CLR0400.dll

(52c.1388): Unknown exception - code 04242420 (first chance)

ModLoad: 79880000 7a642000   C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\d6e053b4e78f3077025a0c035237d5cc\mscorlib.ni.dll

*** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\d6e053b4e78f3077025a0c035237d5cc\mscorlib.ni.dll

ModLoad: 60930000 60940000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\nlssorting.dll

ModLoad: 72540000 7269c000   C:\Windows\system32\ole32.dll

ModLoad: 10000000 1000c000   C:\Windows\system32\CRYPTBASE.dll

*** WARNING: Unable to verify checksum for Simple.exe

ModLoad: 79810000 79870000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll

Breakpoint: JIT notification received for method Simple.Program.Main(System.String[]) in AppDomain 005f1ab0.

Breakpoint set at Simple.Program.Main(System.String[]) in AppDomain 005f1ab0.

Breakpoint 1 hit

eax=02b4b1f8 ebx=00000000 ecx=02b4b1f8 edx=00629758 esi=00629758 edi=0012f410

eip=003c00a9 esp=0012f3d8 ebp=0012f3e4 iopl=0         nv up ei pl zr na pe nc

cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246

003c00a9 8b4df8          mov     ecx,dword ptr [ebp-8] ss:0023:0012f3dc=02b4b1f8

显示当前调用栈各帧局部变量

0:000> !clrstack -a -n

OS Thread Id: 0x1388 (0)

Child SP IP       Call Site

0012f3d8 003c00a9 Simple.Program.Main(System.String[])

    PARAMETERS:

        args (0x0012f3e0) = 0x02b4b1e8

    LOCALS:

        0x0012f3dc = 0x02b4b1f8

0012f610 791421bb [GCFrame: 0012f610] 

接下来查看类Simple的方法表:

0:000> dd 0x02b4b1f8

02b4b1f8  003538d0 00000000 00000000 00000000

02b4b208  00000000 00000000 00000000 00000000

02b4b218  00000000 00000000 00000000 00000000

02b4b228  00000000 00000000 00000000 00000000

02b4b238  00000000 00000000 00000000 00000000

02b4b248  00000000 00000000 00000000 00000000

02b4b258  00000000 00000000 00000000 00000000

02b4b268  00000000 00000000 00000000 00000000

0:000> !dumpmt -md 003538d0 

EEClass:      00351494

Module:       00352ea4

Name:         Simple.Program+Calc

mdToken:      02000003

File:         E:\test\Simple\Simple\bin\Debug\Simple.exe

BaseSize:        0x10

ComponentSize:   0x0

Slots in VTable: 10

Number of IFaces in IFaceMap: 0

--------------------------------------

MethodDesc Table

   Entry MethodDesc      JIT Name

79aaa790   79884cd8   PreJIT System.Object.ToString()

79aae290   79884ce0   PreJIT System.Object.Equals(System.Object)

79aae1a0   79884d00   PreJIT System.Object.GetHashCode()

79b317b0   79884d14   PreJIT System.Object.Finalize()

003c00d0   003538c8      JIT Simple.Program+Calc..ctor()

0035c03d   0035388c     NONE Simple.Program+Calc.get_DataA()

0035c041   00353898     NONE Simple.Program+Calc.set_DataA(Int32)

0035c045   003538a4     NONE Simple.Program+Calc.get_DataB()

0035c049   003538b0     NONE Simple.Program+Calc.set_DataB(Int32)

0035c04d   003538bc     NONE Simple.Program+Calc.Add()

很明显地看到未调用的函数标置为 NONE,未被编译成本地语言,而被执行过的代码如Simple.Program+Calc..ctor()构造函数已经设置为 JIT,表示已经被编译成本地语言, PerJIT表示为预编译

 

cuiweican
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值