Bug with 'time.Sleep()' in go or in wine?

445 views
Skip to first unread message

leonb...@gmail.com

unread,
Mar 22, 2015, 7:00:52 PM3/22/15
to golan...@googlegroups.com
Hi all,

When I compile this simple program and run it under wine (1.7, ubuntu 14.04) it hangs indefinitely:

package main

import (
"fmt"
"time"
)

func main() {
fmt.Println("before")
fmt.Println(time.Now())
time.Sleep(10 * time.Second)
fmt.Println(time.Now())
fmt.Println("after")
}

Is there a way I could debug this? Can somebody else reproduce this behavior?

I tried cross-compiling it on my linux laptop and under Windows but it doesn't make a difference: it hangs. When run on Windows it works fine.

Also what's weird: if I use the syscall Sleep (from the windows api) the sleep works but time.Now() isn't updated and gives the same date+time as the before call.

Brad Fitzpatrick

unread,
Mar 22, 2015, 7:20:11 PM3/22/15
to leonb...@gmail.com, golang-nuts
Works on Linux and Windows, so I assume it's a bug in wine.



--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

brainman

unread,
Mar 22, 2015, 7:42:32 PM3/22/15
to golan...@googlegroups.com, leonb...@gmail.com
On Monday, 23 March 2015 10:00:52 UTC+11, leonb...@gmail.com wrote:

What version of Go do you use?

Alex 

minux

unread,
Mar 22, 2015, 10:58:50 PM3/22/15
to leonb...@gmail.com, golang-nuts
On Sun, Mar 22, 2015 at 7:00 PM, <leonb...@gmail.com> wrote:
When I compile this simple program and run it under wine (1.7, ubuntu 14.04) it hangs indefinitely:

package main

import (
"fmt"
"time"
)

func main() {
fmt.Println("before")
fmt.Println(time.Now())
time.Sleep(10 * time.Second)
fmt.Println(time.Now())
fmt.Println("after")
}

Is there a way I could debug this? Can somebody else reproduce this behavior?

I tried cross-compiling it on my linux laptop and under Windows but it doesn't make a difference: it hangs. When run on Windows it works fine.

There used to be a bug in Go's runtime that fails to maintain required stack alignment
when calling windows syscall (ntdll exported functions). It's #8174.

Perhaps you're hit by that issue. Try again with Go 1.4.2 if you're using earlier version
(the bug is first fixed in Go 1.4)

I've heard that Go programs that use network doesn't work properly in wine too. But
as the program works perfectly under Windows. I'm inclined to say that it's wine's bug
unless proved otherwise.

Generally, the windows port of Go targets the real windows, not wine.

Rich

unread,
Mar 23, 2015, 6:30:41 AM3/23/15
to golan...@googlegroups.com, leonb...@gmail.com
Just to add in... runs fine on my Mac...

[rmasci@rm-Mac ~/go] $ go run time.go
before
2015-03-23 06:29:18.732602392 -0400 EDT
2015-03-23 06:29:28.733808749 -0400 EDT
after
[rmasci@rm-Mac ~/go]

leonb...@gmail.com

unread,
Mar 23, 2015, 1:19:43 PM3/23/15
to golan...@googlegroups.com, leonb...@gmail.com
What version of Go do you use?

1.4.2 

leonb...@gmail.com

unread,
Mar 23, 2015, 1:48:13 PM3/23/15
to golan...@googlegroups.com, leonb...@gmail.com
I've opened a bug on the wine bugtracker: https://bugs.winehq.org/show_bug.cgi?id=38272

Brad Fitzpatrick

unread,
Mar 23, 2015, 3:14:25 PM3/23/15
to leonb...@gmail.com, golang-nuts
The third comment is interesting:


I guess Wine doesn't provide that interface.

If they're unable to do so, it's possible that the Go runtime could be modified to know when it's running on Wine and do something else, but it's not clear a) that it's worth it (why slow down real Windows users for wine users, especially since Go already runs natively on ~everything), and b) that we'd ever be done. There might just always be another wine compatibility thing to work around? I haven't used Wine ~15 years. It's probably much better nowadays.


On Mon, Mar 23, 2015 at 10:48 AM, <leonb...@gmail.com> wrote:
I've opened a bug on the wine bugtracker: https://bugs.winehq.org/show_bug.cgi?id=38272

--

minux

unread,
Mar 23, 2015, 4:56:20 PM3/23/15
to Brad Fitzpatrick, Leon Bogaert, golang-nuts
On Mon, Mar 23, 2015 at 3:14 PM, Brad Fitzpatrick <brad...@golang.org> wrote:
The third comment is interesting:


