首页 > 其他分享 >.Net7 CLR的调用函数和编译函数

.Net7 CLR的调用函数和编译函数

时间:2023-03-17 10:11:06浏览次数:45  
标签:libcoreclr 函数 libc frame 调用函数 corerun so Net7 CLR

前言

.Net运行模型,无非就两个过程。一个是调用入口函数,另外一个就是编译入口函数。前者主调用,后者主编译。


概括

一:入口函数:RunMainInternal
所有的.Net程序,包括控制台,Web,窗体等等入口都是Main。而调用这个Main的就是RunMainInternal,从这个函数的名字就可以看出,它的Run就表示是运行Main函数的,而后面的Internal表示是内部的,而非外部所能调用,当然你用一些非常规手段,这个函数还是可以外部的调用的,那是后话。


二:通过LLDB看下它的堆栈

* thread #1, name = 'corerun', stop reason = step over
  * frame #0: 0x00007ffff6d53cdf libcoreclr.so`RunMainInternal
    frame #1: 0x00007ffff6d53c99 libcoreclr.so`RunMain
    frame #2: 0x00007ffff6d4ec76 libcoreclr.so`RunMain
    frame #3: 0x00007ffff6d4ea22 libcoreclr.so`RunMain
    frame #4: 0x00007ffff6d4f030 libcoreclr.so`Assembly::ExecuteMainMethod
    frame #5: 0x00007ffff6dc2b9c libcoreclr.so`CorHost2::ExecuteAssembly
    frame #6: 0x00007ffff6d1a6c1 libcoreclr.so`::coreclr_execute_assembly
    frame #7: 0x000055555556f9f9 corerun`run(config=0x00007fffffffdbc0)
    frame #9: 0x00007ffff7829d90 libc.so.6`__libc_start_call_main
    frame #10: 0x00007ffff7829e40 libc.so.6`__libc_start_main_impl
    frame #11: 0x000055555556c0e5 corerun`_start + 37

可以看到它在Linux平台下面,是通过Glibc OR Newlibc调用的。而它的前面一个函数就是RunMain,这个通过它名字也可以看到它就是运行Main函数的。


三:编译函数PreStubWorker
这个函数顾名思义,预桩工作。就是插桩的意思。每次编译一个函数,都会经过它。它会调用RyuJIT把函数编译成机器码,然后再返回到这个被编译函数的函数头地址运行。
部分代码:

extern "C" PCODE STDCALL PreStubWorker(TransitionBlock* pTransitionBlock, MethodDesc* pMD)
{
    PCODE pbRetVal = NULL;

    BEGIN_PRESERVE_LAST_ERROR;

    STATIC_CONTRACT_THROWS;
    STATIC_CONTRACT_GC_TRIGGERS;
    STATIC_CONTRACT_MODE_ANY;
    STATIC_CONTRACT_ENTRY_POINT;
    // 此处省略一万字
}

可以看到它只是带了一个MethodDesc,也就是函数的描述结构体。通过它可以找到Module,MSIL,然后进行一个编译。


