Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/link: source paths in binary distribution assume installation to specific directory #5533

Closed
alexbrainman opened this issue May 22, 2013 · 29 comments

Comments

@alexbrainman
Copy link
Member

Here to demonstrate:

$ mkdir ~/tmp
$ cd ~/tmp
$ zcat /tmp/go1.1.linux-386.tar.gz | tar x
$ export GOROOT=~/tmp/go
$ export PATH=$PATH:$GOROOT/bin/
$ mkdir a
$ cd a
$ cat >a.go
package main

import (
    "fmt"
)

func main() {
    fmt.Printf("Hello\n")
}
$ go build a.go
$ gdb a                                                                  
GNU gdb (Gentoo 7.3.1 p2) 7.3.1                                                         
     
Copyright (C) 2011 Free Software Foundation, Inc.                                       
     
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>;     
           
This is free software: you are free to change and redistribute it.                      
     
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"    
               
and "show warranty" for details.                                              
               
This GDB was configured as "i686-pc-linux-gnu".                               
               
For bug reporting instructions, please see:                                             
     
<http://bugs.gentoo.org/>;...                                                      
           
Reading symbols from /home/brainman/tmp/a/a...done.                                     
     
warning: /usr/local/go/src/pkg/runtime/runtime-gdb.py (referenced in
.debug_gdb_scripts): No such file or directory                                          
                              
(gdb) br main.main                                                                      
     
Breakpoint 1 at 0x8048c00: file /home/brainman/tmp/a/a.go, line 5.                      
     
(gdb) r                                                                                 
     
Starting program: /home/brainman/tmp/a/a                                                
     
                                                                                              
Breakpoint 1, main.main () at /home/brainman/tmp/a/a.go:5                               
     
5       func main() {                                                                   
     
(gdb) s                                                                                 
     
6               fmt.Printf("Hello\n")                                         
               
(gdb)                                                                                   
     
fmt.Printf (format=..., a=..., n=405032960, err=...)                                    
     
    at /usr/local/go/src/pkg/fmt/print.go:222                                                 
222     /usr/local/go/src/pkg/fmt/print.go: No such file or directory.                  
     
        in /usr/local/go/src/pkg/fmt/print.go                                                 
(gdb) q                                                                                 
     
A debugging session is active.                                                          
     
                                                                                              
        Inferior 1 [process 17239] will be killed.                                            
                                                                                              
Quit anyway? (y or n) y                                                                 
     
$                                                                        

We could stress that only /usr/local/go destination is supported. But this does not work
on windows, because our windows installer allows other path (then c:\go) to be specified.

Perhaps we could change our linker, so it rewrites these paths correctly.

Alex
@ianlancetaylor
Copy link
Contributor

Comment 1:

We can rewrite source paths using the P option to go pack.  Then you would have to set
the directory search path in gdb.

@alexbrainman
Copy link
Member Author

Comment 2:

Why would I need to fiddle with gdb? I have GOROOT set when I build the executable.
Shouldn't "go build" use GOROOT value and set all debug info accordingly? As far as I
can see, it uses whatever values were set when package binaries were created. That is
the purpose of GOROOT_FINAL. Isn't it? But it doesn't work very well in this situation.
Perhaps, we could just make linker smarter and drop GOROOT_FINAL altogether.
I suspect I miss something here. So help me please. Tank you.
Alex

@ianlancetaylor
Copy link
Contributor

Comment 3:

I probably don't understand the problem.
You seem to be saying that the Windows installer permits the user to select the
directory where Go should be installed.  If that directory is not /usr/local/go, then
gdb is unable to find runtime-gdb.py, and it is unable to find the source code for the
standard library.  Is that an accurate description of the problem?

@alexbrainman
Copy link
Member Author

Comment 4:

That is accurate description of the problem (the /usr/local/go directory on windows is
called c:\go).
Also runtime.Caller is wrong too.
Alex

@ianlancetaylor
Copy link
Contributor

Comment 5:

In that case it seems to me that the most natural fix is to rewrite the debug info in
the packages during the install.  Perhaps we can use go tool pack -P, perhaps we need to
add another go tool pack option.

@ianlancetaylor
Copy link
Contributor

Comment 6:

Labels changed: added priority-later, os-windows, removed priority-triage.

@alexbrainman
Copy link
Member Author

Comment 7:

What does "during the install" mean? I think we should do it every time we create an
executable.
Alex

@ianlancetaylor
Copy link
Contributor

Comment 8:

When I said "during the install" I mean "when the Windows installer is installing Go." 
That is, fix it once, for the location where the files are installed.

@alexbrainman
Copy link
Member Author

Comment 9:

I am not sure if it possible - I know nothing about our installer. What about zip file?
Who is going to "fix" extracted files? Same for linux archive. That means all binaries
distos must be installed at particular location.
Alex

@ianlancetaylor
Copy link
Contributor

Comment 10:

I also know nothing about our installer, but I feel confident that it must be able to
run programs after installing the files.

@alexbrainman
Copy link
Member Author

Comment 11:

What about my proposal to rewrite these path during build process?
You suggested to use "pack -P" for that, but I don't think this will work. "pack -P"
allows only single replacement, and "go" command uses it to replace $WORK path while it
builds executables. Also, looking at the source code for "pack -P", I don't see that it
can handle windows paths. I am surprised we didn't see any complains about that, but I
logged an issue https://golang.org/issue/5550.
What about making linker do the job?
Alex

@ianlancetaylor
Copy link
Contributor

Comment 12:

I don't understand why adjusting the path every time we build is preferable to adjusting
the path once at install time.
But I don't plan on doing this work myself, so, whatever.

@rsc
Copy link
Contributor

rsc commented Jul 30, 2013

Comment 13:

Labels changed: added go1.2maybe.

Status changed to Accepted.

@rsc
Copy link
Contributor

rsc commented Jul 30, 2013

Comment 14:

Labels changed: added feature.

@alexbrainman
Copy link
Member Author

Comment 15:

rsc,
There are 2 problems here:
1) when building binary windows distro, we have
C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist357622851/go instead of c:\go written into
all lib files - this is because GOROOT -> GOROOT_FINAL substitution logic does not work
for windows paths in [568][acg];
2) dwarf source paths cannot be used if windows binary distro is installed anywhere but
c:\go - I reported it separately  https://golang.org/issue/5533
Perhaps we should create a new issue for 1) and close this one. Or change this issue
subject to 1). Pick what you like.
Alex

