.Net7运行模型之托管Main函数的调用
前言:
.Net7的CLR最具特色的一个地方,就是运行模型。因为它主宰了整个CLR的运行过程。
又因为其庞大的代码量,有的几十万行甚至百万行。所以理解起来非常不容易。本篇拆分来看下,里面一个细节Main函数(注意这里的Main指的是托管Main,因为还有非托管main,所以特别指出下以免混淆)是如何被CLR调用的。
概括
Main函数的调用,基本上是最后才会被CLR引擎所调用。为啥?因为,如果.Net标准类库,以及底层的非托管C++类库没有在Main函数被调用之前,加载完成,那么你强行调用Main函数就会出错。
我们可以在Windows/Linux平台通过Windbg或者是LLDB来看下托管的Main函数的堆栈
00007ff7f55703b0
coreclr.dll!CallDescrWorkerInternal
coreclr.dll!CallDescrWorkerWithHandler
coreclr.dll!MethodDescCallSite::CallTargetWorker
coreclr.dll!MethodDescCallSite::Call C++
coreclr.dll!RunMainInternal C++
coreclr.dll!``RunMain'::`30'
coreclr.dll!`RunMain'::`30'
coreclr.dll!RunMain C++
coreclr.dll!Assembly::ExecuteMainMethod
coreclr.dll!CorHost2::ExecuteAssembly
coreclr.dll!coreclr_execute_assembly C++
corerun.exe!run C++
corerun.exe!wmain C++
corerun.exe!invoke_main C++
corerun.exe!__scrt_common_main_seh C++
corerun.exe!__scrt_common_main C++
corerun.exe!wmainCRTStartup C++
kernel32.dll!BaseThreadInitThunk
ntdll.dll!RtlUserThreadStart
这个堆栈里面我们可以得出很多的信息:
比如:
1.最上面的地址:00007ff7f55703b0是.Net里面的托管Main函数的入口地址。
2.整个程序的运行最开始的代码是ntdll.dll模块里面的RtlUserThreadStart函数。
3.非托管的CLR的入口是wmain函数。
有了以上的信息,我们很容易分析到。托管的Main函数调用是在程序集的ExecuteMainMethod函数里面调用RunMain这个函数,整个函数的名字一看就知道是运行Main函数的。
此后通过CallDescrWorkerInternal来调用RyuJIT编译MSIL代码为机器码。返回到托管Main函数的开头地址。
也就是上面的这个地址:00007ff7f55703b0
分析:
这个过程看似分析非常简单,但是实际上会遇到很多问题。但是如果你只用单一的调试器,比如只用Windbg。你可能完全看不出来以下这些问题。
比如你在调试.Ctor,也就是.Net 7里面默认的构造函数的时候。如果在VS上Debug CLR上面,如果进入到托管Main的机器码当中,运行到.Ctor的机器码的地方。它会报一个不是错误的错误,而跟踪下来居然是MapViewOfFile这个微软的官方函数的错误,关于这一点可以看这里,之前写的一篇文章:点击这里查看之前文章
而另外如果你在Linux上面用LLDB调试的时候,会发现托管的Main入口断点可能会进不去的情况。
当然这些类似Bug但可能不是Bug东西,需要深厚的功力去发现和验证它到底是啥。
结尾:
作者:江湖评谈
欢迎关注我,带你了解.Net7的CLR的各种奇巧淫技。让.Net7,甚至后面的.Net8,9,10。在你面前毫无神秘可言。
.Net7运行模型之托管Main函数的调用的更多相关文章
- VS2010-如何建立并运行多个含有main函数的文件
一.先说两个概念,解决方案与工程 在VS2010中,工程都是在解决方案管理之下的.一个解决方案可以管理多个工程,可以把解决方案理解为多个有关系或者没有关系的工程的集合. 每个应用程序都作为一个工程来处 ...
- java中main函数怎么调用外部非static方法
使用外部方法时(不管是static还是非static),都要先new一个对象,才能使用该对象的方法. 举例如下: 测试函数(这是错误的): public class Test { public sta ...
- java 运行指定类的main函数
运行jar文件的方法是: java -jar xxx.jar 但是有时,我们希望运行里面的具体某个类,这时可以通过: java -cp xxx.jar xxx.com.xxxx 它会找到这个类的ma ...
- python+unnitest时运行后不执行main函数里面的内容
1.使用工具pycharm运行unnitest程序遇到的问题 1) 问题:运行后无法生成报告:经print()发现未执行main函数里的内容 2) 原因:使用unnitest测试框架,pycharm运 ...
- Java中main函数只能调用同类中的静态方法?
如果想调用本类中的非静态方法可以这么来写: public class TT{ public static void main(String[] args){ TT t = new TT(); t.fu ...
- C# Main函数中调用异步方法的2种实现
As you discovered, in VS11 the compiler will disallow an async Main method. This was allowed (but ne ...
- main函数如何调用文件外的函数
- 为什么c程序里一定要写main函数
一. 学习过程 编写程序f.c: 对其进行编译,正常通过,再对其进行连接,出现错误: 显示的出错信息为: 翻译成中文是:在c0s模块没有定义符号’_main’. 那么这个错误信息可能与文件c0s.ob ...
- main函数的参数argc和argv
版权声明:本文为博主原创文章,转载请注明CSDN博客源地址!共同学习,一起进步~ https://blog.csdn.net/Eastmount/article/details/20413773 该篇 ...
- c语言中的main函数讨论
**从刚开始写C程序,相比大家便开始写main()了.虽然无数的教科书和老师告诉我们main是程序的入口.那么main函数是怎么被调用的,怎么传入参数,返回的内容到哪里了,返回的内容是什么?接下来我们 ...
随机推荐
- C#一个16进制数用二进制数表示是几位?
1个字节是8位,二进制8位:xxxxxxxx 范围从00000000-11111111,表示0到255.一位16进制数(用二进制表示是xxxx) 最多只表示到15(即对应16进制的F),要表示到255 ...
- ElasticSearch深度分页详解
1 前言 ElasticSearch是一个实时的分布式搜索与分析引擎,常用于大量非结构化数据的存储和快速检索场景,具有很强的扩展性.纵使其有诸多优点,在搜索领域远超关系型数据库,但依然存在与关系型数据 ...
- 【红队技巧】Windows存储的密码获取
[红队技巧]Windows存储的密码获取 免责声明: 使用前提 支持版本 利用方式 参考: 免责声明: 本文章仅供学习和研究使用,严禁使用该文章内容对互联网其他应用进行非法操作,若将其用于非法目的,所 ...
- Go语言核心36讲50
作为拾遗的部分,今天我们来讲讲与Go程序性能分析有关的基础知识. Go语言为程序开发者们提供了丰富的性能分析API,和非常好用的标准工具.这些API主要存在于: runtime/pprof: net/ ...
- IPV4地址详解
在互联网时代,相信会上网的人应该对IP地址都不是很陌生.就像我们每个人都有一个身份证号码一样,网络里的每个终端都使用一个IP地址用于标示自己.那么你知道哪些是保留地址?哪些是特殊地址吗? 一.保留地址 ...
- SpringCloud(十一)- 秒杀 抢购
1.流程图 1.1 数据预热 1.2 抢购 1.3 生成订单 (发送订单消息) 1.4 订单入库 (监听 消费订单消息) 1.5 查看订单状态 1.6 支付 (获取支付链接 ) 1.7 支付成功 微信 ...
- python实现AES加密解密
1. 前言 AES是一种对称加密,所谓对称加密就是加密与解密使用的秘钥是一个. 之前写过一片关于python AES加密解密的文章,但是这里面细节实在很多,这次我从 参数类型.加密模式.编码模式.补全 ...
- jmeter中下一接口依赖上一接口的参数,上一个接口存在分页时,如何在下一接口循环读取上一接口的数据?
问题背景: 工作中性能测试存在接口数据依赖,B接口依赖A接口的数据,希望提取到A接口的数据,传入到B接口,但是A接口存在分页的情况. 如何保证A接口返回的数据未知,且每次从A接口传给B接口的数据不重复 ...
- day17 MySQL的安装 & 数据库基本语法——增删改查
day17 MySQL 登录数据库 mysql -h localhost -P 3307 -u root -p 查看所有数据库 show databases; 退出数据库 exit; //现有表格 u ...
- 从一个 issue 出发,带你玩图数据库 NebulaGraph 内核开发
如何 build NebulaGraph?如何为 NebulaGraph 内核做贡献?即便是新手也能快速上手,从本文作为切入点就够了. NebulaGraph 的架构简介 为了方便对 NebulaGr ...