浏览代码

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 <bradfitz@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Tobias Klauser 6 年之前
父节点
当前提交
92a0ff1e1e
共有 4 个文件被更改,包括 17 次插入1 次删除
  1. 7 0
      cpu/cpu.go
  2. 5 1
      cpu/cpu_linux.go
  3. 3 0
      cpu/cpu_test.go
  4. 2 0
      cpu/cpu_x86.go

+ 7 - 0
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 }
 

+ 5 - 1
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
 }

+ 3 - 0
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")
 		}

+ 2 - 0
cpu/cpu_x86.go

@@ -9,6 +9,8 @@ package cpu
 const cacheLineSize = 64
 
 func init() {
+	Initialized = true
+
 	maxID, _, _, _ := cpuid(0, 0)
 
 	if maxID < 1 {