go runtime.newobject闭包变量malloc不在堆中

时间:2018-04-19 07:31:10

标签: go closures runtime

代码:


    package main

    import "fmt"

    func test(x, y int) func() {
            return func() {
                    x += y
            }
    }

    func main() {
            f := test(0x100, 0x200)
            f()
            fmt.Println("close")
    }

编译:

go build -gcflags "-N -l" -o test main.go

GDB:


           info "(gdb)Auto-loading safe path"
    (gdb) l
    2
    3       import "fmt"
    4
    5       func test(x, y int) func() {
    6               return func() {
    7                       x += y
    8               }
    9       }
    10
    11      func main() {
    (gdb) l
    12              f := test(0x100, 0x200)
    13              f()
    14              fmt.Println("close")
    15      }
        (gdb) b 13
        Breakpoint 1 at 0x483291: file /home/devops/study/src/function/closed_function.go, line 13.
        (gdb) b 6 
        Breakpoint 2 at 0x4831cc: /home/devops/study/src/function/closed_function.go:6. (2 locations)
        (gdb) r
        Starting program: /home/devops/study/src/function/test 

        Breakpoint 2, main.test (x=256, y=512, ~r2={void ()} 0xc420043f20) at /home/devops/study/src/function/closed_function.go:6
        6               return func() {
        (gdb) set disassembly-flavor intel
        (gdb) disassemble 
    Dump of assembler code for function main.test:
       0x0000000000483180 :     mov    rcx,QWORD PTR fs:0xfffffffffffffff8
       0x0000000000483189 :     cmp    rsp,QWORD PTR [rcx+0x10]
       0x000000000048318d :    jbe    0x483240 
       0x0000000000483193 :    sub    rsp,0x28
       0x0000000000483197 :    mov    QWORD PTR [rsp+0x20],rbp
       0x000000000048319c :    lea    rbp,[rsp+0x20]
       0x00000000004831a1 :    mov    QWORD PTR [rsp+0x40],0x0
       0x00000000004831aa :    lea    rax,[rip+0x103af]        # 0x493560
       0x00000000004831b1 :    mov    QWORD PTR [rsp],rax
       0x00000000004831b5 :    call   0x40e3c0 
       0x00000000004831ba :    mov    rax,QWORD PTR [rsp+0x8]
       0x00000000004831bf :    mov    QWORD PTR [rsp+0x18],rax
       0x00000000004831c4 :    mov    rcx,QWORD PTR [rsp+0x30]
       0x00000000004831c9 :    mov    QWORD PTR [rax],rcx
    => 0x00000000004831cc :    lea    rax,[rip+0x1e44d]        # 0x4a1620
       0x00000000004831d3 :    mov    QWORD PTR [rsp],rax
       0x00000000004831d7 :    call   0x40e3c0      # this wihle return a unsafe.Poniter
       0x00000000004831dc :    mov    rax,QWORD PTR [rsp+0x8]
       0x00000000004831e1 :    mov    QWORD PTR [rsp+0x10],rax
       0x00000000004831e6 :   lea    rcx,[rip+0x133]        # 0x483320 
       0x00000000004831ed :   mov    QWORD PTR [rax],rcx
       0x00000000004831f0 :   mov    rax,QWORD PTR [rsp+0x10]
       0x00000000004831f5 :   test   BYTE PTR [rax],al
       0x00000000004831f7 :   mov    ecx,DWORD PTR [rip+0xc2de3]        # 0x545fe0 
       0x00000000004831fd :   mov    rdx,QWORD PTR [rsp+0x18]
       0x0000000000483202 :   lea    rdi,[rax+0x8]
       0x0000000000483206 :   test   ecx,ecx
       0x0000000000483208 :   jne    0x483236 
       0x000000000048320a :   jmp    0x48320c 
       0x000000000048320c :   mov    QWORD PTR [rax+0x8],rdx
       0x0000000000483210 :   jmp    0x483212 
       0x0000000000483212 :   mov    rax,QWORD PTR [rsp+0x10]
       0x0000000000483217 :   test   BYTE PTR [rax],al
       0x0000000000483219 :   mov    rcx,QWORD PTR [rsp+0x38]
       0x000000000048321e :   mov    QWORD PTR [rax+0x10],rcx
       0x0000000000483222 :   mov    rax,QWORD PTR [rsp+0x10]
       0x0000000000483227 :   mov    QWORD PTR [rsp+0x40],rax
       0x000000000048322c :   mov    rbp,QWORD PTR [rsp+0x20]
       0x0000000000483231 :   add    rsp,0x28
       0x0000000000483235 :   ret    
       0x0000000000483236 :   mov    rax,rdx
       0x0000000000483239 :   call   0x44f5c0 
       0x000000000048323e :   jmp    0x483212 
       0x0000000000483240 :   call   0x44d170 
       0x0000000000483245 :   jmp    0x483180 
    End of assembler dump.
    (gdb) c
    Continuing.

    Breakpoint 1, main.main () at /home/devops/study/src/function/closed_function.go:13
    13  
    (gdb) x/16xg $rsp 
    0xc420043f10:   0x0000000000000100      0x0000000000000200
    0xc420043f20:   0x000000c42000a060      0x000000000040423c
    0xc420043f30:   0x000000c42005a058      0x0000000000000000
    0xc420043f40:   0x000000c42000a060      0x00000000004b7465
    0xc420043f50:   0x0000000000000000      0x0000000000000000
    0xc420043f60:   0x000000c42000e1d0      0x000000c420043f78
    0xc420043f70:   0x000000c42005a058      0x000000c420043f80
    0xc420043f80:   0x0000000000427f32      0x000000c42005a000
    (gdb) x/3xg 0x000000c42000a060
    0xc42000a060:   0x0000000000483320      0x000000c420014098
    0xc42000a070:   0x0000000000000200
    (gdb) x/1xg 0x000000c420014098
    0xc420014098:   0x0000000000000100

通过查看变量的内存地址,找到最终的相应变量,并且内存地址不在堆上,而是运行时。 newobject只分配一个似乎跟随的指针,并且不会继续指向该操作?

0 个答案:

没有答案