隨著.NET Core 開(kāi)源和跨平臺(tái)的特性逐漸被廣大開(kāi)發(fā)者熟知和接受,有越來(lái)越多的.NET 應(yīng)用從Windows 平臺(tái)向Linux 平臺(tái)進(jìn)行遷移,有越來(lái)越多的開(kāi)發(fā)者在Linux 或者macOS 操作系統(tǒng)上開(kāi)發(fā).NET 應(yīng)用。同時(shí),這也給之前只熟悉在Windows 平臺(tái)上開(kāi)發(fā).NET 應(yīng)用的開(kāi)發(fā)者帶來(lái)了一系列挑戰(zhàn)。怎樣在Linux 和macOS操作系統(tǒng)上有效地使用工具對(duì).NET Core 應(yīng)用程序進(jìn)行調(diào)試,找出程序中隱藏的代碼錯(cuò)誤和內(nèi)存中的問(wèn)題成為保障應(yīng)用程序在Linux 和macOS 上平穩(wěn)運(yùn)行的重要課題。本書從.NET Core概念、.NET Core 相關(guān)工具、調(diào)試器選擇、調(diào)試命令介紹和多線程、內(nèi)存調(diào)試實(shí)踐等多個(gè)環(huán)節(jié)對(duì).NET Core在Linux、macOS和Windows 三個(gè)操作系統(tǒng)上如何進(jìn)行調(diào)試做了詳盡的介紹。內(nèi)容包括.NET Core基礎(chǔ)知識(shí)、.NET Core 的編譯、.NET Core 命令行工具、調(diào)試環(huán)境的配置、調(diào)試器的基本命令、.NET 基本調(diào)試命令、多線程、async和await、內(nèi)存和垃圾收集等,分9章全面地闡述了.NET Core 跨平臺(tái)調(diào)試技術(shù)。
本書系統(tǒng)論述了.NET Core 的相關(guān)概念、編譯方法、命令行工具使用方法、調(diào)試環(huán)境搭建,調(diào)試器基本使用方法、.NET Core 調(diào)試擴(kuò)展基本使用方法、.NET Core 多線程應(yīng)用程序調(diào)試、以及.NET Core 內(nèi)存管理垃圾收集器等相關(guān)知識(shí)。全書論述了如下主題:
? .NET Core 你需要知道的;
? .NET Core 的編譯;
? .NET Core 命令行工具;
? 調(diào)試環(huán)境的配置;
? 調(diào)試器的基本命令;
? .NET 基本調(diào)試命令;
? 多線程調(diào)試;
? async 和await;
? 內(nèi)存和垃圾收集。
前言
不知不覺(jué),.NET Core 已經(jīng)開(kāi)源三年多了。在這三年多的時(shí)間里,我作為一個(gè)親歷者,經(jīng)歷了.NET Core 從1.0 到2.0 的涅槃。這幾年,也是我個(gè)人轉(zhuǎn)型為一名微軟技術(shù)布道師(Evangelist) 的重要時(shí)期。
作為一名24年前第一次接觸計(jì)算機(jī)就使用微軟產(chǎn)品的我來(lái)說(shuō),微軟這三年帶來(lái)的變化對(duì)我的影響真是太大了!開(kāi)源和云計(jì)算除了讓微軟的股價(jià)翻了兩番以外,也讓我走上了學(xué)習(xí)和了解開(kāi)源世界的道路。開(kāi)源為我打開(kāi)了世界的另一扇門,讓我了解到傳統(tǒng)企業(yè)軟件以外的廣闊世界。開(kāi)源真的徹底改變了我的思維。以前,寫一個(gè)客戶端應(yīng)用,我會(huì)直接打開(kāi)Visual Studio;現(xiàn)在,我會(huì)考慮清楚用哪種技術(shù)才能同時(shí)支持Windows、Linux 和macOS三個(gè)操作系統(tǒng)平臺(tái),再去動(dòng)手開(kāi)發(fā)。你能想象嗎?這本書的全部?jī)?nèi)容就是我在一臺(tái)蘋果筆記本上創(chuàng)作的,書稿的版本管理是通過(guò)Git 和Visual Studio Online 來(lái)實(shí)現(xiàn)的。
當(dāng)然,作為一名Windows 平臺(tái)的開(kāi)發(fā)者,向開(kāi)源世界轉(zhuǎn)型也并不是輕松的。為此,我專門買了一臺(tái)Macbook Pro。在工作和業(yè)余時(shí)間強(qiáng)迫自己去適應(yīng)它,去熟悉開(kāi)源世界的那些常用工具,在開(kāi)發(fā)過(guò)程中體會(huì)Visual Studio Code 的輕便快捷。在這個(gè)過(guò)程中也積累了一些經(jīng)驗(yàn),我的這本書就是我在開(kāi)源世界工作經(jīng)驗(yàn)的一部分總結(jié)。
.NET Core 作為.NET Framework 的一個(gè)開(kāi)源世界的變體,與.NET Framework 既有千絲萬(wàn)縷的聯(lián)系,又有很大的區(qū)別。一方面.NET Core 的大部分代碼都來(lái)自.NET Framework,另一方面.NET Core 還要處理好.NET Framework 不曾面對(duì)的跨平臺(tái)、自包含等新問(wèn)題的挑戰(zhàn)。在使用.NET Core 開(kāi)發(fā)的過(guò)程中,我發(fā)現(xiàn)有很多的待解決問(wèn)題。于是,我決定用我的這本書將它們總結(jié)出來(lái)分享給廣大.NET 開(kāi)發(fā)者,讓他們?cè)谑褂?NET Core 開(kāi)發(fā)應(yīng)用程序時(shí)少走一些彎路。
這本書集成了我在微軟作為開(kāi)發(fā)方向原廠支持工程師(PFE) 時(shí)的應(yīng)用程序調(diào)試和調(diào)優(yōu)的經(jīng)驗(yàn),同時(shí)也融合了我在Linux 平臺(tái)上的使用經(jīng)驗(yàn)。通過(guò)本書,我將向大家介紹如何在Linux 的各個(gè)發(fā)行版本以及Windows 上利用調(diào)試器對(duì).NET Core 應(yīng)用程序進(jìn)行調(diào)試的技術(shù)和技巧。因?yàn)?NET Core 要想在生產(chǎn)環(huán)境上大規(guī)模地使用,必須有強(qiáng)大的應(yīng)用程序調(diào)試技術(shù)作為保證,以便快速定位問(wèn)題和解決問(wèn)題。
通過(guò)長(zhǎng)達(dá)一年時(shí)間的寫作和對(duì).NET Core 問(wèn)題狀態(tài)的追蹤和分析,現(xiàn)在我真的認(rèn)為是時(shí)候把應(yīng)用程序遷移到.NET Core 上了!
本書包含哪些內(nèi)容
本書系統(tǒng)論述了.NET Core 的相關(guān)概念、編譯方法、命令行工具使用方法、調(diào)試環(huán)境搭建、調(diào)試器基本使用方法、.NET Core 調(diào)試擴(kuò)展基本使用方法、.NET Core 多線程應(yīng)用程序調(diào)試,以及.NET Core 內(nèi)存管理垃圾收集器等相關(guān)知識(shí)。本書全面詳盡地闡述了.NET Core源代碼獲取、編譯、調(diào)試的全方位技術(shù),你需要知道的.NET Core技術(shù)、.NET Core的編譯、.NET Core 命令行工具的使用、調(diào)試環(huán)境的配置、調(diào)試器的基本命令、.NET 調(diào)試基本命令、多線程、async 和await、內(nèi)存和垃圾收集等內(nèi)容。
如何高效地閱讀本書
本書從讀者角度出發(fā),章節(jié)由淺入深,從.NET Core 常見(jiàn)問(wèn)題講起,直到最后綜合運(yùn)用各種工具對(duì).NET Core應(yīng)用程序高級(jí)排錯(cuò)。因此,建議讀者從頭至尾順序閱讀。如果讀者具有豐富的Linux 使用經(jīng)驗(yàn),也可以忽略其中一些簡(jiǎn)單的章節(jié)。
本書適合哪些讀者
本書適合使用.NET Core 技術(shù)進(jìn)行應(yīng)用程序開(kāi)發(fā)的相關(guān)開(kāi)發(fā)人員,也適合于希望深入了解和學(xué)習(xí).NET Core平臺(tái)的讀者。
致謝
首先,我要感謝我的家人和我可愛(ài)的女兒。因?yàn)槲以趯憰鍟r(shí)嚴(yán)重占用了和她們?cè)谝黄鹦蓍e的時(shí)間。其次,要感謝我敬愛(ài)的老板崔宏禹老師,以及認(rèn)真負(fù)責(zé)的責(zé)任編輯盛東亮,這是我們合作的第三本書了。最后我還要感謝我心里愛(ài)著的那個(gè)人,你是我創(chuàng)作的原動(dòng)力。
由于作者水平有限,.NET Core 跨平臺(tái)相關(guān)知識(shí)涉及廣泛,書中難免存在疏漏和不妥之處,敬請(qǐng)廣大讀者批評(píng)指正。
書中樣例代碼
為了詳盡描述調(diào)試的整個(gè)過(guò)程,突出一些要調(diào)試的現(xiàn)象,書中涉及了許多.NET Core 代碼工程。這些代碼都是使用Visual Studio Code 針對(duì).NET Core 2.0 進(jìn)行編寫,源代碼下載地址:
https://github.com/micli/netcoredebugging
以上源代碼都可以在.NET Core 2.0環(huán)境的支持下,運(yùn)行在Windows、Linux和macOS 操作系統(tǒng)上。
書中特殊約定
為了直觀,書中與操作系統(tǒng)相關(guān)的命令都通過(guò)操作系統(tǒng)對(duì)應(yīng)的商標(biāo)來(lái)標(biāo)識(shí),代表這些命令在對(duì)應(yīng)的操作系統(tǒng)下測(cè)試通過(guò)。因Linux發(fā)行版本眾多,不同發(fā)行版本的Linux部分命令可能略有差異。因作者精力有限,僅能覆蓋CentOS/Red Hat 和Debian/Ubuntu 等最流行的兩組發(fā)行版本,望讀者見(jiàn)諒。
(1) 代表Debian 8.0或者Ubuntu 操作系統(tǒng);
(2) 代表CentOS 7.0 或者Red Hat 操作系統(tǒng);
(3) 代表Windows 8.1、10、Server 2008/2012/2016系列操作系統(tǒng);
(4) 代表 macOS Sierra系列操作系統(tǒng)。
在書中配有大量的Shell命令、C#代碼和調(diào)試器指令以及為了說(shuō)明調(diào)試輸出的圖片。書中的命令是指用戶與操作系統(tǒng)Shell之間交互時(shí)輸入的命令; 代碼是指經(jīng)過(guò)編譯,可以運(yùn)行在.NET Core 2.0上的C#語(yǔ)言源代碼; 調(diào)試是指調(diào)試者與Windbg或者LLDB調(diào)試器之間交互時(shí)輸入的調(diào)試指令。請(qǐng)讀者在閱讀時(shí)加以區(qū)分。
編著者
2018年8月
李爭(zhēng) 微軟(中國(guó))有限公司開(kāi)發(fā)者體驗(yàn)與平臺(tái)合作事業(yè)部資深技術(shù)顧問(wèn)。專注于微軟公有云平臺(tái)Azure的解決方案和架構(gòu)設(shè)計(jì)、Azure應(yīng)用的實(shí)施,以及Azure上的開(kāi)源技術(shù)等工作。曾在微軟企業(yè)服務(wù)部作為原廠技術(shù)支持工程師工作多年,承擔(dān)企業(yè)開(kāi)發(fā)者代碼調(diào)試和技術(shù)支持、Web應(yīng)用前端后端代碼調(diào)優(yōu),以及IIS 的問(wèn)題診斷、調(diào)優(yōu)、培訓(xùn)等工作。具有豐富的企業(yè)客戶臨場(chǎng)解決嚴(yán)重系統(tǒng)問(wèn)題的經(jīng)驗(yàn)。擁有四十多門微軟認(rèn)證證書,涵蓋了幾乎全部微軟開(kāi)發(fā)相關(guān)技術(shù),同時(shí)也是一位具有十多年授課經(jīng)驗(yàn)的微軟認(rèn)證講師(MCT)。 著有《微軟互聯(lián)網(wǎng)信息服務(wù)(IIS)最佳實(shí)踐》《微軟開(kāi)源跨平臺(tái)移動(dòng)開(kāi)發(fā)實(shí)踐》暢銷圖書。
目錄
叢書序Ⅰ
推薦序Ⅲ
前言Ⅴ
贊譽(yù)Ⅸ
第1章.NET Core基礎(chǔ)知識(shí)
1.1.NET Core到底是什么
1.1.1從軟件許可協(xié)議說(shuō)開(kāi)源
1.1.2構(gòu)成.NET Core的重要組件
1.2.NET Standard又是什么
1.3.NET Core的一些重要工具
1.4常見(jiàn)問(wèn)題解答
第2章.NET Core的編譯
2.1.NET Core源代碼在Linux操作系統(tǒng)上的編譯
2.1.1獲取.NET Core源代碼
2.1.2安裝編譯源代碼必要的工具
2.1.3在CentOS上手工編譯LLVM、Clang和LLDB
2.1.4在Linux上編譯.NET Core源代碼
2.2.NET Core源代碼在Windows操作系統(tǒng)上的編譯
2.2.1下載和安裝Visual Studio
2.2.2安裝其他必備軟件
2.2.3在Windows系統(tǒng)上執(zhí)行.NET Core編譯
2.3.NET Core源代碼在macOS操作系統(tǒng)上的編譯
第3章.NET Core命令行工具
3.1.NET Core CLI的安裝
3.2創(chuàng)建.NET Core項(xiàng)目
3.3.NET Core項(xiàng)目的遷移
3.4.NET Core項(xiàng)目的構(gòu)建
3.5.NET Core項(xiàng)目的發(fā)布
3.6對(duì).NET Core項(xiàng)目進(jìn)行管理
3.6.1dotnet sln命令介紹
3.6.2項(xiàng)目之間的引用管理
3.6.3項(xiàng)目的包管理
3.6.4項(xiàng)目引用NuGet包的恢復(fù)
3.7.NET Core應(yīng)用的執(zhí)行
3.8將.NET Core項(xiàng)目發(fā)布成NuGet包
3.8.1dotnet pack命令介紹
3.8.2dotnet nuget push命令介紹
3.8.3dotnet nuget locals命令介紹
3.8.4dotnet nuget delete命令介紹
3.9dotnet相關(guān)命令的使用
3.9.1創(chuàng)建解決方案和項(xiàng)目
3.9.2設(shè)置項(xiàng)目的引用
3.9.3添加測(cè)試工程
第4章調(diào)試環(huán)境的配置
4.1調(diào)試環(huán)境設(shè)置概述
4.2Linux操作系統(tǒng)調(diào)試環(huán)境設(shè)置
4.2.1在Linux上設(shè)置ulimit
4.2.2在Linux操作系統(tǒng)上部署調(diào)試器
4.2.3在Linux操作系統(tǒng)上抓取內(nèi)存轉(zhuǎn)儲(chǔ)文件
4.3在macOS操作系統(tǒng)上部署調(diào)試器
4.4在Windows操作系統(tǒng)上部署調(diào)試器
4.4.1Windows上安裝Windbg
4.4.2在Windows上抓取內(nèi)存轉(zhuǎn)儲(chǔ)
第5章調(diào)試器的基本命令
5.1使用LLDB進(jìn)行調(diào)試
5.1.1LLDB調(diào)試器簡(jiǎn)介
5.1.2命令行參數(shù)
5.1.3一段用于演示的代碼
5.1.4LLDB的啟動(dòng)和退出
5.1.5設(shè)置斷點(diǎn)
5.1.6單步調(diào)試指令
5.1.7查看調(diào)用堆棧
5.1.8線程切換
5.1.9寄存器調(diào)試指令
5.1.10查看內(nèi)存數(shù)據(jù)
5.2Windbg調(diào)試器和基本指令
5.2.1Windbg簡(jiǎn)介
5.2.2Windbg的啟動(dòng)和退出
5.2.3Windbg設(shè)置斷點(diǎn)
5.2.4Windbg查看堆棧調(diào)用
5.2.5Windbg線程相關(guān)指令
5.2.6Windbg寄存器相關(guān)指令
5.2.7Windbg查看內(nèi)存數(shù)據(jù)
第6章.NET基本調(diào)試命令
6.1.NET調(diào)試擴(kuò)展概覽
6.2.NET數(shù)據(jù)結(jié)構(gòu)的基本知識(shí)
6.2.1對(duì)象在內(nèi)存中的形態(tài)
6.2.2MethodTable和EEClass
6.2.3MethodDesc
6.3.NET調(diào)試擴(kuò)展命令
6.3.1代碼和堆棧調(diào)試命令
6.3.2CLR數(shù)據(jù)結(jié)構(gòu)相關(guān)調(diào)試命令
6.3.3內(nèi)存對(duì)象分析相關(guān)命令
6.4那些所謂的調(diào)試套路
第7章多線程
7.1多線程基礎(chǔ)
7.1.1線程的基本概念
7.1.2.NET Core多線程同步對(duì)象
7.2一個(gè)簡(jiǎn)單的多線程程序調(diào)試
7.2.1MassiveThreads程序
7.2.2LLDB調(diào)試MassiveThreads
7.2.3Windbg調(diào)試MassiveThreads
7.2.4MassiveThreads調(diào)試總結(jié)
7.3程序死鎖的調(diào)試
7.3.1DBDeadlockHang應(yīng)用程序
7.3.2使用LLDB調(diào)試死鎖
7.3.3使用Windbg調(diào)試死鎖
7.3.4死鎖調(diào)試總結(jié)
第8章async和await
8.1基于任務(wù)的異步編程模式
8.2如何寫好一個(gè)TAP異步方法
8.2.1函數(shù)的命名和聲明
8.2.2異步方法中的代碼
8.2.3函數(shù)中的異常處理
8.2.4異步方法執(zhí)行過(guò)程中的終止
8.2.5異步任務(wù)執(zhí)行進(jìn)度的通知
8.3async/await是什么
8.4async/await調(diào)試
8.4.1使用LLDB在Linux上調(diào)試異步方法
8.4.2在Visual Studio 2017上調(diào)試異步方法
第9章內(nèi)存和垃圾收集
9.1.NET Core內(nèi)存管理工作原理
9.1.1從一行簡(jiǎn)單的代碼看內(nèi)存申請(qǐng)
9.1.2.NET Core內(nèi)存管理概覽
9.1.3托管堆內(nèi)存的分代管理
9.1.4Finalizer隊(duì)列
9.2內(nèi)存泄漏調(diào)試
9.2.1如何診斷內(nèi)存泄漏
9.2.2Linux的內(nèi)存泄漏調(diào)試
9.2.3Windows下的內(nèi)存泄漏調(diào)試
9.3Finalizer隊(duì)列調(diào)試
后記