go build doesn't propagate options that disable optimizations

809 views
Skip to first unread message

ptu...@gmail.com

unread,
Mar 15, 2018, 2:52:28 PM3/15/18
to golang-nuts
I build my Go project with the -N and -l options, but they only seem to apply to the top-most package -- imported packages are still optimized.  From what I can tell, this is because go build isn't propagating the options that disable optimization as it tracks down and builds dependencies.

claim that:

  • If I tell  go build  to disable optimizations, it makes sense that optimizations should be disabled for everything it ends up building.

  • Therefore, this is a bug.

I'm writing here because I'm a Go n00b, and there may be something I'm missing.

Let me show my evidence...

Consider the following trivial Go project:

.
├── main.go
└── help
    └── help.go


Here's main.go:


package main

import "./help"

func main() {
    help.Help()
}


Here's help.go:


package help

import "fmt"

func Help() {
    fmt.Println("I'm helping")
}


Here's how I built the project:


go build -gcflags="-N -l" main.go


The -N option disables optimization, and the -l option disables inlining.

This produced an executable called main in my current directory (as expected).  I tried to debug this executable with delve and saw this:


$ dlv exec main
Type 'help' for list of commands.
(dlv) b main.main
Breakpoint 1 set at 0x108e83f for main.main() ./main.go:5
(dlv) c
> main.main() ./main.go:5 (hits goroutine(1):1 total:1) (PC: 0x108e83f)
     1: package main
     2:
     3: import "./help"
     4:
=>   5: func main() {
     6:     help.Help()
     7: }
(dlv) s
> main.main() ./main.go:6 (PC: 0x108e84b)
     1: package main
     2:
     3: import "./help"
     4:
     5: func main() {
=>   6:     help.Help()
     7: }
(dlv) s
> _/Users/pturley/Workspace/Go/src/debug-problem/help.Help() ./help/help.go:5 (PC: 0x108e76f)
Warning: debugging optimized function
     1: package help
     2:
     3: import "fmt"
     4:
=>   5: func Help() {
     6:     fmt.Println("I'm helping")
     7: }


Notice that main() isn't optimized (as expected), but Help() is optimized, and delve prints a warning about that.  If, for example, Help() had local variables, it would be unlikely you could view their values.

I tried building again with a few more options:


go build -a -x -gcflags="-N -l" main.go > log 2>&1


The -a option ensures Go doesn't rely on any cached build artifacts.  The -x option causes Go to print all commands before executing them.

Here's the command that built main.go (white space inserted to improve clarity):


/opt/local/lib/go/pkg/tool/darwin_amd64/compile
    -o $WORK/b001/_pkg_.a
    -trimpath $WORK/b001
    -N -l
    -p main
    -complete
    -buildid XMSzm8g7wNG80cfFP4Nw/XMSzm8g7wNG80cfFP4Nw
    -goversion go1.10
    -D _/Users/pturley/Workspace/Go/src/debug-problem
    -importcfg $WORK/b001/importcfg
    -pack -c=4
    ./main.go


Here's the command that built help.go:


/opt/local/lib/go/pkg/tool/darwin_amd64/compile
    -o $WORK/b002/_pkg_.a
    -trimpath $WORK/b002
    -p _/Users/pturley/Workspace/Go/src/debug-problem/help
    -complete
    -buildid Td3vdeSGgO-nwcrs810U/Td3vdeSGgO-nwcrs810U
    -goversion go1.10
    -D _/Users/pturley/Workspace/Go/src/debug-problem/help
    -importcfg $WORK/b002/importcfg
    -pack -c=4
    ./help.go


Note that the -N and -l options are missing in the latter command.  If they had been propagated by  go build (which I claim makes the most sense), all my code would be debuggable.

matthe...@gmail.com

unread,
Mar 15, 2018, 3:16:37 PM3/15/18
to golang-nuts
This looks like it changed between 1.9.4 and 1.10.


I guess the package patterns thing is new. Try this:

go build -a -x -gcflags=“all=-N -l”

Matt

Patrick Turley

unread,
Mar 15, 2018, 4:36:58 PM3/15/18
to golang-nuts
Indeed -- that pattern made the difference.

Thank you.

Florin Pățan

unread,
Mar 16, 2018, 3:37:30 AM3/16/18
to golang-nuts
My understanding is that you do not need -a anymore, just the rest of the flags.

jake...@gmail.com

unread,
Mar 16, 2018, 11:53:18 AM3/16/18
to golang-nuts
For completeness, this is documented in the 1.10 release notes. See the second paragraph of this section: https://golang.org/doc/go1.10#build.
Reply all
Reply to author
Forward
0 new messages