升级到Catalina后,golang执行问题

aside section ._1OhGeD · · 3969 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

升级到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调试了


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:aside section ._1OhGeD

查看原文:升级到Catalina后,golang执行问题

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:701969077

3969 次点击  
加入收藏 微博
1 回复  |  直到 2019-11-12 11:49:08
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传