I guess Wine doesn't provide that interface.

If they're unable to do so, it's possible that the Go runtime could be modified to know when it's running on Wine and do something else, but it's not clear a) that it's worth it (why slow down real Windows users for wine users, especially since Go already runs natively on ~everything), and b) that we'd ever be done. There might just always be another wine compatibility thing to work around? I haven't used Wine ~15 years. It's probably much better nowadays.

I vote for no Wine specific workarounds.

Of course it's possible for wine to implement that feature. mmap a page with no read permission
there and trap every read to that region, and in the signal handler, emulate the read instruction
and update the thread context. It's a lot of work, but Wine is supposed to emulate Windows, so
it should do that even if it's inefficient. I can't think of any reason to use wine to run performance
critical Go programs (why not just run Go natively?)

leonb...@gmail.com

unread,
Mar 23, 2015, 6:37:54 PM3/23/15
to golan...@googlegroups.com, brad...@golang.org, leonb...@gmail.com
I can't think of any reason to use wine to run performance
critical Go programs (why not just run Go natively?)

In my case it's to interface with a "Linux" game that uses wine. I need some Windows syscalls to read a memory mapped file. If it's a lot of work to implement I understand why this wouldn't be implemented. Would be nice though.

brainman

unread,
Mar 23, 2015, 10:38:57 PM3/23/15
to golan...@googlegroups.com, leonb...@gmail.com
On Tuesday, 24 March 2015 06:14:25 UTC+11, bradfitz wrote:
The third comment is interesting:


I guess Wine doesn't provide that interface.


We are using undocumented / unofficial interface. So that is not surprising.
 
If they're unable to do so, it's possible that the Go runtime could be modified to know when it's running on Wine and do something else, ...

It could be simple enough to implement. It does not have to slow anything down.

I will go with whatever decision you (people on this thread) will make.

Alex

Govert Versluis

unread,
Mar 24, 2015, 8:41:57 AM3/24/15
to golan...@googlegroups.com, leonb...@gmail.com
Does this mean that this interface might break in a future version of Windows as well?
In that case it might be worth it to develop the workaround (which is actually the proper way of doing things) so that any breakage can quickly be solved?

brainman

unread,
Mar 24, 2015, 6:50:03 PM3/24/15
to golan...@googlegroups.com, leonb...@gmail.com
On Tuesday, 24 March 2015 23:41:57 UTC+11, Govert Versluis wrote:
> Does this mean that this interface might break in a future version of Windows as well?

Sure. It is "undocumented" facility, so Microsoft can change / remove it any time. But I suspect we're not the only ones who use this trick. I don't think Microsoft want to break other people's programs.

Alex

Lars Seipel

unread,
Mar 24, 2015, 8:32:25 PM3/24/15
to leonb...@gmail.com, golan...@googlegroups.com, brad...@golang.org
On Mon, Mar 23, 2015 at 03:37:45PM -0700, leonb...@gmail.com wrote:
> In my case it's to interface with a "Linux" game that uses wine. I need
> some Windows syscalls to read a memory mapped file.

Why can't you just make your Go program do what Wine would do to emulate
those Windows syscalls?

Brad Fitzpatrick

unread,
Mar 24, 2015, 8:35:34 PM3/24/15
to Lars Seipel, Leon Bogaert, golang-nuts
We're doing system calls on Windows. And the way Wine would emulate it is to call do Linux or other Unix-specific things.

Lars Seipel

unread,
Mar 24, 2015, 9:10:04 PM3/24/15
to Brad Fitzpatrick, Leon Bogaert, golang-nuts
Yeah, it wasn't meant as a suggestion for the Go runtime (you ended up
in CC just because of Reply-All) but for Leon's specific usecase:
instead of compiling the program for Windows and running it on Linux
using Wine, compile for native Linux and use Linux syscalls to interact
with that Winelib-using game.

leonb...@gmail.com

unread,
Mar 25, 2015, 4:27:47 AM3/25/15
to golan...@googlegroups.com, leonb...@gmail.com, brad...@golang.org
Why can't you just make your Go program do what Wine would do to emulate
those Windows syscalls?

If that would be possible that would be awesome. But I couldn't find a way to do it. These are the syscall's I need: https://github.com/LeonB/irsdk-go/blob/master/test.go#L193+L198

leonb...@gmail.com

unread,
Mar 25, 2015, 7:09:59 PM3/25/15
to golan...@googlegroups.com, leonb...@gmail.com
What are the arguments against using QPC?

brainman