四:看下它的堆栈

 thread #1, name = 'corerun', stop reason = breakpoint 2.1
  * frame #0: 0x00007ffff6ef55d0 libcoreclr.so`::PreStubWorker
    frame #2: 0x00007ffff731e14f libcoreclr.so`CallDescrWorkerInternal
    frame #3: 0x00007ffff6faae98 libcoreclr.so`CallDescrWorkerWithHandler
    frame #4: 0x00007ffff6fabb8d libcoreclr.so`MethodDescCallSite::CallTargetWorker
    frame #5: 0x00007ffff6d2e4b3 libcoreclr.so`MethodDescCallSite::Call
    frame #6: 0x00007ffff6d53f6f libcoreclr.so`RunMainInternal
    frame #7: 0x00007ffff6d53c99 libcoreclr.so`RunMain
    frame #8: 0x00007ffff6d4ec76 libcoreclr.so`RunMain
    frame #9: 0x00007ffff6d4ea22 libcoreclr.so`RunMain
    frame #10: 0x00007ffff6d4f030 libcoreclr.so`Assembly::ExecuteMainMethod
    frame #11: 0x00007ffff6dc2b9c libcoreclr.so`CorHost2::ExecuteAssembly
    frame #12: 0x00007ffff6d1a6c1 libcoreclr.so`::coreclr_execute_assembly
    frame #13: 0x000055555556f9f9 corerun`run(config=0x00007fffffffdbc0) argv=0x00007fffffffddb8) at corerun.cpp:624:21
    frame #15: 0x00007ffff7829d90 libc.so.6`__libc_start_call_main
    frame #16: 0x00007ffff7829e40 libc.so.6`__libc_start_main_impl
    frame #17: 0x000055555556c0e5 corerun`_start + 37

它刚好在RunMainInternal的后面,说明它是在被调用之后,才会进行编译。



结尾

作者:江湖评谈
image

标签:libcoreclr,函数,libc,frame,调用函数,corerun,so,Net7,CLR
From: https://www.cnblogs.com/tangyanzhi1111/p/17222778.html

相关文章

  • Unity中使用Timer实现延迟调用函数
    需求背景在Unity中实现延迟调用函数的方法,据我所知有三种使用协程中的yieldreturn使用Invoke使用DoTween中的Sequence但是如果我想一次性添加多个函数,并且在每个函......
  • .NET7依赖注入 延迟加载模式
    .NET7依赖注入延迟加载模式延迟加载(LazyLoading)模式是指在服务被首次请求时,才对其进行初始化。这种模式可以减少程序启动时间和资源消耗。示例代码如下://MyService类......
  • .NET7依赖注入 装饰器模式
    ##.NET7依赖注入装饰器模式装饰器(Decorator)模式是一种在不改变原始类的情况下增强其功能的模式。在DI中,装饰器模式常用于在不改变原始服务的实现的情况下增强其功能,例......
  • .NET7依赖注入
    依赖注入(DependencyInjection,简称DI)功能,使得应用程序可以更加容易地管理组件之间的依赖关系。在.NET7中,DI是通过Microsoft.Extensions.DependencyInjection命名空......
  • 【大型软件开发】开发日志(五).net框架与C++的融合:CLR——C++调用C#的DLL
    做什么?先说一下场景,现在正在开发一个QtActiveServer,也就是用一个应用程序去向其他的组件暴露接口,以达到提供服务的目的。然后新版的框架要提供大部分功能,也就是要重做大......
  • 【App消息推送】.NET7简单实现个推服务端
     一.添加基础设施1.添加配置实体模型publicclassGetuiConfigOptions{publicstringAppID{get;set;}publicstringAppKey{get;......
  • Java/.Net双平台核心,Jvm和CLR运行异同点
    前言:本篇以.Net7.0.2CLR和OpenJDk19参照,解析下它们各自调用函数的异同。以下为个人理解。概述JDK大约5.9G,CLR大约7.6G,两者相差1.7G左右。root@tang-virtual-mac......
  • CLR Inside Out Large Object Heap Uncovered
    CLRInsideOut LargeObjectHeapUncoveredMaoniStephensContentsTheLargeObjectHeapandtheGCWhenaLargeObjectGetsCollectedLOHPerformanceImplica......
  • 『 再看.NET7』string的进化
    string是开发过程中,使用频度最高的类型之一,所以在构建类型时作了很多处理,如“不可变性”,“保留性”等特点。string的常量是在""引号中进行赋值的。varstr1="......
  • 『 再看.NET7』string的进化
    string是开发过程中,使用频度最高的类型之一,所以在构建类型时作了很多处理,如“不可变性”,“保留性”等特点。string的常量是在""引号中进行赋值的。varstr1="这是......