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
x/exp/shiny/driver/x11driver: runtime error on centos-7 #15100
Comments
FYI, it's also present when using a
@nigeltao any idea? |
What is $HOME and $XAUTHORITY for both cases? For docker, it looks like $HOME is "/home", which looks weird. Are you running as root? (Sorry, I'm not very familiar with docker). On centos, could you strace both the xgb- and xgbutil-based programs and see what files they open, whose names look vaguely like "Xauthority"? |
Ah, never mind about the strace. I just read the first post again, and if you can get a window up, then xgb should have auth'd correctly, even if the window isn't painting properly. Hmm... |
just a small update. package main
import (
"fmt"
"image"
"image/color"
"image/draw"
"time"
"github.com/BurntSushi/xgbutil"
"github.com/BurntSushi/xgbutil/xevent"
"github.com/BurntSushi/xgbutil/xgraphics"
)
func main() {
const (
w = 150
h = 150
)
img := image.NewRGBA(image.Rect(0, 0, int(w), int(h)))
X, err := xgbutil.NewConn()
fatal(err)
ximg := xgraphics.New(X, img.Bounds())
wid := ximg.XShowExtra("foo", true)
go func() {
xevent.Main(X)
}()
ximg.XDraw()
ximg.XPaint(wid.Id)
fmt.Printf("window id: %v\n", wid.Id)
time.Sleep(2 * time.Second)
fmt.Printf("drawing white...\n")
draw.Draw(ximg, ximg.Bounds(), image.NewUniform(color.White), image.Point{0, 0}, draw.Src)
ximg.XDraw()
ximg.XPaint(wid.Id)
time.Sleep(5 * time.Second)
}
func fatal(err error) {
if err != nil {
panic(err)
}
} |
I'd still like to know what $HOME and $XAUTHORITY are, and whether you're running as root. |
inside the docker container, I get these:
inside a proper centos-7 VM, I am indeed running as
|
and, on another Centos-7 machine I have access to, as a regular user:
|
did a bit of print-foo debugging.
which correspond to: buf := make([]byte, 32)
err, seq = nil, 0
if _, err := io.ReadFull(c.conn, buf); err != nil {
Logger.Printf("A read error is unrecoverable: %s", err)
fmt.Printf("**** read error: %v\n", err)
c.eventChan <- err
c.Close()
continue
}
switch buf[0] {
case 0: // This is an error
// Use the constructor function for this error (that is auto
// generated) by looking it up by the error number.
newErrFun, ok := NewErrorFuncs[int(buf[1])]
if !ok {
Logger.Printf("BUG: Could not find error constructor function "+
"for error with number %d.", buf[1])
continue
}
err = newErrFun(buf)
seq = err.SequenceId()
fmt.Printf("--- case 0: err=%v seq=%v\nbuf=%v\n", err, seq, buf)
// This error is either sent to the event channel or a specific
// cookie's error channel below.
case 1: // This is a reply
seq = Get16(buf[2:])
// check to see if this reply has more bytes to be read
size := Get32(buf[4:])
if size > 0 {
byteCount := 32 + size*4
biggerBuf := make([]byte, byteCount)
copy(biggerBuf[:32], buf)
if _, err := io.ReadFull(c.conn, biggerBuf[32:]); err != nil {
Logger.Printf("A read error is unrecoverable: %s", err)
fmt.Printf("**** read-error: %v\n", err)
c.eventChan <- err
c.Close()
continue
}
replyBytes = biggerBuf
} else {
replyBytes = buf
}
fmt.Printf("--- case 1: err=%v seq=%v\n", err, seq)
// This reply is sent to its corresponding cookie below.
default: // This is an event
// Use the constructor function for this event (like for errors,
// and is also auto generated) by looking it up by the event number.
// Note that we AND the event number with 127 so that we ignore
// the most significant bit (which is set when it was sent from
// a SendEvent request).
evNum := int(buf[0] & 127)
newEventFun, ok := NewEventFuncs[evNum]
if !ok {
Logger.Printf("BUG: Could not find event construct function "+
"for event with number %d.", evNum)
fmt.Printf("*** could not find event construct[%d]\n", evNum)
continue
}
fmt.Printf("--- case default: err=%v evtnum=%v\n", err, evNum)
c.eventChan <- newEventFun(buf)
continue
}
fmt.Printf("----> cookies... (seq=%v err=%v)\n", seq, err)
// At this point, we have a sequence number and we're either
// processing an error or a reply, which are both responses to
// requests. So all we have to do is find the cookie corresponding
// to this error/reply, and send the appropriate data to it.
// In doing so, we make sure that any cookies that came before it
// are marked as successful if they are void and checked.
// If there's a cookie that requires a reply that is before this
// reply, then something is wrong.
for cookie := range c.cookieChan {
// This is the cookie we're looking for. Process and break.
if cookie.Sequence == seq {
if err != nil { // this is an error to a request
// synchronous processing
if cookie.errorChan != nil {
fmt.Printf("**** sync-cookie error: %v\n", err)
cookie.errorChan <- err
} else { // asynchronous processing
fmt.Printf("****cookie err: %v\n", err)
c.eventChan <- err
// if this is an unchecked reply, ping the cookie too
if cookie.pingChan != nil {
cookie.pingChan <- true
}
}
} else { // this is a reply
if cookie.replyChan == nil {
Logger.Printf("Reply with sequence id %d does not "+
"have a cookie with a valid reply channel.", seq)
continue
} else {
cookie.replyChan <- replyBytes
}
}
break
} hth, |
@sbinet: are you trying to use shiny with a remote display server? The 'afs' in your home path makes me think you are. |
@aarzilli dunno. with X11, remote, server and client have (to me) unclear semantics.
hth |
for all the variations of (centos-7) machines to which I ssh, the |
I can sympathize with this. So, the display server (ie the thing that puts stuff on the screen) you are trying to use is running on your local archlinux64b machine, the shiny program is running on a CentOS-7 machine you are ssh'ing into. This makes the display server "remote" wrt the shiny program. AFAIK this won't work, x11driver uses MIT-SHM to upload the image and MIT-SHM doesn't work without, you know, actual "shared memory" between the client and the display server. xgbutil and xgb examples work because they are using server side pixmaps (or whatever they are called, I'm not an expert). I guess it wouldn't be too much work to add PutImage as a fallback for uploading but remember that we're all getting waylanded soon and once we are in wayland-land there's no way remote display servers work. |
Change https://golang.org/cl/213199 mentions this issue: |
This PR implement the **TODO** in buffer.go: ``` // TODO: detect if the X11 server or connection cannot support SHM pixmaps, // and fall back to regular pixmaps. ``` It fixes the issues: [golang/go#15100](golang/go#15100) [aarzilli/gdlv#26](aarzilli/gdlv#26) [aarzilli/gdlv#5](aarzilli/gdlv#5) [oakmound#8](oakmound#8) @sbinet @aarzilli @200sc Change-Id: I7f157c95928ca5fde015935ea5fe1d1f8b03ea43 GitHub-Last-Rev: 0a5d514 GitHub-Pull-Request: #9 Reviewed-on: https://go-review.googlesource.com/c/exp/+/213199 Reviewed-by: Nigel Tao <nigeltao@golang.org>
Please answer these questions before submitting your issue. Thanks!
go version
)?$> go version go version go1.6 linux/amd64
go env
)?a window with 3 rounded squares.
an empty window (with whatever was displayed behind that window, captured into that window but not refreshed) and the following error:
$> ./main 2016/04/04 13:47:06 x11driver: xproto.WaitForEvent: BadAccess {NiceName: Access, Sequence: 17, BadValue: 92274692, MinorOpcode: 1, MajorOpcode: 130} 2016/04/04 13:47:06 x11driver: xproto.WaitForEvent: BadBadSeg {NiceName: BadSeg, Sequence: 21, BadValue: 92274691, MinorOpcode: 3, MajorOpcode: 130}
The "interesting" thing is that the pointer-painting example from
xgbutil
works correctly.So it presumably is some configuration issue on the
x11driver
end.(I tried replacing
xgb.NewConn()
withxgbutil.NewConn()
and adapt a bit, to no avail)The text was updated successfully, but these errors were encountered: