成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

曹大帶我學 Go之如何用匯編打同事的臉

開發 后端
今天介紹幾個常用的查看 Go 匯編代碼、調試 Go 程序的命令和工具,既可以在平時和同事、網友抬杠時使用,還能在關鍵時刻打他們的臉。

[[401881]]

本文轉載自微信公眾號「碼農桃花源」,作者小X。轉載本文請聯系碼農桃花源公眾號。

你好,我是小X。

曹大最近開 Go 課程了,小X 正在和曹大學 Go。

這個系列會講一些從課程中學到的讓人醍醐灌頂的東西,撥云見日,帶你重新認識 Go。

今天介紹幾個常用的查看 Go 匯編代碼、調試 Go 程序的命令和工具,既可以在平時和同事、網友抬杠時使用,還能在關鍵時刻打他們的臉。

比如,有同事說這段代碼:

  1. package main 
  2.  
  3. type Student struct { 
  4.  Class int 
  5.  
  6. func main() { 
  7.  var a = &Student{1} 
  8.  println(a) 

的執行效率要高于下面這段代碼:

  1. package main 
  2.  
  3. type Student struct { 
  4.  Class int 
  5.  
  6. func main() { 
  7.  var a = Student{1} 
  8.  var b = &a 
  9.  println(b) 

并且給你講了一通道理,你好像沒法辯贏他。怎么辦?

直接用一行命令生成匯編代碼,馬上可以戳穿他,打他的臉。

go tool 生成匯編

其實很簡單,有兩個命令可以做到:

  1. go tool compile -S main.go 

和:

  1. go build main.go && go tool objdump ./main 

前者是編譯,即將源代碼編譯成 .o 目標文件,并輸出匯編代碼。

后者是反匯編,即從可執行文件反編譯成匯編,所以要先用 go build 命令編譯出可執行文件。

二者不盡相同,但都能看到前面兩個示例代碼對應的匯編代碼是一致的。同事的“謠言”不攻自破,臉都被你打疼了。

找到 runtime 源碼

Go 是一門有 runtime 的語言,什么是 runtime?其實就是一段輔助程序,用戶沒有寫的代碼,runtime 替我們寫了,比如 Go 調度器的代碼。

我們只需要知道用 go 關鍵字創建 goroutine,就可以瘋狂堆業務了。至于 goroutine 是怎么被調度的,根本不需要關心,這些是 runtime 調度器的工作。

那我們自己寫的代碼如何和 runtime 里的代碼對應起來呢?

前面介紹的方法就可以做到,只需要加一個 grep 就可以。

例如,我想知道 go 關鍵字對應 runtime 里的哪個函數,于是寫了一段測試代碼:

  1. package main 
  2.  
  3. func main() { 
  4.  go func() { 
  5.   println(1+2) 
  6.  }() 

因為 go func(){}() 那一行代碼在第 4 行,所以,grep 的時候加一個條件:

  1. go tool compile -S main.go | grep "main.go:4" 
  2.  
  3. // 或 
  4.  
  5. go build main.go && go tool objdump ./main | grep "main.go:4" 

go func

馬上就能看到 go func(){}() 對應 newproc() 函數,這時再深入研究下 newproc() 函數就大概知道 goroutine 是如何被創建的。

用 dlv 調試

那有同學問了,有沒有其他可以調試 Go、以及和 Go 程序互動的方法呢?其實是有的!這就是我們要介紹的 dlv 調試工具,目前它對調試 Go 程序的支持是最好的。

之前沒我怎么研究它,只會一些非常簡單的命令,這次學會了幾個進階的指令,威力挺大,也進一步加深了對 Go 的理解。

下面我們帶著一個任務來講解 dlv 如何使用。

我們知道,向一個 nil 的 slice append 元素,不會有任何問題。但是向一個 nil 的 map 插入新元素,馬上就會報 panic。這是為什么呢?又是在哪 panic 呢?

首先寫出讓 map 產生 panic 的示例程序:

  1. package main 
  2.  
  3. func main() { 
  4.  var m map[int]int 
  5.  m[1] = 1 

接著用 go build 命令編譯生成可執行文件:

  1. go build a.go 

然后,使用 dlv 進入調試狀態:

  1. dlv exec ./a 

使用 b 這個命令打斷點,有三種方法:

  1. b + 地址
  2. b + 代碼行數
  3. b + 函數名

我們要在對 map 賦值的地方加個斷點。先找到代碼位置:

  1. cat -n a.go 

看到:

hello.go

賦值的地方在第 5 行,加斷點:

  1. (dlv) b a.go:5 
  2. Breakpoint 1 set at 0x45e55d for main.main() ./a.go:5 

執行 c 命令,直接運行到斷點處:

運行到斷點處

執行 disass 命令,可以看到匯編指令:

disass

這時使用 si 命令,執行單條指令,多次執行 si,就會執行到 map 賦值函數 mapassign_fast64:

mapassign_fast64

這時再用單步命令 s,就會進入判斷 h 的值為 nil 的分支,然后執行 panic 函數:

panic

至此,向 nil 的 map 賦值時,產生 panic 的代碼就被我們找到了。接著,按圖索驥找到對應 runtime 源碼的位置,就可以進一步探索了。

除此之外,我們還可以使用 bt 命令看到調用棧:

調用棧

使用 frame 1 命令可以跳轉到相應位置。這里 1 對應圖中的 a.go:5,也就是我們前面打斷點的地方,是不是非常酷炫。

上面這張圖里我們也能清楚地看到,用戶 goroutine 其實是被 goexit 函數一路調用過來的。當用戶 goroutine 執行完畢后,就會回到 goexit 函數做一些收尾工作。當然,這是題外話了。

另外,用 dlv 也能干第二部分“找到 runtime 源碼”活。

總結

今天系統地講了幾招通過命令和工具查看用戶代碼對應的 runtime 源碼或者匯編代碼的方法,非常實用。最后再匯總一下:

  • go tool compile
  • go tool objdump
  • dlv

使用這些命令和工具,可以讓你在看 Go 源碼的過程中事半功倍。

 

好了,這就是今天全部的內容了~ 我是小X,我們下期再見~

 

責任編輯:武曉燕 來源: 碼農桃花源
相關推薦

2021-06-10 09:00:32

Go底層代碼

2021-06-07 10:47:02

GoGoexit函數

2021-07-15 08:58:15

指定配置項Go

2021-08-09 07:47:39

ExtraGoMap

2021-06-01 09:27:53

Ast Go語言

2021-05-20 08:59:47

Go調度本質

2022-01-05 08:56:20

Go火焰圖編程

2020-11-09 14:10:38

Bug安全代碼

2017-01-12 22:36:30

2015-08-10 11:09:09

Python代碼Python

2023-04-17 14:32:20

2021-04-21 12:46:19

C語言流水燈匯編

2023-05-26 15:10:46

2019-10-11 15:10:09

GVMGoLinux

2025-03-03 02:25:00

.NET 9JSON序列化

2019-01-02 13:11:53

GO語言緩存

2019-06-24 09:28:55

谷歌臉書亞馬遜

2020-02-20 10:45:57

代碼JS開發

2022-04-06 08:58:39

歸并排序Go算法

2022-03-23 08:01:04

Python語言代碼
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: av午夜电影| 国产精品亚洲精品久久 | 精品伊人久久 | 欧美亚洲国产一区二区三区 | 日韩不卡一区二区 | 91久久精品一区二区三区 | 日韩手机在线看片 | 一色桃子av一区二区 | 国产精品无码专区在线观看 | 日本免费视频在线观看 | 日韩在线观看中文字幕 | 99精品热视频 | 伊伊综合网 | 三a毛片 | av福利网站 | 超碰高清 | 欧美中文在线 | 久久久久久亚洲精品 | a在线观看| 亚洲va欧美va人人爽午夜 | 久久国产成人精品国产成人亚洲 | 日本久久久久久 | 欧美在线色视频 | 亚洲91精品 | 精品av天堂毛片久久久借种 | 亚欧洲精品在线视频免费观看 | 亚洲欧美一区二区三区1000 | 国内精品99| 成人在线中文 | 欧美一级在线观看 | 国产在线中文 | 亚洲色图综合网 | 精品永久 | 日韩高清黄色 | 国产高清在线精品一区二区三区 | 韩日精品一区 | 日韩精品 | 日本精品一区二区三区在线观看视频 | 99久久精品国产一区二区三区 | 欧美精品一区在线 | 亚洲福利片 |