mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/link, runtime: mark goexit as the top of the call stack
This CL adds a new attribute, TOPFRAME, which can be used to mark functions that should be treated as being at the top of the call stack. The function `runtime.goexit` has been marked this way on architectures that use a link register. This will stop programs that use DWARF to unwind the call stack from unwinding past `runtime.goexit` on architectures that use a link register. For example, it eliminates "corrupt stack?" warnings when generating a backtrace that hits `runtime.goexit` in GDB on s390x. Similar code should be added for non-link-register architectures (i.e. amd64, 386). They mark the top of the call stack slightly differently to link register architectures so I haven't added that code (they need to mark "rip" as undefined). Fixes #24385. Change-Id: I15b4c69ac75b491daa0acf0d981cb80eb06488de Reviewed-on: https://go-review.googlesource.com/c/go/+/169726 Run-TryBot: Michael Munday <mike.munday@ibm.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
0bd101cecc
commit
aafe257390
16 changed files with 75 additions and 12 deletions
|
|
@ -82,6 +82,22 @@ func checkGdbPython(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// checkCleanBacktrace checks that the given backtrace is well formed and does
|
||||
// not contain any error messages from GDB.
|
||||
func checkCleanBacktrace(t *testing.T, backtrace string) {
|
||||
backtrace = strings.TrimSpace(backtrace)
|
||||
lines := strings.Split(backtrace, "\n")
|
||||
if len(lines) == 0 {
|
||||
t.Fatalf("empty backtrace")
|
||||
}
|
||||
for i, l := range lines {
|
||||
if !strings.HasPrefix(l, fmt.Sprintf("#%v ", i)) {
|
||||
t.Fatalf("malformed backtrace at line %v: %v", i, l)
|
||||
}
|
||||
}
|
||||
// TODO(mundaym): check for unknown frames (e.g. "??").
|
||||
}
|
||||
|
||||
const helloSource = `
|
||||
import "fmt"
|
||||
import "runtime"
|
||||
|
|
@ -272,6 +288,11 @@ func testGdbPython(t *testing.T, cgo bool) {
|
|||
t.Fatalf("info locals failed: %s", bl)
|
||||
}
|
||||
|
||||
// Check that the backtraces are well formed.
|
||||
checkCleanBacktrace(t, blocks["goroutine 1 bt"])
|
||||
checkCleanBacktrace(t, blocks["goroutine 2 bt"])
|
||||
checkCleanBacktrace(t, blocks["goroutine 1 bt at the end"])
|
||||
|
||||
btGoroutine1Re := regexp.MustCompile(`(?m)^#0\s+(0x[0-9a-f]+\s+in\s+)?main\.main.+at`)
|
||||
if bl := blocks["goroutine 1 bt"]; !btGoroutine1Re.MatchString(bl) {
|
||||
t.Fatalf("goroutine 1 bt failed: %s", bl)
|
||||
|
|
@ -281,6 +302,7 @@ func testGdbPython(t *testing.T, cgo bool) {
|
|||
if bl := blocks["goroutine 2 bt"]; !btGoroutine2Re.MatchString(bl) {
|
||||
t.Fatalf("goroutine 2 bt failed: %s", bl)
|
||||
}
|
||||
|
||||
btGoroutine1AtTheEndRe := regexp.MustCompile(`(?m)^#0\s+(0x[0-9a-f]+\s+in\s+)?main\.main.+at`)
|
||||
if bl := blocks["goroutine 1 bt at the end"]; !btGoroutine1AtTheEndRe.MatchString(bl) {
|
||||
t.Fatalf("goroutine 1 bt at the end failed: %s", bl)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue