因此 .NET Core 的运行时支持根据对象中间的地址找到对象的开始地址 (在前几年已经实现了)
很久没有写过 .NET Core 相关的文章了,目前关店在家休息所以有些时间写一篇新的??。此次的文章主要介绍如安在 Linux 上编译调试最新的 .NET Core 5.0 Preview 与简单分析 Span 的实现道理。微软从 .NET Core 5.0 开始把 GIT 货仓 coreclr 与 corefx 合并移动到了 runtime 货仓,原有货仓仅用于维护 .NET Core 3.x,你可以从以下地点检察最新的源代码:
https://github.com/dotnet/runtime
为了便利重现,接下来的编译调试会使用 docker 与 ubuntu 18.04 镜像(尽管微软供给了编译专用的镜像但并不适合调试分析),法式会与之前的博客介绍的 1.1,册本介绍的 2.1 有一些差别。
如果你感受阅读这篇文章有困难,可以参考我之前颁布的 .NET Core 源代码分析系列或者册本《.NET Core 底层入门》,册本的采办链接在文章最后。
编译 .NET Core 5.0 Preview本文编译的版本是 0d607a757372e3ecc8e942141d7f586a98694e42
创建 docker 容器执行以下命令即可创建一个 ubuntu 18.04 的 docker 容器,注意创建时需要使用 --privileged 参数,否则无法使用 lldb 或者 gdb 调试措施。
docker run -it --privileged ubuntu:18.04 安置 cmake.NET Core 5.0 要求的 cmake 版本非常高,我们需要添加第三方源来安置新版本的 cmake:
apt-get update apt-get install apt-transport-https ca-certificates gnupg software-properties-common wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | apt-key add - apt-add-repository 'deb https://apt.kitware.com/ubuntu/ bionic main' apt-get update 安置依赖的类库与工具这个法式与之前版本的 .NET Core 不异:
apt-get install git wget locales locales-all vim apt-get install cmake llvm-3.9 clang-9 libunwind8 libunwind8-dev gettext libicu-dev liblttng-ust-dev libcurl4-openssl-dev libssl-dev libnuma-dev libkrb5-dev 下载 .NET Core 源代码并编译这个法式也与之前的 .NET Core 不异,但因为 corefx 合并到了同一个货仓中,执行以下法式以后会同时编译 corefx 的 dll 文件。注意这个法式编译的是 Debug 版本的运行时,便利后面的调试。
git clone https://github.com/dotnet/runtime cd runtime ./build.sh编译完成后你可以在 artifacts 文件夹下找到编译功效。
使用 .NET Core 5.0 Preview 执行 Hello World 措施接下来我们会看如何使用本身编译的 .NET Core 执行一个 Hello World 措施,.NET Core 5.0 会同时编译出 dotnet 措施,我们可以使用它取代 corerun 来简化运行法式(不需要像以前的版本一样手动复制 corefx 的 dll或者设置 CORE_ROOT 环境变量)。但因为 runtime 货仓中不包孕 sdk(sdk 在 sdk 货仓中,此次懒得编译),我们仍然需要此外安置一个官方的 .NET Core 用于创建与编译 Hello World 措施。
安置官方的 .NET Core 3.1 SDK wget -q https://packages.microsoft.com/config/ubuntu/19.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb dpkg -i packages-microsoft-prod.deb apt-get update apt-get install dotnet-sdk-3.1 创建与编译 Hello World 措施 mkdir /console cd /console dotnet new console dotnet build 执行 Hello World 措施因为使用了 .NET Core 3.1 的 SDK 编译,我们还需要改削 措施名.runtimeconfig.json 中的运行时版本号,否则会呈现版本号不一致而执行掉败的问题。
cd /console/bin/Debug/netcoreapp3.1 vi console.runtimeconfig.json需要改削两处:
runtimeOptions.tfm 改削到 netcoreapp5.0
runtimeOptions.framework.version 改削到 5.0.0
改削完以后使用以下命令即可执行:
/runtime/artifacts/bin/testhost/netcoreapp5.0-Linux-Debug-x64/dotnet console.dll如果看到 Hello World 输出就代表执行告成了。
调试 .NET Core 5.0 Preview在 linux 上调试 .NET Core 一般使用 lldb (gdb 也可以但是没有 SOS 插件撑持),SOS 插件的源代码被搬到了 diagnostics 货仓,所以我们还需要下载编译这个货仓的源代码。
下载编译 diagnostics 货仓 (LLDB SOS 插件)安置 LLDB 与 LLDB 的开发文件:
apt-get install clang llvm lldb liblldb-3.9-dev下载编译 diagnostics 货仓:
git clone https://github.com/dotnet/diagnostics cd diagnostics ./build.sh编译告成后你可以在 /diagnostics/artifacts/bin/Linux.x64.Debug/libsosplugin.so 找到 SOS 插件的 dll 文件。
使用 LLDB 调试 .NET CoreSOS 插件需要在执行达到 LoadLibraryExW 后才可以正常使用,使用 LLDB 的 -o 参数可以省略每次调试的时候都要做的筹备事情:
cd /console/bin/Debug/netcoreapp3.1 lldb -o "plugin load /diagnostics/artifacts/bin/Linux.x64.Debug/libsosplugin.so" -o "process launch -s" -o "process handle -s false SIGUSR1 SIGUSR2" -o "b LoadLibraryExW" -o "c" -o "br del 1" -o "sos Help" /runtime/artifacts/bin/testhost/netcoreapp5.0-Linux-Debug-x64/dotnet console.dll执行以后会停在 LoadLibraryExW 并打印出 SOS 插件的辅佐,接下来我们可以使用 SOS 插件给托管函数下断点:
sos bpmd console.dll console.Program.Main然后使用 c 命令继续执行措施,直到触发断点:
c达到断点(JIT 编译后的托管函数 Main)以后我们可以使用 SOS 插件打印这个托管函数编译出来的汇编内容:
sos u $rip如果到此都没有问题,那么接下来我们可以开始分析 Span 的实现道理了。
Span 与 Memory 简介温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/web/30371.html