@alexbrainman
Copy link
Member Author

Comment 16:

Ignore my previous comment. It should be somewhere else.
Alex

@robpike
Copy link
Contributor

robpike commented Aug 30, 2013

Comment 17:

Not for 1.2.

Labels changed: removed go1.2maybe.

@rsc
Copy link
Contributor

rsc commented Nov 27, 2013

Comment 18:

Labels changed: added go1.3maybe.

@rsc
Copy link
Contributor

rsc commented Nov 27, 2013

Comment 19:

Labels changed: removed feature.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 20:

Labels changed: added release-none, removed go1.3maybe.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 21:

Labels changed: added repo-main.

@rsc
Copy link
Contributor

rsc commented Apr 16, 2014

Comment 22:

The binary distributions expect to be installed in /usr/local/go. We're very upfront
about that. If they are installed elsewhere then things don't work as well. In
particular, source line information is wrong for the compiled packages. I don't think we
intend to change that.
I just wrote godoc.org/code.google.com/p/rsc/cmd/editpcln that edits the pcln tables for
Go 1.3 archives. You could use it to download a binary Go 1.3 distribution and replace
/usr/local/go with a different prefix. Since we're just shipping tar files, I doubt we
would include this in the Unix distributions, but perhaps it would make sense in the
Windows distributions. (Or perhaps not.)
If nothing else, something to keep in mind for Go 1.4.

Labels changed: removed os-windows.

@alexbrainman
Copy link
Member Author

Comment 23:

I am fine with requiring to install into /usr/local/go. But then our Windows Install
package shouldn't provide option to "install into directory of your choice". Because not
everyone installs into c:\go, and when they install into different directory, things get
out of place. gdb would be broken then.
Alex

@rsc rsc added this to the Unplanned milestone Apr 10, 2015
@rsc rsc removed accepted labels Apr 14, 2015
@rsc rsc changed the title cmd/ld: source paths in binary distribution assume installation to specific directory cmd/link: source paths in binary distribution assume installation to specific directory Jun 8, 2015
@kormat
Copy link

kormat commented Dec 29, 2015

I have (presumably) the same problem on linux: i installed go in ~/opt/go, set $GOROOT to that dir, but go build still hardcodes the wrong .debug_gdb_scripts path into binaries (/usr/local/go/src/runtime/runtime-gdb.py).

@davecheney
Copy link
Contributor

@kormat if you are building Go from source, it is recommended to build Go in it's final destination. If that is not possible you should set GOROOT_FINAL to the destination, then after building Go move it to that location taking care to not touch any timestamps.

@kormat
Copy link

kormat commented Dec 29, 2015

@davecheney - i'm just using the tarball directly from https://golang.org/dl/

@davecheney
Copy link
Contributor

@kormat in that case I appolgise, I have no workaround for the gdb issue.

@rsc
Copy link
Contributor

rsc commented Dec 29, 2015

I prepared a CL to use $GOROOT for the location of the gdb script. That will help with finding the gdb script. The source line information for the standard library will still point at /usr/local/go but maybe that's not as big a deal.

@gopherbot
Copy link

CL https://golang.org/cl/18200 mentions this issue.

@rsc rsc closed this as completed in 83746fd Jan 4, 2016
@golang golang locked and limited conversation to collaborators Jan 4, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants