第1章 .NET Core基础知识 1
1.1 .NET Core到底是什么 1
1.1.1 从软件许可协议说开源 1
1.1.2 构成.NET Core的重要组件 2
1.2.NET Standard又是什么 5
1.3.NET Core的一些重要工具 6
1.4 常见问题解答 9
第2章 .NET Core的编译 10
2.1.NET Core源代码在Linux操作系统上的编译 10
2.1.1 获取.NETCore源代码 10
2.1.2 安装编译源代码必要的工具 11
2.1.3 在CentOS上手工编译LLVM、Clang和LLDB 13
2.1.4 在Linux上编译.NET Core源代码 16
2.2.NET Core源代码在Windows操作系统上的编译 18
2.2.1 下载和安装Visual Studio 18
2.2.2 安装其他必备软件 19
2.2.3 在Windows系统上执行.NETCore编译 20
2.3.NET Core源代码在macOS操作系统上的编译 20
第3章 .NET Core命令行工具 23
3.1 .NET Core CLI的安装 23
3.2 创建.NET Core项目 23
3.3.NETCore项目的迁移 25
3.4 .NET Core项目的构建 26
3.5.NET Core项目的发布 29
3.6 对.NET Core项目进行管理 30
3.6.1 dotnet sln命令介绍 30
3.6.2 项目之间的引用管理 31
3.6.3 项目的包管理 32
3.6.4 项目引用NuGet包的恢复 32
3.7 .NETCore应用的执行 33
3.8 将.NETCore项目发布成NuGet包 33
3.8.1 dotnet pack命令介绍 34
3.8.2 dotnet nuget push命令介绍 34
3.8.3 dotnet nuget locals命令介绍 35
3.8.4 dotnet nuget delete命令介绍 36
3.9 dotnet相关命令的使用 36
3.9.1 创建解决方案和项目 36
3.9.2 设置项目的引用 38
3.9.3 添加测试工程 40
第4章 调试环境的配置 42
4.1 调试环境设置概述 42
4.2 Linux操作系统调试环境设置 43
4.2.1 在Linux上设置ulimit 44
4.2.2 在Linux操作系统上部署调试器 44
4.2.3 在Linux操作系统上抓取内存转储文件 46
4.3 在macOS操作系统上部署调试器 47
4.4 在Windows操作系统上部署调试器 49
4.4.1 Windows上安装Windbg 50
4.4.2 在Windows上抓取内存转储 51
第5章 调试器的基本命令 54
5.1 使用LLDB进行调试 54
5.1.1 LLDB调试器简介 54
5.1.2 命令行参数 55
5.1.3 一段用于演示的代码 57
5.1.4 LLDB的启动和退出 58
5.1.5 设置断点 59
5.1.6 单步调试指令 60
5.1.7 查看调用堆栈 61
5.1.8 线程切换 63
5.1.9 寄存器调试指令 63
5.1.10 查看内存数据 64
5.2 Windbg调试器和基本指令 65
5.2.1 Windbg简介 65
5.2.2 Windbg的启动和退出 66
5.2.3 Windbg设置断点 68
5.2.4 Windbg查看堆栈调用 69
5.2.5 Windbg线程相关指令 69
5.2.6 Windbg寄存器相关指令 71
5.2.7 Windbg查看内存数据 72
第6章 .NET基本调试命令 73
6.1.NET调试扩展概览 73
6.2.NET数据结构的基本知识 74
6.2.1 对象在内存中的形态 75
6.2.2 MethodTable和EEClass 76
6.2.3 MethodDesc 77
6.3.NET调试扩展命令 77
6.3.1 代码和堆栈调试命令 77
6.3.2 CLR数据结构相关调试命令 83
6.3.3 内存对象分析相关命令 89
6.4 那些所谓的调试套路 95
第7章 多线程 98
7.1 多线程基础 98
7.1.1 线程的基本概念 98
7.1.2.NETCore多线程同步对象 98
7.2 一个简单的多线程程序调试 100
7.2.1 MassiveThreads程序 100
7.2.2 LLDB调试MassiveThreads 101
7.2.3 Windbg调试MassiveThreads 108
7.2.4 MassiveThreads调试总结 113
7.3 程序死锁的调试 114
7.3.1 DBDeadlockHang应用程序 114
7.3.2 使用LLDB调试死锁 116
7.3.3 使用Windbg调试死锁 122
7.3.4 死锁调试总结 128
第8章 async和await 129
8.1 基于任务的异步编程模式 129
8.2 如何写好一个TAP异步方法 130
8.2.1 函数的命名和声明 131
8.2.2 异步方法中的代码 131
8.2.3 函数中的异常处理 131
8.2.4 异步方法执行过程中的终止 132
8.2.5 异步任务执行进度的通知 132
8.3 async/await是什么 133
8.4 async/await调试 135
8.4.1 使用LLDB在Linux上调试异步方法 135
8.4.2 在Visual Studio 2017上调试异步方法 147
第9章 内存和垃圾收集 149
9.1.NETCore内存管理工作原理 149
9.1.1 从一行简单的代码看内存申请 149
9.1.2.NETCore内存管理概览 151
9.1.3 托管堆内存的分代管理 152
9.1.4 Finalizer队列 153
9.2 内存泄漏调试 153
9.2.1 如何诊断内存泄漏 153
9.2.2 Linux的内存泄漏调试 155
9.2.3 Windows下的内存泄漏调试 165
9.3 Finalizer队列调试 166
后记 168