美文网首页go
Go中全局变量存储在哪里?

Go中全局变量存储在哪里?

作者: 沙漠中的猴 | 来源:发表于2018-08-14 20:01 被阅读0次

    创建一个src.go文件,加入下面的代码

    package main
    
    import "fmt"
    
    var xxx = 0xEE     // 通过值来推断类型
    var yyy int = 0xFF // 定义类型,并赋值
    var zzz int        // 定义变量
    
    func main() {
        xxx = 0x11
        yyy = 0x22
        zzz = 0x33
    
        fmt.Println(xxx, yyy, zzz)
    }
    

    然后在命令行输入

    go build -gcflags "-N -l"
    

    -N 关闭编译器优化
    -l 关闭内联

    gdb调试

    进入gdb模式

    gdb src
    

    设置断点

    (gdb) b 14     // 在第十四行设置断点
    

    运行程序

    (gdb) r
    

    设置汇编语言为intel

    (gdb) set disassembly-flavor intel
    

    输入

    (gdb) disass
    

    来查看变量分配的地址。

    (gdb) set disassembly-flavor intel
    (gdb) disass
    Dump of assembler code for function main.main:
       0x00000000004820f0 <+0>: mov    rcx,QWORD PTR fs:0xfffffffffffffff8
       0x00000000004820f9 <+9>: lea    rax,[rsp-0x38]
       0x00000000004820fe <+14>:    cmp    rax,QWORD PTR [rcx+0x10]
       0x0000000000482102 <+18>:    jbe    0x4822d1 <main.main+481>
       0x0000000000482108 <+24>:    sub    rsp,0xb8
       0x000000000048210f <+31>:    mov    QWORD PTR [rsp+0xb0],rbp
       0x0000000000482117 <+39>:    lea    rbp,[rsp+0xb0]
       0x000000000048211f <+47>:    mov    QWORD PTR [rip+0x91f96],0x11        # 0x5140c0 <main.xxx>
       0x000000000048212a <+58>:    mov    QWORD PTR [rip+0x91f93],0x22        # 0x5140c8 <main.yyy>
       0x0000000000482135 <+69>:    mov    QWORD PTR [rip+0xc1d00],0x33        # 0x543e40 <main.zzz>
    => 0x0000000000482140 <+80>:    xorps  xmm0,xmm0
    

    我们可以看到:

    • xxx地址为0x5140c0
    • yyy地址为0x5140c8
    • zzz地址为0x543e40

    他们分别位于哪个段(Section)呢?

    我们输入如下命令来查看所处的位置

    (gdb) info symbol 0x5140c0
    main.xxx in section .noptrdata of /root/go/src/src
    (gdb) info symbol 0x5140c8
    main.yyy in section .noptrdata of /root/go/src/src
    (gdb) info symbol 0x543e40
    main.zzz in section .noptrbss of /root/go/src/src
    

    我们可以看到xxx与yyy位于.noptrdata段(Section)内。zzz位于.noptrbss段(Section)内

    由于go有垃圾回收器,所以将.data段(Section)去分为有指针和无指针两个段(Section)

    如何查看段(Section)分配的空间大小?

    (gdb) info files
    Symbols from "/root/go/src/src".
    Native process:
        Using the running image of child LWP 4272.
        While running this, GDB does not access memory from...
    Local exec file:
        `/root/go/src/src', file type elf64-x86-64.
        Entry point: 0x44f550
        0x0000000000401000 - 0x0000000000482505 is .text
        0x0000000000483000 - 0x00000000004c4a7e is .rodata
        0x00000000004c4ba0 - 0x00000000004c56e8 is .typelink
        0x00000000004c56e8 - 0x00000000004c5728 is .itablink
        0x00000000004c5728 - 0x00000000004c5728 is .gosymtab
        0x00000000004c5740 - 0x0000000000513947 is .gopclntab
        0x0000000000514000 - 0x0000000000520bfc is .noptrdata
        0x0000000000520c00 - 0x0000000000527710 is .data
        0x0000000000527720 - 0x0000000000543da8 is .bss
        0x0000000000543dc0 - 0x0000000000546458 is .noptrbss
        0x0000000000400f9c - 0x0000000000401000 is .note.go.buildid
        0x00007ffff7ffd120 - 0x00007ffff7ffd15c is .hash in system-supplied DSO at 0x7ffff7ffd000
        0x00007ffff7ffd160 - 0x00007ffff7ffd1a8 is .gnu.hash in system-supplied DSO at 0x7ffff7ffd000
        0x00007ffff7ffd1a8 - 0x00007ffff7ffd298 is .dynsym in system-supplied DSO at 0x7ffff7ffd000
        0x00007ffff7ffd298 - 0x00007ffff7ffd2f6 is .dynstr in system-supplied DSO at 0x7ffff7ffd000
        0x00007ffff7ffd2f6 - 0x00007ffff7ffd30a is .gnu.version in system-supplied DSO at 0x7ffff7ffd000
        0x00007ffff7ffd310 - 0x00007ffff7ffd348 is .gnu.version_d in system-supplied DSO at 0x7ffff7ffd000
        0x00007ffff7ffd348 - 0x00007ffff7ffd478 is .dynamic in system-supplied DSO at 0x7ffff7ffd000
        0x00007ffff7ffd478 - 0x00007ffff7ffd7b8 is .rodata in system-supplied DSO at 0x7ffff7ffd000
        0x00007ffff7ffd7b8 - 0x00007ffff7ffd7f4 is .note in system-supplied DSO at 0x7ffff7ffd000
        0x00007ffff7ffd7f4 - 0x00007ffff7ffd830 is .eh_frame_hdr in system-supplied DSO at 0x7ffff7ffd000
        0x00007ffff7ffd830 - 0x00007ffff7ffd948 is .eh_frame in system-supplied DSO at 0x7ffff7ffd000
        0x00007ffff7ffd950 - 0x00007ffff7ffdde9 is .text in system-supplied DSO at 0x7ffff7ffd000
        0x00007ffff7ffdde9 - 0x00007ffff7ffde1d is .altinstructions in system-supplied DSO at 0x7ffff7ffd000
        0x00007ffff7ffde1d - 0x00007ffff7ffde29 is .altinstr_replacement in system-supplied DSO at 0x7ffff7ffd000
    

    如何查看段(Section)的权限?

    root@000d3fada0b3:~/go/src# readelf -S src
    There are 23 section headers, starting at offset 0x1c8:
    
    Section Headers:
      [Nr] Name              Type             Address           Offset
           Size              EntSize          Flags  Link  Info  Align
      [ 0]                   NULL             0000000000000000  00000000
           0000000000000000  0000000000000000           0     0     0
      [ 1] .text             PROGBITS         0000000000401000  00001000
           0000000000081505  0000000000000000  AX       0     0     16
      [ 2] .rodata           PROGBITS         0000000000483000  00083000
           0000000000041a7e  0000000000000000   A       0     0     32
      [ 3] .shstrtab         STRTAB           0000000000000000  000c4a80
           000000000000010b  0000000000000000           0     0     1
      [ 4] .typelink         PROGBITS         00000000004c4ba0  000c4ba0
           0000000000000b48  0000000000000000   A       0     0     32
      [ 5] .itablink         PROGBITS         00000000004c56e8  000c56e8
           0000000000000040  0000000000000000   A       0     0     8
      [ 6] .gosymtab         PROGBITS         00000000004c5728  000c5728
           0000000000000000  0000000000000000   A       0     0     1
      [ 7] .gopclntab        PROGBITS         00000000004c5740  000c5740
           000000000004e207  0000000000000000   A       0     0     32
      [ 8] .noptrdata        PROGBITS         0000000000514000  00114000
           000000000000cbfc  0000000000000000  WA       0     0     32
      [ 9] .data             PROGBITS         0000000000520c00  00120c00
           0000000000006b10  0000000000000000  WA       0     0     32
      [10] .bss              NOBITS           0000000000527720  00127720
           000000000001c688  0000000000000000  WA       0     0     32
      [11] .noptrbss         NOBITS           0000000000543dc0  00143dc0
           0000000000002698  0000000000000000  WA       0     0     32
      [12] .debug_abbrev     PROGBITS         0000000000547000  00128000
           00000000000001b5  0000000000000000           0     0     1
      [13] .debug_line       PROGBITS         00000000005471b5  001281b5
           00000000000106e8  0000000000000000           0     0     1
      [14] .debug_frame      PROGBITS         000000000055789d  0013889d
           00000000000120dc  0000000000000000           0     0     1
      [15] .debug_pubnames   PROGBITS         0000000000569979  0014a979
    
    • A 是否载入内存
    • W 是否可写
    • X 执行权限

    总结

    初始化的全局变量分配在.data段(Section)内
    未初始化的全局变量分配在.bss段(Section)内

    局部变量在程序运行时分配内存地址。

    如何对src文件反汇编?

    go tool objdump -s "main\.main" src
    

    相关文章

      网友评论

        本文标题:Go中全局变量存储在哪里?

        本文链接:https://www.haomeiwen.com/subject/vlgvbftx.html