Skip to content

cmd/5l: cross-compiling on Windows 64 for arm with CGO_ENABLED=1 5l.exe always fails with "stack overflow" exception #8723

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

Closed
gopherbot opened this issue Sep 14, 2014 · 11 comments

Comments

@gopherbot
Copy link
Contributor

by mike0berg:

Description:

go version go1.3.1 windows/amd64 built with x86_64-w64-mingw32 (gcc version 4.8.2),
cross environment targeting linux/arm (cross compiler Linaro gcc version 4.8.4 20140811)

When biding simple cgo program (go build test) on Windowss 64 targetting linux/arm:

package main

/*
char* foo(void) { return "hello, world!"; }
*/
import "C"

import "fmt"

func main() {
  fmt.Println(C.GoString(C.foo()))
} 

last build step (5l) always fails with 0xC00000FD - Stack overflow. Running windbg shows
very long stack trace (same addresses, different parameters). Checking with mingw gdb
shows SEGFAULT.

This happens after external linked has been invoked and all work already done, basically
during call to errorexit() in pobj.c program segfaults on call to exit(0).

If I specify linkmode=internal build succeeds and resulting ./test properly runs on
targeted arm environment.
@ianlancetaylor
Copy link
Contributor

Comment 1:

Labels changed: added repo-main, release-go1.4, os-windows.

@rsc
Copy link
Contributor

rsc commented Sep 15, 2014

Comment 2:

Will fix by rewriting linker in Go, which can use bigger stacks.

Labels changed: added release-none, removed release-go1.4.

@gopherbot
Copy link
Contributor Author

Comment 3 by mike0berg:

Could you please explain why you think stack is an issue here? I am sure I am missing
something, however exactly the same problem exists when I use Windows 386 build as a
host. More than that: if I run "go build -work test" and grab a.out from _obj/exe
directory - it runs perfectly on the target platform. I tried this with program more
complex than "Hello world" - for example one that opens sqllite database end executes
simple query. Looks like linking is actually done and there is an error somewhere which
results in a stack corruption...

@gopherbot
Copy link
Contributor Author

Comment 4 by mike0berg:

I think I traced the problem to its origin and it has nothing to do with rewriting
linker in go. 
As far as I could see there is a bug in lib9 in implementation of removeall() function
(file tempdir_windows.c). Windows calls FindFirstFileW/FindNextFileW do not return full
file path in cFileName member of WIN32_FIND_DATAW structure, only the last part of it -
base name. As the result strrchr(q, '\\') always returns NULL pointer and removeall()
calls itself recursively with directory name "." until stack is exhausted completely.
Nothing gets removed.
Even after this is fixed temporary directory is not removed because go.o never closed 
by linker and Windows does not allow removal of opened file (file is locked).
This could be easily confirmed by looking at user's temporary directory.
Please, find attached a simple patch to correct both of those problems - I think this
issue could be closed now.

Attachments:

  1. go_131_windows.patch (954 bytes)

@ianlancetaylor
Copy link
Contributor

Comment 5:

Thanks for investigating this.  If you could submit your patch using the process
described at http://golang.org/doc/contribute.html , that would be very helpful.  Thanks.

Status changed to Accepted.

@gopherbot
Copy link
Contributor Author

Comment 6 by mike0berg:

I am sorry - I looked at http://golang.org/doc/contribute.html and at the moment it is a
bit overwhelming. I am not planning to perform any "real" work on go implementation
itself and 6 line patch for dying code base (since you are rewriting linker in Go
anyways) does not seems to warrant spending any additional time on this (beyond 2 days I
already spent tracking the problem).

@ianlancetaylor
Copy link
Contributor

Comment 7:

OK, I'll take care of it.

@gopherbot
Copy link
Contributor Author

Comment 8:

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

@gopherbot
Copy link
Contributor Author

Comment 9 by mike0berg:

I may be wrong here, but I do not think that your change to lib.c would work - since in
your change removeall still sequentially gets called with last part of the path only.
And since files for removal are not in current directory it will silently fail leaving
junk around. Having
+       char *qt = toutf(data.cFileName);
+       q = smprint("%s\\%s", p, qt);
+       free(qt);
is essential. You prevent the recursion, but do not delete files themselves!

@ianlancetaylor
Copy link
Contributor

Comment 10:

Good point, thanks for following up.  I updated the patch.

@ianlancetaylor
Copy link
Contributor

Comment 11:

This issue was closed by revision 5a40b56.

Status changed to Fixed.

@golang golang locked and limited conversation to collaborators Jun 25, 2016
wheatman pushed a commit to wheatman/go-akaros that referenced this issue Jun 25, 2018
This fixes a couple of problems that occur when the linker
removes its temporary directory on Windows.  The linker only
creates and removes a temporary directory when doing external
linking.  Windows does not yet support external linking.
Therefore, these problems are only seen when using a
cross-compiler hosted on Windows.

In lib9, FindFirstFileW returns just the file name, not the
full path name.  Don't assume that we will find a slash.
Changed the code to work either way just in case.

In ld, Windows requires that files be closed before they are
removed, so close the output file before we might try to
remove it.

Fixes golang#8723.

LGTM=alex.brainman
R=golang-codereviews, alex.brainman
CC=golang-codereviews
https://golang.org/cl/141690043
wheatman pushed a commit to wheatman/go-akaros that referenced this issue Jul 9, 2018
This fixes a couple of problems that occur when the linker
removes its temporary directory on Windows.  The linker only
creates and removes a temporary directory when doing external
linking.  Windows does not yet support external linking.
Therefore, these problems are only seen when using a
cross-compiler hosted on Windows.

In lib9, FindFirstFileW returns just the file name, not the
full path name.  Don't assume that we will find a slash.
Changed the code to work either way just in case.

In ld, Windows requires that files be closed before they are
removed, so close the output file before we might try to
remove it.

Fixes golang#8723.

LGTM=alex.brainman
R=golang-codereviews, alex.brainman
CC=golang-codereviews
https://golang.org/cl/141690043
wheatman pushed a commit to wheatman/go-akaros that referenced this issue Jul 30, 2018
This fixes a couple of problems that occur when the linker
removes its temporary directory on Windows.  The linker only
creates and removes a temporary directory when doing external
linking.  Windows does not yet support external linking.
Therefore, these problems are only seen when using a
cross-compiler hosted on Windows.

In lib9, FindFirstFileW returns just the file name, not the
full path name.  Don't assume that we will find a slash.
Changed the code to work either way just in case.

In ld, Windows requires that files be closed before they are
removed, so close the output file before we might try to
remove it.

Fixes golang#8723.

LGTM=alex.brainman
R=golang-codereviews, alex.brainman
CC=golang-codereviews
https://golang.org/cl/141690043
This issue was closed.
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

3 participants