Skip to content

Commit

Permalink
runtime: send android stderr to /dev/log/main
Browse files Browse the repository at this point in the history
I tried to submit this in Go 1.4 as cl/107540044 but tripped over the
changes for getting C off the G stack. This is a rewritten version that
avoids cgo and works directly with the underlying log device.

Change-Id: I14c227dbb4202690c2c67c5a613d6c6689a6662a
Reviewed-on: https://go-review.googlesource.com/1285
Reviewed-by: Keith Randall <[email protected]>
  • Loading branch information
crawshaw committed Dec 10, 2014
1 parent 6820be2 commit bee8ae1
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/runtime/print1.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func gwrite(b []byte) {
}
gp := getg()
if gp == nil || gp.writebuf == nil {
write(2, unsafe.Pointer(&b[0]), int32(len(b)))
writeErr(b)
return
}

Expand Down
9 changes: 9 additions & 0 deletions src/runtime/print1_write.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// +build !android

package runtime

import "unsafe"

func writeErr(b []byte) {
write(2, unsafe.Pointer(&b[0]), int32(len(b)))
}
44 changes: 44 additions & 0 deletions src/runtime/print1_write_android.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package runtime

import "unsafe"

var (
writeHeader = []byte{6 /* ANDROID_LOG_ERROR */, 'G', 'o', 0}
writePath = []byte("/dev/log/main\x00")
writeFD uintptr
writeBuf [1024]byte
writePos int
)

func writeErr(b []byte) {
// Log format: "<priority 1 byte><tag n bytes>\x00<message m bytes>\x00"
// The entire log needs to be delivered in a single syscall (the NDK
// does this with writev). Each log is its own line, so we need to
// buffer writes until we see a newline.
if writeFD == 0 {
writeFD = uintptr(open(&writePath[0], 0x1 /* O_WRONLY */, 0))
if writeFD == 0 {
// It is hard to do anything here. Write to stderr just
// in case user has root on device and has run
// adb shell setprop log.redirect-stdio true
msg := []byte("runtime: cannot open /dev/log/main\x00")
write(2, unsafe.Pointer(&msg[0]), int32(len(msg)))
exit(2)
}
copy(writeBuf[:], writeHeader)
}
dst := writeBuf[len(writeHeader):]
for _, v := range b {
if v == 0 { // android logging won't print a zero byte
v = '0'
}
dst[writePos] = v
writePos++
if v == '\n' || writePos == len(dst)-1 {
dst[writePos] = 0
write(writeFD, unsafe.Pointer(&writeBuf[0]), int32(len(writeHeader)+writePos))
memclrBytes(dst)
writePos = 0
}
}
}

0 comments on commit bee8ae1

Please sign in to comment.