From 92a0ff1e1e2f61773648454ec71ec0c0f1c700a2 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 27 Feb 2019 16:14:45 +0100 Subject: [PATCH] cpu: don't panic on error reading /proc/self/auxv On Android /proc/self/auxv is not readable, leading to a panic in init. Instead of panic'ing in this case, introduce the Initialized global bool to report whether the CPU features were initialized i.e. /proc/self/auxv was successfullly read. Fixes golang/go#30413 Change-Id: Ib520f202990614a76bceb0bf9d19a88eadd13e10 Reviewed-on: https://go-review.googlesource.com/c/164057 Reviewed-by: Brad Fitzpatrick Reviewed-by: Ian Lance Taylor --- cpu/cpu.go | 7 +++++++ cpu/cpu_linux.go | 6 +++++- cpu/cpu_test.go | 3 +++ cpu/cpu_x86.go | 2 ++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/cpu/cpu.go b/cpu/cpu.go index 6b0034ec..e3a2c4c8 100644 --- a/cpu/cpu.go +++ b/cpu/cpu.go @@ -6,6 +6,13 @@ // various CPU architectures. package cpu +// Initialized reports whether the CPU features were initialized. +// +// For some GOOS/GOARCH combinations initialization of the CPU features depends +// on reading an operating specific file, e.g. /proc/self/auxv on linux/arm +// Initialized will report false if reading the file fails. +var Initialized bool + // CacheLinePad is used to pad structs to avoid false sharing. type CacheLinePad struct{ _ [cacheLineSize]byte } diff --git a/cpu/cpu_linux.go b/cpu/cpu_linux.go index 33b61e52..76b5f507 100644 --- a/cpu/cpu_linux.go +++ b/cpu/cpu_linux.go @@ -28,7 +28,9 @@ var hwCap2 uint func init() { buf, err := ioutil.ReadFile(procAuxv) if err != nil { - panic("read proc auxv failed: " + err.Error()) + // e.g. on android /proc/self/auxv is not accessible, so silently + // ignore the error and leave Initialized = false + return } bo := hostByteOrder() @@ -52,4 +54,6 @@ func init() { } } doinit() + + Initialized = true } diff --git a/cpu/cpu_test.go b/cpu/cpu_test.go index e4b0f0d1..c0d8f640 100644 --- a/cpu/cpu_test.go +++ b/cpu/cpu_test.go @@ -13,6 +13,9 @@ import ( func TestAMD64minimalFeatures(t *testing.T) { if runtime.GOARCH == "amd64" { + if !cpu.Initialized { + t.Fatal("Initialized expected true, got false") + } if !cpu.X86.HasSSE2 { t.Fatal("HasSSE2 expected true, got false") } diff --git a/cpu/cpu_x86.go b/cpu/cpu_x86.go index 2b3ca2e1..d70d317f 100644 --- a/cpu/cpu_x86.go +++ b/cpu/cpu_x86.go @@ -9,6 +9,8 @@ package cpu const cacheLineSize = 64 func init() { + Initialized = true + maxID, _, _, _ := cpuid(0, 0) if maxID < 1 {