File: 0003-fix-gccgo.patch

package info (click to toggle)
runc 1.0.0~rc93%2Bds1-5
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, sid
  • size: 3,172 kB
  • sloc: sh: 1,679; ansic: 1,039; makefile: 139
file content (90 lines) | stat: -rw-r--r-- 3,032 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
From: Shengjing Zhu <zhsj@debian.org>
Date: Mon, 27 Apr 2020 13:41:27 +0800
Subject: fix gccgo

Forwarded: https://github.com/opencontainers/runc/pull/2355
---
 libcontainer/stacktrace/capture.go      | 21 ++++++++++++---------
 libcontainer/stacktrace/capture_test.go |  4 ++--
 libcontainer/stacktrace/frame.go        | 15 +++++----------
 3 files changed, 19 insertions(+), 21 deletions(-)

diff --git a/libcontainer/stacktrace/capture.go b/libcontainer/stacktrace/capture.go
index 0bbe149..522fbbe 100644
--- a/libcontainer/stacktrace/capture.go
+++ b/libcontainer/stacktrace/capture.go
@@ -7,19 +7,22 @@ import "runtime"
 // skip is the number of frames to skip
 func Capture(userSkip int) Stacktrace {
 	var (
-		skip   = userSkip + 1 // add one for our own function
+		skip   = userSkip + 2 // add one for our own function, one for runtime.Callers
 		frames []Frame
-		prevPc uintptr
 	)
-	for i := skip; ; i++ {
-		pc, file, line, ok := runtime.Caller(i)
-		//detect if caller is repeated to avoid loop, gccgo
-		//currently runs  into a loop without this check
-		if !ok || pc == prevPc {
+
+	pc := make([]uintptr, 10)
+	n := runtime.Callers(skip, pc)
+	if n == 0 {
+		return Stacktrace{}
+	}
+	f := runtime.CallersFrames(pc)
+	for {
+		frame, more := f.Next()
+		frames = append(frames, newFrame(frame))
+		if !more {
 			break
 		}
-		frames = append(frames, NewFrame(pc, file, line))
-		prevPc = pc
 	}
 	return Stacktrace{
 		Frames: frames,
diff --git a/libcontainer/stacktrace/capture_test.go b/libcontainer/stacktrace/capture_test.go
index 978f6c4..efa72c7 100644
--- a/libcontainer/stacktrace/capture_test.go
+++ b/libcontainer/stacktrace/capture_test.go
@@ -21,8 +21,8 @@ func TestCaptureTestFunc(t *testing.T) {
 	if expected := "captureFunc"; frame.Function != expected {
 		t.Fatalf("expected function %q but received %q", expected, frame.Function)
 	}
-	expected := "/runc/libcontainer/stacktrace"
-	if !strings.HasSuffix(frame.Package, expected) {
+	// captureFunc is inlined in gccgo, so don't expect the full package path
+	if expected := "stacktrace"; !strings.HasSuffix(frame.Package, expected) {
 		t.Fatalf("expected package %q but received %q", expected, frame.Package)
 	}
 	if expected := "capture_test.go"; frame.File != expected {
diff --git a/libcontainer/stacktrace/frame.go b/libcontainer/stacktrace/frame.go
index 0d590d9..a5d718b 100644
--- a/libcontainer/stacktrace/frame.go
+++ b/libcontainer/stacktrace/frame.go
@@ -6,18 +6,13 @@ import (
 	"strings"
 )
 
-// NewFrame returns a new stack frame for the provided information
-func NewFrame(pc uintptr, file string, line int) Frame {
-	fn := runtime.FuncForPC(pc)
-	if fn == nil {
-		return Frame{}
-	}
-	pack, name := parseFunctionName(fn.Name())
+func newFrame(frame runtime.Frame) Frame {
+	pack, name := parseFunctionName(frame.Function)
 	return Frame{
-		Line:     line,
-		File:     filepath.Base(file),
-		Package:  pack,
+		File:     filepath.Base(frame.File),
 		Function: name,
+		Package:  pack,
+		Line:     frame.Line,
 	}
 }