Commit 7deb28a5 authored by Kirill Smelkov's avatar Kirill Smelkov

xruntime: Switch to using runtime.Frame

As it was planned switch to using runtime.Frame instead of our
local imitation.

Add test to make sure we are not breaking anything.
Adjust users in exc.
parent 6cabc980
......@@ -20,6 +20,7 @@ package exc
import (
"fmt"
"runtime"
"strings"
"lab.nexedi.com/kirr/go123/my"
......@@ -36,11 +37,10 @@ func (e *Error) Error() string {
msgv := []string{}
msg := ""
for e != nil {
// TODO(go1.7) -> runtime.Frame (see xruntime.Traceback())
if f, ok := e.arg.(xruntime.Frame); ok {
if f, ok := e.arg.(runtime.Frame); ok {
//msg = f.Function
//msg = fmt.Sprintf("%s (%s:%d)", f.Function, f.File, f.Line)
msg = strings.TrimPrefix(f.Name(), _errorpkgdot) // XXX -> better prettyfunc
msg = strings.TrimPrefix(f.Function, _errorpkgdot) // XXX -> better prettyfunc
} else {
msg = fmt.Sprint(e.arg)
}
......@@ -159,7 +159,7 @@ func Addcallingcontext(topfunc string, e *Error) *Error {
seenraise := false
for _, f := range xruntime.Traceback(2) {
// do not show anything after raise*()
if !seenraise && strings.HasPrefix(f.Name(), _errorraise) {
if !seenraise && strings.HasPrefix(f.Function, _errorraise) {
seenraise = true
continue
}
......@@ -168,12 +168,12 @@ func Addcallingcontext(topfunc string, e *Error) *Error {
}
// do not go beyond topfunc
if topfunc != "" && f.Name() == topfunc {
if topfunc != "" && f.Function == topfunc {
break
}
// skip intermediates
if strings.HasSuffix(f.Name(), "_") { // XXX -> better skipfunc
if strings.HasSuffix(f.Function, "_") { // XXX -> better skipfunc
continue
}
......
......@@ -22,16 +22,9 @@ import (
"runtime"
)
// TODO(go1.7) goes away in favour of runtime.Frame
type Frame struct {
*runtime.Func
Pc uintptr
}
// get current calling traceback as []Frame
// Traceback returns current calling traceback as []runtime.Frame
// nskip meaning: the same as in runtime.Callers()
// TODO(go1.7) []Frame -> []runtime.Frame
func Traceback(nskip int) []Frame {
func Traceback(nskip int) []runtime.Frame {
// all callers
var pcv = []uintptr{0}
for {
......@@ -44,7 +37,6 @@ func Traceback(nskip int) []Frame {
}
// pcv -> frames
/*
framev := make([]runtime.Frame, 0, len(pcv))
frames := runtime.CallersFrames(pcv)
for more := true; more; {
......@@ -52,11 +44,6 @@ func Traceback(nskip int) []Frame {
frame, more = frames.Next()
framev = append(framev, frame)
}
*/
framev := make([]Frame, 0, len(pcv))
for _, pc := range pcv {
framev = append(framev, Frame{runtime.FuncForPC(pc), pc})
}
return framev
}
// Copyright (C) 2015-2017 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
// option) any later version, as published by the Free Software Foundation.
//
// You can also Link and Combine this program with other software covered by
// the terms of any of the Open Source Initiative approved licenses and Convey
// the resulting work. Corresponding source of such a combination shall include
// the source code for all other software used.
//
// This program is distributed WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// See COPYING file for full licensing terms.
package xruntime
import (
"runtime"
"testing"
"lab.nexedi.com/kirr/go123/my"
)
func f333(tb1, tb2 *[]runtime.Frame) {
// NOTE keeping tb1 and tb2 updates on the same line - so that .Line in both frames is the same
*tb1 = append(*tb1, my.Frame()); *tb2 = Traceback(1)
}
func f222(tb1, tb2 *[]runtime.Frame) {
*tb1 = append(*tb1, my.Frame()); f333(tb1, tb2)
}
func f111(tb1, tb2 *[]runtime.Frame) {
*tb1 = append(*tb1, my.Frame()); f222(tb1, tb2)
}
func TestTraceback(t *testing.T) {
var tb1, tb2 []runtime.Frame
f111(&tb1, &tb2)
if len(tb1) != 3 {
t.Fatal("len(tb1) = %v ; must be 3", len(tb1))
}
tb1[0], tb1[1], tb1[2] = tb1[2], tb1[1], tb1[0] // reverse
for i, f1 := range tb1 {
f2 := tb2[i]
// pc are different; everything else must be the same
f1.PC = 0
f2.PC = 0
if f1 != f2 {
t.Errorf("traceback #%v:\nhave %v\nwant %v", i, f2, f1)
}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment