go func 時發生了什麼

G1733發表於2024-07-05

1、go func

編譯如下程式,將斷點打在go recvGen 和go tstPrint 處,分別單步除錯進入newproc 函式檢視fn地址

package main

import "fmt"

func tstPrint(x int, c chan int) {
    fmt.Printf("%d", x)
    c <- x * x
}

func recvGen(c chan int) {
    x := <-c
    go tstPrint(x, c)
    fmt.Printf("%d", <-c)
    return
}

func main() {
    var c1, c2 chan int
    c1 = make(chan int, 3)
    go recvGen(c1)
    c1 <- 2
    fmt.Printf("%d", <-c2)
}

檢視objdump 反彙編的程式碼找到上述的fn地址,可以發現每一個go func 編譯器都會使用一個parentsName.func[\d+] 去包裝呼叫,保證每一個go func 執行地址的唯一

  000000000049e980 <main.main.func1>:
  49e980:       49 3b 66 10             cmp    0x10(%r14),%rsp
  49e984:       76 2f                   jbe    49e9b5 <main.main.func1+0x35>
  49e986:       48 83 ec 18             sub    $0x18,%rsp
  49e98a:       48 89 6c 24 10          mov    %rbp,0x10(%rsp)
  49e98f:       48 8d 6c 24 10          lea    0x10(%rsp),%rbp
  49e994:       4d 8b 66 20             mov    0x20(%r14),%r12
  49e998:       4d 85 e4                test   %r12,%r12
  49e99b:       75 1f                   jne    49e9bc <main.main.func1+0x3c>
  49e99d:       48 8b 42 08             mov    0x8(%rdx),%rax
  49e9a1:       48 89 44 24 08          mov    %rax,0x8(%rsp)
  49e9a6:       e8 55 fc ff ff          callq  49e600 <main.recvGen>  // 呼叫目標函式
  49e9ab:       48 8b 6c 24 10          mov    0x10(%rsp),%rbp
  49e9b0:       48 83 c4 18             add    $0x18,%rsp
  49e9b4:       c3                      retq
  49e9b5:       e8 26 5d fc ff          callq  4646e0 <runtime.morestack.abi0>
  49e9ba:       eb c4                   jmp    49e980 <main.main.func1>
  49e9bc:       4c 8d 6c 24 20          lea    0x20(%rsp),%r13
  49e9c1:       4d 39 2c 24             cmp    %r13,(%r12)
  49e9c5:       75 d6                   jne    49e99d <main.main.func1+0x1d>
  49e9c7:       49 89 24 24             mov    %rsp,(%r12)
  49e9cb:       eb d0                   jmp    49e99d <main.main.func1+0x1d>
  
 
 000000000049e7a0 <main.recvGen.func1>:
  49e7a0:       49 3b 66 10             cmp    0x10(%r14),%rsp
  49e7a4:       76 3d                   jbe    49e7e3 <main.recvGen.func1+0x43>
  49e7a6:       48 83 ec 28             sub    $0x28,%rsp
  49e7aa:       48 89 6c 24 20          mov    %rbp,0x20(%rsp)
  49e7af:       48 8d 6c 24 20          lea    0x20(%rsp),%rbp
  49e7b4:       4d 8b 66 20             mov    0x20(%r14),%r12
  49e7b8:       4d 85 e4                test   %r12,%r12
  49e7bb:       75 2d                   jne    49e7ea <main.recvGen.func1+0x4a>
  49e7bd:       48 8b 4a 08             mov    0x8(%rdx),%rcx
  49e7c1:       48 89 4c 24 10          mov    %rcx,0x10(%rsp)
  49e7c6:       48 8b 5a 10             mov    0x10(%rdx),%rbx
  49e7ca:       48 89 5c 24 18          mov    %rbx,0x18(%rsp)
  49e7cf:       48 8b 44 24 10          mov    0x10(%rsp),%rax
  49e7d4:       e8 27 fd ff ff          callq  49e500 <main.tstPrint>  // 呼叫目標函式
  49e7d9:       48 8b 6c 24 20          mov    0x20(%rsp),%rbp
  49e7de:       48 83 c4 28             add    $0x28,%rsp
  49e7e2:       c3                      retq
  49e7e3:       e8 f8 5e fc ff          callq  4646e0 <runtime.morestack.abi0>
  49e7e8:       eb b6                   jmp    49e7a0 <main.recvGen.func1>
  49e7ea:       4c 8d 6c 24 30          lea    0x30(%rsp),%r13
  49e7ef:       4d 39 2c 24             cmp    %r13,(%r12)
  49e7f3:       75 c8                   jne    49e7bd <main.recvGen.func1+0x1d>
  49e7f5:       49 89 24 24             mov    %rsp,(%r12)
  49e7f9:       eb c2                   jmp    49e7bd <main.recvGen.func1+0x1d>
  49e7fb:       cc                      int3
  49e7fc:       cc                      int3
  49e7fd:       cc                      int3
  49e7fe:       cc                      int3
  49e7ff:       cc                      int3

相關文章