美文网首页
升级到Catalina后,golang执行问题

升级到Catalina后,golang执行问题

作者: lizyyy | 来源:发表于2019-10-10 15:03 被阅读0次

升级到Catalina 10.15后,golang编译完成后,执行二进制文件报错:
dyld: malformed mach-o image: segment __DWARF has vmsize < filesize

下边我们简单的说一下 Mach-O 文件。

Mach-O

我们知道,进程是可执行文件在内存中加载得到的结果,而 Mach-O 就是一种 macOS 平台的可执行文件格式。

Mach-O 文件分为三个区域 Header、Load commands、Data。其中 Load commands 区的指令指导如何设置并加载二进制数据。

  • LC_SEGMENT 对应的数据结构:segment_command
    定义了这个文件中的一个 segment,在 Mach-O 文件被加载到时,这个 segment 会被映射到对应的地址空间。需要留意,segment_command 中有一个 segname,可通过 segname 来查找指定的 segment。
struct segment_command { /* for 32-bit architectures */
    uint32_t    cmd;        /* LC_SEGMENT */
    uint32_t    cmdsize;    /* includes sizeof section structs */
    char        segname[16];    /* segment name */
    uint32_t    vmaddr;     /* memory address of this segment */
    uint32_t    vmsize;     /* memory size of this segment */
    uint32_t    fileoff;    /* file offset of this segment */
    uint32_t    filesize;   /* amount to map from the file */
    vm_prot_t   maxprot;    /* maximum VM protection */
    vm_prot_t   initprot;   /* initial VM protection */
    uint32_t    nsects;     /* number of sections in segment */
    uint32_t    flags;      /* flags */
};

对于每一个 segment 而言,设置进程虚拟内存的过程就是将相应的内容加载到内存中,也就是从 Mach-O 文件的 fileoff 初加载 filesize 字节到虚拟内存地址的 vmaddr 处,占用 vmsize 字节。需要留意,对某些 segment 来说,vmsize 可能会大于 filesize,如__Data、__LINKEDIT。

目前解决办法,去掉DWARF调试信息:

编译的时候使用 go build -ldflags "-w" 这种方式编译。
-ldflags: 表示将后面的参数传给连接器(5/6/8l)
-s:去掉符号信息
-w:去掉DWARF调试信息
注意:
-w 去掉DWARF调试信息,得到的程序就不能用gdb调试了

相关文章

网友评论

      本文标题:升级到Catalina后,golang执行问题

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