简体   繁体   English

如何检查是否使用--ldflags =“ - s -w”编译golang二进制文件

[英]how to check whether golang binary is compiled with --ldflags=“-s -w”

我知道--ldflags="-s -w"会使Go二进制大小变小,但是没有比较没有ldflags的那个,我们怎么知道Go二进制编译是否有ldflags="-s -w"

Disclaimer first: I'm no expert of compilation toolchains and executable file formats. 免责声明:我不是编译工具链和可执行文件格式的专家。 I'll try not to say stupid things, but correct me if you see any mistake ! 我会尽量不说愚蠢的事情,但如果你看到任何错误,请纠正我!

I ran those tests on an ArchLinux laptop, with x86_64 architecture. 我在带有x86_64架构的ArchLinux笔记本电脑上运行这些测试。 Go version is 1.8.1. Go版本是1.8.1。

First, we need to know where those flags are actually used: 首先,我们需要知道实际使用这些标志的位置:

$ go help build
...
-ldflags 'flag list'
    arguments to pass on each go tool link invocation
...

Apparently, flags are merely passed to the go tool link invocation. 显然,标志只是传递给go tool link调用。 Looking at the help, we have a bit more information: 看看帮助,我们有更多信息:

$ go tool link
...
-s  disable symbol table
...
-w  disable DWARF generation
...

Taken from the short introduction to ELF that I found here , here is the header text concerning the Symbol Table: 从我在这里找到的ELF的简短介绍中,这里是关于符号表的标题文本:

An object file's symbol table holds information needed to locate and relocate a program's symbolic definitions and references. 目标文件的符号表包含查找和重定位程序的符号定义和引用所需的信息。

As for DWARF, this is a format for debugging data. 对于DWARF,这是一种用于调试数据的格式。

From there, how do we know if a binary has a symbol table, or DWARF enabled ? 从那里,我们如何知道二进制文件是否具有符号表或启用了DWARF? The answer lies in ELF sections. 答案在于ELF部分。 There are probably other ways, but it is the one I found and is easy to check for. 可能还有其他方法,但它是我找到的并且很容易检查的方式。 Here are the rules that I've used to determine if a Golang binary has been compiled with -ldflags='-s' or -ldflags='-w' : 以下是我用来确定是否使用-ldflags='-s'-ldflags='-w'编译Golang二进制文件的规则:

  • If a Go binary has a symbol table, the section .symtab is present 如果Go二进制文件具有符号表,则存在.symtab部分
  • If a Go binary has DWARF debug, the section .debug_info is present. 如果Go二进制文件具有DWARF调试,则存在.debug_info部分。 This section is not the only one to be present, but serves as an indicator. 此部分不是唯一存在的部分,但可作为指标。

On Linux, there are some tools which can read section names to extract those informations. 在Linux上,有一些工具可以读取段名以提取这些信息。 readelf and nm are examples, yet probably more exist. readelfnm是例子,但可能更多存在。

It also turns out that Go provide a debug/elf package which can be used to get those informations. 事实证明,Go提供了一个debug/elf包,可用于获取这些信息。 Here is a sample program that does this job: 这是一个完成这项工作的示例程序:

package main

import "fmt"
import "os"
import "debug/elf"

func main() {
    fileName := "path/to/main"
    fp, err := elf.Open(fileName)
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }

    symtab := fp.Section(".symtab")
    if symtab == nil {
        fmt.Println("No Symbol Table : compiled with -ldflags='-s'")
    }

    debugInfo := fp.Section(".debug_info")
    if debugInfo == nil {
        fmt.Println("No DWARF data : compiled with -ldflags='-w'")
    }
}

I tested this program against the basic Golang Hello World, using no flags, only the -s flag, only the -w flag and both -s -w flags. 我针对基本的Golang Hello World测试了这个程序,没有使用标志,只使用-s标志,只使用-w标志和-s -w标志。 I noted that while compiling with -s only, it also removed DWARF data, but I did not search why. 我注意到,虽然只使用-s进行编译,但它也删除了DWARF数据,但我没有搜索原因。 Aside from that, the results were as expected. 除此之外,结果如预期。

Though ELF was the focus format, the same method can be applied for Windows executables (there is a debug/pe package in Golang). 虽然ELF是焦点格式,但是同样的方法可以应用于Windows可执行文件(Golang中有一个debug/pe包)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM