.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函数是怎么被调用的,怎么传入参数,返回的内容到哪里了,返回的内容是什么?接下来我们 ...
随机推荐
- vim编译器
光标移动,模式切换,删除,查找,复制,粘贴,撤销 vim的三种模式(重点) vim存在的三种模式 命令模式,编辑模式,尾行模式 命令 模式:不能直接编辑.但是可以用快捷键进行一些操作(删除,复制,移动 ...
- selenium 添加特殊配置(如不完整 希望各位大神评论告诉我)
options 常用配置 #添加特殊配置 options=webdriver.ChromeOptions() #设置默认编码为utf-8,也就是中文 options.add_argument('lan ...
- docker+nginx 安装部署修改资源目录配置文件和容器端口信息
查看docker镜像 可以先查看docker下是否存在nginx镜像,使用如下这些命令查看: docker images: 列出所有镜像. docker images nginx: 列出所有nginx ...
- ROS应用层通信协议解析
参考:http://wiki.ros.org/ROS/Master_API http://wiki.ros.org/ROS/Connection Header 说明 ROS本质上就是一个松耦合的通信框 ...
- 为什么标准库的模板变量都是inline的
最近在看标准库里的type_traits的时候发现了个有趣的地方,几乎所有在标准库里的变量模板都是inline的! 不仅常见的实现上(libstdc++.libc++.ms stl)都是inline的 ...
- 【Java SE进阶】Day07 等待与唤醒案例、线程池、Lamdba表达式
一.等待唤醒机制 1.线程间通信 多个线程处理同一个资源,就存在线程通信问题(线程间存在竞争与协作机制) 为什么处理:为了 保证多个线程有规律地完成同一任务 如何处理:避免对共享变量争夺,需要等待唤醒 ...
- 3A锂电池充电管理芯片PW4035
PW4052 是一颗适用于单节锂电池的.具有恒压/恒流充电模式的充电管理 IC.该芯片采用开关型的工作模式, 能够为单节锂电池提供快速. 高效且简单的充电管理解决方案. PW4052 采用三段式充电管 ...
- webflux延迟队列逻辑更改过程记录
title : webflux延迟队列逻辑更改过程记录 author : simonLee date : 2022/11/22 10:26 目录 webflux延迟队列逻辑更改过程记录 一.问题背景 ...
- 什么是NineData?突然就火了
NineData 是集成了 SQL 开发.数据复制.数据备份.数据对比多个模块的云服务,支持混合云(自建库+云数据库的业务架构)和多云(多个不同云厂商数据库组成的业务架构)架构下的企业数据管理,大幅降 ...
- 如何使用Abstract类?抽象类的威力
简介: 今天我想谈谈如何使用抽象类,以及抽象类真正的威力.本文将结合具体业务来说明如何使用抽象类. 业务简述: 本人目前只接触过PMS(物业管理系统),公司主要业务的是美国的租房业务.由于美国租房和中 ...