unread,
Mar 25, 2015, 7:36:31 PM3/25/15
to golan...@googlegroups.com, leonb...@gmail.com
On Thursday, 26 March 2015 10:09:59 UTC+11, leonb...@gmail.com wrote:
What are the arguments against using QPC?

Lars Seipel

unread,
Mar 25, 2015, 9:37:55 PM3/25/15
to leonb...@gmail.com, golan...@googlegroups.com
On Wed, Mar 25, 2015 at 01:27:30AM -0700, leonb...@gmail.com wrote:
> If that would be possible that would be awesome. But I couldn't find a way
> to do it. These are the syscall's I
> need: https://github.com/LeonB/irsdk-go/blob/master/test.go#L193+L198

Luckily, the Wine people have a nice cross-referenced copy of their
sources online.

http://source.winehq.org/WineAPI/OpenFileMappingW.html
http://source.winehq.org/WineAPI/MapViewOfFile.html

Starting there, you see that those forward to NtOpenSection and
NtMapViewOfSection, defined in:
http://source.winehq.org/source/dlls/ntdll/virtual.c#2553

As one would expect this ends up calling mmap with some file descriptor
(plus lots of impedance matching between the different APIs). When using
Wine that file descriptor is obtained through a Unix socket from the
"Wine server", which I guess is some thing that keeps inter-process
state that on Windows would be handled by the kernel.

But maybe that's not even necessary. When looking at a python library
found through Google (github.com/kutu/pyirsdk, the game is iRacing,
right?) there doesn't seem to be any extensive interaction between the
game and the client code. After "mmap-ing" (using some python mmap
module) the file it just starts reading from that.

That "Local\\IRSDKMemMapFileName" path, how is that handled by Wine?
Look around in /dev/shm, /tmp or whereever Wine keeps its stuff and see
if you can find something that corresponds to it. Note that this might
change with future Wine updates, though.

You could also try calling out to Winelib using cgo (make it use
winegcc). Actually, that might be the most straightforward solution, now
that I think of it. It's probably also the one most likely to keep
working with future changes to Wine.

leonb...@gmail.com

unread,
Mar 26, 2015, 5:51:28 PM3/26/15
to golan...@googlegroups.com, leonb...@gmail.com
Luckily, the Wine people have a nice cross-referenced copy of their
sources online.

http://source.winehq.org/WineAPI/OpenFileMappingW.html
http://source.winehq.org/WineAPI/MapViewOfFile.html

Starting there, you see that those forward to NtOpenSection and
NtMapViewOfSection, defined in:
http://source.winehq.org/source/dlls/ntdll/virtual.c#2553

As one would expect this ends up calling mmap with some file descriptor
(plus lots of impedance matching between the different APIs). When using
Wine that file descriptor is obtained through a Unix socket from the
"Wine server", which I guess is some thing that keeps inter-process
state that on Windows would be handled by the kernel.

I don't think I'm smart enough to port that piece of code to go :( 


But maybe that's not even necessary. When looking at a python library
found through Google (github.com/kutu/pyirsdk, the game is iRacing,
right?) there doesn't seem to be any extensive interaction between the
game and the client code. After "mmap-ing" (using some python mmap
module) the file it just starts reading from that.

Nice find. This was exactly what I was trying to do. However that python code will only run on Windows because of mmap.mmap() and the tagname parameter: https://docs.python.org/2/library/mmap.html
 

That "Local\\IRSDKMemMapFileName" path, how is that handled by Wine?
Look around in /dev/shm, /tmp or whereever Wine keeps its stuff and see
if you can find something that corresponds to it. Note that this might
change with future Wine updates, though.

Yeah, that was my first try. I believe when the iracing game starts up a shm segment is added. But I think the windows syscalls do something else. Because if I request the memory address with MapViewOfFile and write that address down and then directly try to access that address without the windows syscalls the piece of memory wouldn't 'map' (don't know how you call that) to the irsdk_header struct. I also asked one the wine-devel mailing list if there was some way to access that piece of memory with linux only calls but I didn't get a response to that question.
 

You could also try calling out to Winelib using cgo (make it use
winegcc). Actually, that might be the most straightforward solution, now
that I think of it. It's probably also the one most likely to keep
working with future changes to Wine.

I think you're on to something here. I did briefly try winelib yesterday evening but I couldn't get it to work properly. I thought it was a mismatch between the version of winelib and the version of wine (actually crossover office) bundled with wine. But I'll have another (better) look at it this evening. If winelib would work that would be the nicest solution in my opinion.

Thanks for thinking along! 
Reply all
Reply to author
Forward
0 new messages