Skip to content

Commit bee8ae1

Browse files
committed
runtime: send android stderr to /dev/log/main
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]>
1 parent 6820be2 commit bee8ae1

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

src/runtime/print1.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func gwrite(b []byte) {
7575
}
7676
gp := getg()
7777
if gp == nil || gp.writebuf == nil {
78-
write(2, unsafe.Pointer(&b[0]), int32(len(b)))
78+
writeErr(b)
7979
return
8080
}
8181

src/runtime/print1_write.go

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// +build !android
2+
3+
package runtime
4+
5+
import "unsafe"
6+
7+
func writeErr(b []byte) {
8+
write(2, unsafe.Pointer(&b[0]), int32(len(b)))
9+
}

src/runtime/print1_write_android.go

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package runtime
2+
3+
import "unsafe"
4+
5+
var (
6+
writeHeader = []byte{6 /* ANDROID_LOG_ERROR */, 'G', 'o', 0}
7+
writePath = []byte("/dev/log/main\x00")
8+
writeFD uintptr
9+
writeBuf [1024]byte
10+
writePos int
11+
)
12+
13+
func writeErr(b []byte) {
14+
// Log format: "<priority 1 byte><tag n bytes>\x00<message m bytes>\x00"
15+
// The entire log needs to be delivered in a single syscall (the NDK
16+
// does this with writev). Each log is its own line, so we need to
17+
// buffer writes until we see a newline.
18+
if writeFD == 0 {
19+
writeFD = uintptr(open(&writePath[0], 0x1 /* O_WRONLY */, 0))
20+
if writeFD == 0 {
21+
// It is hard to do anything here. Write to stderr just
22+
// in case user has root on device and has run
23+
// adb shell setprop log.redirect-stdio true
24+
msg := []byte("runtime: cannot open /dev/log/main\x00")
25+
write(2, unsafe.Pointer(&msg[0]), int32(len(msg)))
26+
exit(2)
27+
}
28+
copy(writeBuf[:], writeHeader)
29+
}
30+
dst := writeBuf[len(writeHeader):]
31+
for _, v := range b {
32+
if v == 0 { // android logging won't print a zero byte
33+
v = '0'
34+
}
35+
dst[writePos] = v
36+
writePos++
37+
if v == '\n' || writePos == len(dst)-1 {
38+
dst[writePos] = 0
39+
write(writeFD, unsafe.Pointer(&writeBuf[0]), int32(len(writeHeader)+writePos))
40+
memclrBytes(dst)
41+
writePos = 0
42+
}
43+
}
44+
}

0 commit comments

Comments
 (0)