Golang FuncForPC示例

说明

golang funcforpc示例是从最受好评的开源项目中提取的实现代码,你可以参考下面示例的使用方式。

编程语言: Golang

命名空间/包名称: runtime

示例#1
文件: SFDebug.go 项目: slowfei/gosfcore

//	break
func Break(format bool, v ...interface{}) {

	fmt.Println("Variables:")
	Fdump(os.Stdout, format, v...)

	var pc, file, line, ok = runtime.Caller(1)
	if ok {
		fmt.Printf("\n\n[Debug] %s() [%s:%d]\n[Stack]\n", runtime.FuncForPC(pc).Name(), file, line)
	}

	for i := 2; ; i++ {
		pc, file, line, ok := runtime.Caller(i)
		if !ok {
			break
		}
		fn := runtime.FuncForPC(pc).Name()
		if 0 != len(file) {
			//	/usr/local/go/src/pkg/runtime/proc.c:1223 (0x173d0)
			fmt.Printf("%s(...)\n%s:%d (0x%x)\n", fn, file, line, pc)
		} else {
			// 	runtime.goexit(...)
			// 	L1223: runtime.goexit(...) (0x173d0)
			fmt.Printf("L%d: %s(...) (0x%x)\n", line, fn, pc)
		}
	}

	fmt.Println("\nPress Enter to Continue")
	fmt.Scanln()
	fmt.Println("Break End...")
}

示例#2
文件: gocheck.go 项目: evaluation-alex/gosync

func (c *C) logCaller(skip int) {
	// This is a bit heavier than it ought to be.
	skip += 1 // Our own frame.
	pc, callerFile, callerLine, ok := runtime.Caller(skip)
	if !ok {
		return
	}
	var testFile string
	var testLine int
	testFunc := runtime.FuncForPC(c.method.PC())
	if runtime.FuncForPC(pc) != testFunc {
		for {
			skip += 1
			if pc, file, line, ok := runtime.Caller(skip); ok {
				// Note that the test line may be different on
				// distinct calls for the same test.  Showing
				// the "internal" line is helpful when debugging.
				if runtime.FuncForPC(pc) == testFunc {
					testFile, testLine = file, line
					break
				}
			} else {
				break
			}
		}
	}
	if testFile != "" && (testFile != callerFile || testLine != callerLine) {
		c.logCode(testFile, testLine)
	}
	c.logCode(callerFile, callerLine)
}

示例#3
文件: terst.go 项目: henrylee2cn/godocdown

func (self *Tester) findDepth() int {
	height := 1 // Skip us
	for {
		pc, _, _, ok := runtime.Caller(height)
		function := runtime.FuncForPC(pc)
		if !ok {
			// Got too close to the sun
			if false {
				for ; height > 0; height-- {
					pc, _, _, ok := runtime.Caller(height)
					fmt.Printf("[%d %v %v]", height, pc, ok)
					if ok {
						function := runtime.FuncForPC(pc)
						fmt.Printf(" => [%s]", function.Name())
					}
					fmt.Printf("\n")
				}
			}
			return 1
		}
		functionEntry := function.Entry()
		if functionEntry == self.focusEntry || functionEntry == self.testEntry {
			return height - 1 // Not the surrounding test function, but within it
		}
		height += 1
	}
	return 1
}

示例#4
文件: logger.go 项目: MoonighT/logger

func getActualCaller() (file string, line int, ok bool) {
	cpc, _, _, ok := runtime.Caller(2)
	if !ok {
		return
	}

	callerFunPtr := runtime.FuncForPC(cpc)
	if callerFunPtr == nil {
		ok = false
		return
	}

	var pc uintptr
	for callLevel := 3; callLevel < 5; callLevel++ {
		pc, file, line, ok = runtime.Caller(callLevel)
		if !ok {
			return
		}
		funcPtr := runtime.FuncForPC(pc)
		if funcPtr == nil {
			ok = false
			return
		}
		if getFuncNameWithoutPackage(funcPtr.Name()) !=
			getFuncNameWithoutPackage(callerFunPtr.Name()) {
			return
		}
	}
	ok = false
	return
}

示例#5
文件: t_run.go 项目: magastzheng/go-2

func test2() {
	pc, file, line, ok := runtime.Caller(2)
	log.Println(pc)
	log.Println(file)
	log.Println(line)
	log.Println(ok)
	f := runtime.FuncForPC(pc)
	log.Println(f.Name())

	pc, file, line, ok = runtime.Caller(0)
	log.Println(pc)
	log.Println(file)
	log.Println(line)
	log.Println(ok)
	f = runtime.FuncForPC(pc)
	log.Println(f.Name())

	pc, file, line, ok = runtime.Caller(1)
	log.Println(pc)
	log.Println(file)
	log.Println(line)
	log.Println(ok)
	f = runtime.FuncForPC(pc)
	log.Println(f.Name())
}

示例#6
文件: stat_holder.go 项目: yoshiharay/fabric

func getCallerInfo() string {
	pc := make([]uintptr, 10)
	// Note: the default value 4 will ensure stat name exclude the path
	// "/perfstat.UpdateTimeStat -> /perfstat.updateStat -> /perfstat.getCallerInfo"
	// "/perfstat.UpdateDataStat -> /perfstat.updateStat -> /perfstat.getCallerInfo"
	runtime.Callers(4, pc)
	var path bytes.Buffer
	j := 0
	for i := range pc {
		f := runtime.FuncForPC(pc[i])
		funcName := f.Name()
		if strings.HasPrefix(funcName, commonPrefix) {
			j = i
		} else {
			break
		}
	}

	for i := j; i >= 0; i-- {
		f := runtime.FuncForPC(pc[i])
		funcName := f.Name()
		funcNameShort := funcName[commonPrefixLen:]
		path.WriteString(funcNameShort)
		if i > 0 {
			path.WriteString(" -> ")
		}
	}

	return path.String()
}

示例#7
文件: stack.go 项目: CadeLaRen/docker-3

// Format formats the frame according to the fmt.Formatter interface.
//
//    %s    source file
//    %d    source line
//    %n    function name
//    %v    equivalent to %s:%d
//
// Format accepts flags that alter the printing of some verbs, as follows:
//
//    %+s   path of source file relative to the compile time GOPATH
//    %+v   equivalent to %+s:%d
func (f Frame) Format(s fmt.State, verb rune) {
	switch verb {
	case 's':
		switch {
		case s.Flag('+'):
			pc := f.pc()
			fn := runtime.FuncForPC(pc)
			if fn == nil {
				io.WriteString(s, "unknown")
			} else {
				file, _ := fn.FileLine(pc)
				fmt.Fprintf(s, "%s\n\t%s", fn.Name(), file)
			}
		default:
			io.WriteString(s, path.Base(f.file()))
		}
	case 'd':
		fmt.Fprintf(s, "%d", f.line())
	case 'n':
		name := runtime.FuncForPC(f.pc()).Name()
		io.WriteString(s, funcname(name))
	case 'v':
		f.Format(s, 's')
		io.WriteString(s, ":")
		f.Format(s, 'd')
	}
}

示例#8
文件: gocheck.go 项目: nuin/ampify

func (c *C) logCaller(skip int, issue string) {
	// This is a bit heavier than it ought to be.
	skip += 1 // Our own frame.
	if pc, callerFile, callerLine, ok := runtime.Caller(skip); ok {
		var testFile string
		var testLine int
		testFunc := runtime.FuncForPC(c.method.Get())
		if runtime.FuncForPC(pc) != testFunc {
			for {
				skip += 1
				if pc, file, line, ok := runtime.Caller(skip); ok {
					// Note that the test line may be different on
					// distinct calls for the same test.  Showing
					// the "internal" line is helpful when debugging.
					if runtime.FuncForPC(pc) == testFunc {
						testFile, testLine = file, line
						break
					}
				} else {
					break
				}
			}
		}
		if testFile != "" && (testFile != callerFile ||
			testLine != callerLine) {
			c.logf("%s:%d > %s:%d:\n... %s", nicePath(testFile), testLine,
				nicePath(callerFile), callerLine, issue)
		} else {
			c.logf("%s:%d:\n... %s", nicePath(callerFile), callerLine, issue)
		}
	}
}

示例#9
文件: track_raft_protos.go 项目: CubeLite/cockroach

// TrackRaftProtos instruments proto marshalling to track protos which are
// marshalled downstream of raft. It returns a function that removes the
// instrumentation and returns the list of downstream-of-raft protos.
func TrackRaftProtos() func() []reflect.Type {
	// Grab the name of the function that roots all raft operations.
	applyRaftFunc := runtime.FuncForPC(reflect.ValueOf((*Replica).executeBatch).Pointer()).Name()
	// Some raft operations trigger gossip, but we don't care about proto
	// serialization in gossip, so we're going to ignore it.
	addInfoFunc := runtime.FuncForPC(reflect.ValueOf((*gossip.Gossip).AddInfoProto).Pointer()).Name()

	belowRaftProtos := struct {
		sync.Mutex
		inner map[reflect.Type]struct{}
	}{
		inner: make(map[reflect.Type]struct{}),
	}

	protoutil.Interceptor = func(pb proto.Message) {
		t := reflect.TypeOf(pb)

		belowRaftProtos.Lock()
		_, ok := belowRaftProtos.inner[t]
		belowRaftProtos.Unlock()
		if ok {
			return
		}

		pcs := make([]uintptr, 100)
		numCallers := runtime.Callers(0, pcs)
		if numCallers == len(pcs) {
			panic(fmt.Sprintf("number of callers %d might have exceeded slice size %d", numCallers, len(pcs)))
		}
		for _, pc := range pcs[:numCallers] {
			funcName := runtime.FuncForPC(pc).Name()
			if strings.Contains(funcName, addInfoFunc) {
				break
			}
			if strings.Contains(funcName, applyRaftFunc) {
				belowRaftProtos.Lock()
				belowRaftProtos.inner[t] = struct{}{}
				belowRaftProtos.Unlock()

				break
			}
		}
	}

	return func() []reflect.Type {
		protoutil.Interceptor = func(_ proto.Message) {}

		belowRaftProtos.Lock()
		types := make([]reflect.Type, 0, len(belowRaftProtos.inner))
		for t := range belowRaftProtos.inner {
			types = append(types, t)
		}
		belowRaftProtos.Unlock()

		return types
	}
}

示例#10
文件: timeout.go 项目: pengzhai/tchannel

// getCallerName returns the test name that called this function.
// It traverses the stack to find the function name directly after a testing.* call.
func getCallerName() string {
	pc := make([]uintptr, 10)
	n := runtime.Callers(2, pc)
	for i := n; i > 0; i-- {
		fname := runtime.FuncForPC(pc[i-1]).Name()
		if strings.HasPrefix(fname, "testing.") {
			return runtime.FuncForPC(pc[i-2]).Name()
		}
	}
	return "unknown"
}

示例#11
文件: cdrv.go 项目: rahul-goqt/goqt

func DefaultErrorHandler(err error, typeid, funcid int32, call int) {
	pc1, _, _, ok1 := runtime.Caller(call)
	fn1 := runtime.FuncForPC(pc1)
	pc2, file, line, ok2 := runtime.Caller(call + 1)
	fn2 := runtime.FuncForPC(pc2)
	if ok1 && ok2 {
		log.Printf("err:%s, type:%d, func:%d; %s, %s , %s, %d \n", err, typeid, funcid, fn1.Name(), fn2.Name(), file, line)
	} else {
		log.Printf("err:%s, type:%d, func:%d\n", err, typeid, funcid)
	}
}

示例#12
文件: handler.go 项目: thevermi/rbot

func handlePrivmsg(conn *irc.Conn, line *irc.Line) {
	nick := conn.GetNick(line.Nick)
	if nick == nil {
		return
	}
	nick.Host = line.Host
	if ignores[conn.Network][nick.Host] {
		return
	}

	defer func() {
		if r := recover(); r != nil {
			fmt.Println("Recovered from", r)
			callers := make([]uintptr, 10)
			runtime.Callers(4, callers)
			cutoff := runtime.FuncForPC(reflect.ValueOf(handlePrivmsg).Pointer()).Entry()
			for _, pc := range callers {
				function := runtime.FuncForPC(pc - 1)
				if function.Entry() == cutoff {
					break
				}
				file, line := function.FileLine(pc - 1)
				fmt.Printf("%s:%d\n\t%s\n", file, line, function.Name())
			}
		}
	}()

	target := line.Args[0]
	if isChannel(target) {
		// message to a channel
		if !command(conn, nick, line.Args[1], target) {
			var video string
			if start := strings.Index(line.Args[1], "youtube.com/watch?"); start > -1 {
				start = strings.Index(line.Args[1], "v=")
				video = line.Args[1][start+2:]
			}
			if start := strings.Index(line.Args[1], "youtu.be/"); start > -1 {
				video = line.Args[1][start+9:]
			}
			if video != "" {
				if end := strings.IndexAny(video, " &#"); end > -1 {
					video = video[0:end]
				}
				youtube(conn, nick, video, target)

			} else {
				command(conn, nick, line.Args[1], target)
			}
		}
	} else if target == conn.Me.Nick {
		// message to us
		command(conn, nick, line.Args[1], line.Nick)
	}
}

示例#13
文件: trace_test.go 项目: CowLeo/distribution

// TestWithTrace ensures that tracing has the expected values in the context.
func TestWithTrace(t *testing.T) {
	pc, file, _, _ := runtime.Caller(0) // get current caller.
	f := runtime.FuncForPC(pc)

	base := []valueTestCase{
		{
			key:           "trace.id",
			notnilorempty: true,
		},

		{
			key:           "trace.file",
			expected:      file,
			notnilorempty: true,
		},
		{
			key:           "trace.line",
			notnilorempty: true,
		},
		{
			key:           "trace.start",
			notnilorempty: true,
		},
	}

	ctx, done := WithTrace(Background())
	defer done("this will be emitted at end of test")

	checkContextForValues(t, ctx, append(base, valueTestCase{
		key:      "trace.func",
		expected: f.Name(),
	}))

	traced := func() {
		parentID := ctx.Value("trace.id") // ensure the parent trace id is correct.

		pc, _, _, _ := runtime.Caller(0) // get current caller.
		f := runtime.FuncForPC(pc)
		ctx, done := WithTrace(ctx)
		defer done("this should be subordinate to the other trace")
		time.Sleep(time.Second)
		checkContextForValues(t, ctx, append(base, valueTestCase{
			key:      "trace.func",
			expected: f.Name(),
		}, valueTestCase{
			key:      "trace.parent.id",
			expected: parentID,
		}))
	}
	traced()

	time.Sleep(time.Second)
}

示例#14
文件: stack_test.go 项目: DanielHeckrath/short

func TestCallFormat(t *testing.T) {
	t.Parallel()

	c := stack.Caller(0)
	pc, file, line, ok := runtime.Caller(0)
	line--
	if !ok {
		t.Fatal("runtime.Caller(0) failed")
	}
	relFile := path.Join(importPath, filepath.Base(file))

	c2, pc2, file2, line2, ok2 := testType{}.testMethod()
	if !ok2 {
		t.Fatal("runtime.Caller(0) failed")
	}
	relFile2 := path.Join(importPath, filepath.Base(file2))

	data := []struct {
		c    stack.Call
		desc string
		fmt  string
		out  string
	}{
		{stack.Call{}, "error", "%s", "%!s(NOFUNC)"},

		{c, "func", "%s", path.Base(file)},
		{c, "func", "%+s", relFile},
		{c, "func", "%#s", file},
		{c, "func", "%d", fmt.Sprint(line)},
		{c, "func", "%n", "TestCallFormat"},
		{c, "func", "%+n", runtime.FuncForPC(pc - 1).Name()},
		{c, "func", "%v", fmt.Sprint(path.Base(file), ":", line)},
		{c, "func", "%+v", fmt.Sprint(relFile, ":", line)},
		{c, "func", "%#v", fmt.Sprint(file, ":", line)},

		{c2, "meth", "%s", path.Base(file2)},
		{c2, "meth", "%+s", relFile2},
		{c2, "meth", "%#s", file2},
		{c2, "meth", "%d", fmt.Sprint(line2)},
		{c2, "meth", "%n", "testType.testMethod"},
		{c2, "meth", "%+n", runtime.FuncForPC(pc2).Name()},
		{c2, "meth", "%v", fmt.Sprint(path.Base(file2), ":", line2)},
		{c2, "meth", "%+v", fmt.Sprint(relFile2, ":", line2)},
		{c2, "meth", "%#v", fmt.Sprint(file2, ":", line2)},
	}

	for _, d := range data {
		got := fmt.Sprintf(d.fmt, d.c)
		if got != d.out {
			t.Errorf("fmt.Sprintf(%q, Call(%s)) = %s, want %s", d.fmt, d.desc, got, d.out)
		}
	}
}

示例#15
文件: pprof_test.go 项目: ds2dev/gcc

// Test that profiler does not observe runtime.gogo as "user" goroutine execution.
// If it did, it would see inconsistent state and would either record an incorrect stack
// or crash because the stack was malformed.
func TestGoroutineSwitch(t *testing.T) {
	if runtime.GOOS == "windows" {
		t.Skip("flaky test; see http://golang.org/issue/6417")
	}
	// How much to try. These defaults take about 1 seconds
	// on a 2012 MacBook Pro. The ones in short mode take
	// about 0.1 seconds.
	tries := 10
	count := 1000000
	if testing.Short() {
		tries = 1
	}
	for try := 0; try < tries; try++ {
		var prof bytes.Buffer
		if err := StartCPUProfile(&prof); err != nil {
			t.Fatal(err)
		}
		for i := 0; i < count; i++ {
			runtime.Gosched()
		}
		StopCPUProfile()

		// Read profile to look for entries for runtime.gogo with an attempt at a traceback.
		// The special entry
		parseProfile(t, prof.Bytes(), func(count uintptr, stk []uintptr) {
			// An entry with two frames with 'System' in its top frame
			// exists to record a PC without a traceback. Those are okay.
			if len(stk) == 2 {
				f := runtime.FuncForPC(stk[1])
				if f != nil && f.Name() == "System" {
					return
				}
			}

			// Otherwise, should not see runtime.gogo.
			// The place we'd see it would be the inner most frame.
			f := runtime.FuncForPC(stk[0])
			if f != nil && f.Name() == "runtime.gogo" {
				var buf bytes.Buffer
				for _, pc := range stk {
					f := runtime.FuncForPC(pc)
					if f == nil {
						fmt.Fprintf(&buf, "%#x ?:0\n", pc)
					} else {
						file, line := f.FileLine(pc)
						fmt.Fprintf(&buf, "%#x %s:%d\n", pc, file, line)
					}
				}
				t.Fatalf("found profile entry for runtime.gogo:\n%s", buf.String())
			}
		})
	}
}

示例#16
文件: dochandler.go 项目: DaviWei/utils-1

/*
Document will take a func, a path, a set of methods (separated by |) and a set of scopes that will be used when updating models in the func, and return a documented route and a function suitable for HandlerFunc.

The input func must match func(context JSONContextLogger) (status int, err error)

One extra input argument after context is allowed, and will be JSON decoded from the request body, and used in the documentation struct.

One extra return value between status and error is allowed, and will be JSON encoded to the response body, and used in the documentation struct.
*/
func Document(fIn interface{}, path string, methods string, minAPIVersion, maxAPIVersion int, scopes ...string) (docRoute *DefaultDocumentedRoute, fOut func(JSONContextLogger) (Resp, error)) {
	// first validate that the handler takes either a context, or a context and a decoded JSON body as argument
	if errs := utils.ValidateFuncInputs(fIn, []reflect.Type{
		reflect.TypeOf((*JSONContextLogger)(nil)).Elem(),
		reflect.TypeOf((*interface{})(nil)).Elem(),
	}, []reflect.Type{
		reflect.TypeOf((*JSONContextLogger)(nil)).Elem(),
	}); len(errs) == 2 {
		panic(fmt.Errorf("%v does not conform. Fix one of %+v", runtime.FuncForPC(reflect.ValueOf(fIn).Pointer()).Name(), errs))
	}
	// then validate that it returns either status, responde body object for JSON encoding and error, or just status and error
	if errs := utils.ValidateFuncOutputs(fIn, []reflect.Type{
		reflect.TypeOf(0),
		reflect.TypeOf((*interface{})(nil)).Elem(),
		reflect.TypeOf((*error)(nil)).Elem(),
	}, []reflect.Type{
		reflect.TypeOf(0),
		reflect.TypeOf((*error)(nil)).Elem(),
	}); len(errs) == 2 {
		panic(fmt.Errorf("%v does not conform. Fix one of %+v", runtime.FuncForPC(reflect.ValueOf(fIn).Pointer()).Name(), errs))
	}

	// then create the route object that we store for documentation purposes
	methodNames := strings.Split(methods, "|")
	docRoute = &DefaultDocumentedRoute{
		Path:          path,
		Methods:       methodNames,
		MinAPIVersion: minAPIVersion,
		MaxAPIVersion: maxAPIVersion,
		Scopes:        scopes,
	}
	// calculate the name of the function
	fName := runtime.FuncForPC(reflect.ValueOf(fIn).Pointer()).Name()
	if match := fNameReg.FindStringSubmatch(fName); match != nil {
		docRoute.Comment = fmt.Sprintf("%#v", match)
	}
	fVal := reflect.ValueOf(fIn)
	fType := fVal.Type()
	// if the handler takes two arguments (that is, one decoded JSON body), add an input param type to document with.
	// also send in the scopes, because the input type fields must be filtered so that those without scopes are ignored
	if fType.NumIn() == 2 {
		docRoute.In = newJSONType(true, fType.In(1), true, methodNames, scopes...)
	}
	// if the handler provides three return values (that is, one decoded JSON body), add an output param type to document with.
	if fType.NumOut() == 3 {
		docRoute.Out = newJSONType(false, fType.Out(1), false, methodNames)
	}

	fOut = CreateResponseFunc(fType, fVal)
	return
}

示例#17
文件: context.go 项目: rubycut/goconvey

// resolveTestPackageAndFunctionName traverses the call stack in reverse, looking for
// the go testing harnass call ("testing.tRunner") and then grabs the very next entry,
// which represents the package under test and the test function name. Voila!
func resolveTestPackageAndFunctionName() string {
	var callerId uintptr
	callers := runtime.Callers(0, callStack)

	for y := callers; y > 0; y-- {
		callerId, _, _, _ = runtime.Caller(y)
		packageAndTestFunctionName := runtime.FuncForPC(callerId).Name()
		if packageAndTestFunctionName == goTestHarness {
			callerId, _, _, _ = runtime.Caller(y - 1)
			name := runtime.FuncForPC(callerId).Name()
			return name
		}
	}
	panic("Can't resolve test method name! Are you calling Convey() from a `*_test.go` file and a `Test*` method (because you should be)?")
}

示例#18
文件: testsuite.go 项目: ConfusedReality/pkg_network_grpc

// When a test is skipped or fails, runtime.Goexit() is called which destroys the callstack.
// This means the name of the test case is lost, so we need to grab a copy of pc before.
func Report(t testing.TB) {
	// If the goroutine panics, Fatal()s, or Skip()s, the function name is at the 3rd callstack
	// layer.  On success, its at 1st.  Since it's hard to check which happened, just try both.
	pcs := make([]uintptr, 10)
	total := runtime.Callers(1, pcs)
	var name string
	for _, pc := range pcs[:total] {
		fn := runtime.FuncForPC(pc)
		fullName := fn.Name()
		if strings.HasPrefix(path.Ext(fullName), ".Test") {
			// Skip the leading .
			name = string([]byte(path.Ext(fullName))[1:])
			break
		}
	}
	if name == "" {
		return
	}

	allCaseInfos.lock.Lock()
	defer allCaseInfos.lock.Unlock()
	allCaseInfos.Cases = append(allCaseInfos.Cases, &caseInfo{
		Name:    name,
		Passed:  !t.Failed() && !t.Skipped(),
		Skipped: t.Skipped(),
		Fatal:   t.Failed() && !strings.HasPrefix(name, "TestSoon"),
	})
}

示例#19
文件: validation.go 项目: isdamir/gotool

func (v *Validation) apply(chk Validator, obj interface{}) *ValidationResult {
	if chk.IsSatisfied(obj) {
		return &ValidationResult{Ok: true}
	}

	//e.g key: validate.(*Validation).apply#84
	var key string
	if pc, _, line, ok := runtime.Caller(2); ok {
		f := runtime.FuncForPC(pc)
		key = f.Name() + "#" + strconv.Itoa(line)
	} else {
		log.Info("Failed to get Caller information to look up Validation key")
	}

	err := &ValidationError{
		Message: chk.DefaultMessage(),
		Key:     key,
	}
	v.Errors = append(v.Errors, err)

	return &ValidationResult{
		Ok:    false,
		Error: err,
	}
}

示例#20
文件: stacktrace.go 项目: palantir/stacktrace

func create(cause error, code ErrorCode, msg string, vals ...interface{}) error {
	// If no error code specified, inherit error code from the cause.
	if code == NoCode {
		code = GetCode(cause)
	}

	err := &stacktrace{
		message: fmt.Sprintf(msg, vals...),
		cause:   cause,
		code:    code,
	}

	// Caller of create is NewError or Propagate, so user's code is 2 up.
	pc, file, line, ok := runtime.Caller(2)
	if !ok {
		return err
	}
	if CleanPath != nil {
		file = CleanPath(file)
	}
	err.file, err.line = file, line

	f := runtime.FuncForPC(pc)
	if f == nil {
		return err
	}
	err.function = shortFuncName(f)

	return err
}

示例#21
文件: errored.go 项目: contiv/volplugin

func getStack(offset int) []errorStack {
	errors := []errorStack{}

	i := offset

	for {
		stack := errorStack{}
		pc, file, line, ok := runtime.Caller(i)
		if !ok {
			break
		}

		fun := runtime.FuncForPC(pc)
		if fun != nil {
			stack.fun = fun.Name()
		}

		stack.file = path.Base(file)
		stack.line = line
		errors = append(errors, stack)

		i++
	}

	return errors
}

示例#22
文件: echo.go 项目: efimovalex/EventKitAPI

func handlerName(h HandlerFunc) string {
	t := reflect.ValueOf(h).Type()
	if t.Kind() == reflect.Func {
		return runtime.FuncForPC(reflect.ValueOf(h).Pointer()).Name()
	}
	return t.String()
}

示例#23
文件: utils.go 项目: slygo/360baosdk

//代码执行位置
func CallerPosition() {
	funcName, file, line, ok := runtime.Caller(2)
	if ok {
		fmt.Println("程序名称:", runtime.FuncForPC(funcName).Name())
		fmt.Println("文件名称:", file+"\n", "程序行号:", line)
	}
}

示例#24
文件: format.go 项目: skycoin/skycoin-exchange

func formatCallpath(calldepth int) string {
	v := ""
	callers := make([]uintptr, 64)
	n := runtime.Callers(calldepth+2, callers)
	oldPc := callers[n-1]

	recursiveCall := false
	for i := n - 3; i >= 0; i-- {
		pc := callers[i]
		if oldPc == pc {
			recursiveCall = true
			continue
		}
		oldPc = pc
		if recursiveCall {
			recursiveCall = false
			v += ".."
		}
		if i < n-3 {
			v += "."
		}
		if f := runtime.FuncForPC(pc); f != nil {
			v += formatFuncName(fmtVerbShortfunc, f.Name())
		}
	}
	return v
}

示例#25
文件: utils.go 项目: pathletboy/errors

// name format:
// runtime.goexit
// runtime.main
// main.init
// main.main
// main.init·1 -> main.init
// main.func·001 -> main.func
// github.com/chai2010/errors.New
// ...
func callerInfo(skip int) (name, file string, line int, ok bool) {
	pc, file, line, ok := runtime.Caller(skip)
	if !ok {
		name = "???"
		file = "???"
		line = 1
		return
	}

	name = runtime.FuncForPC(pc).Name()
	if reInit.MatchString(name) {
		name = reInit.ReplaceAllString(name, "init")
	}
	if reClosure.MatchString(name) {
		name = reClosure.ReplaceAllString(name, "func")
	}

	// Truncate file name at last file name separator.
	if idx := strings.LastIndex(file, "/"); idx >= 0 {
		file = file[idx+1:]
	} else if idx = strings.LastIndex(file, "\\"); idx >= 0 {
		file = file[idx+1:]
	}
	return
}

示例#26
文件: orm_test.go 项目: 4eek/beego

func getCaller(skip int) string {
	pc, file, line, _ := runtime.Caller(skip)
	fun := runtime.FuncForPC(pc)
	_, fn := filepath.Split(file)
	data, err := ioutil.ReadFile(file)
	var codes []string
	if err == nil {
		lines := bytes.Split(data, []byte{'\n'})
		n := 10
		for i := 0; i < n; i++ {
			o := line - n
			if o < 0 {
				continue
			}
			cur := o + i + 1
			flag := "  "
			if cur == line {
				flag = ">>"
			}
			code := fmt.Sprintf(" %s %5d:   %s", flag, cur, strings.Replace(string(lines[o+i]), "\t", "    ", -1))
			if code != "" {
				codes = append(codes, code)
			}
		}
	}
	funName := fun.Name()
	if i := strings.LastIndex(funName, "."); i > -1 {
		funName = funName[i+1:]
	}
	return fmt.Sprintf("%s:%d: \n%s", fn, line, strings.Join(codes, "\n"))
}

示例#27
文件: main.go 项目: BVNK/bank

func trace() (funcTrace string) {
	pc := make([]uintptr, 10) // at least 1 entry needed
	runtime.Callers(2, pc)
	f := runtime.FuncForPC(pc[0])
	file, line := f.FileLine(pc[0])
	return fmt.Sprintf("%s:%d %s", file, line, f.Name())
}

示例#28
文件: bugsnag.go 项目: refiito/pipes-api

func getStacktrace(err error) []bugsnagStacktrace {
	var stacktrace []bugsnagStacktrace
	if serr, ok := err.(*bugsnagError); ok {
		return serr.stacktrace
	}
	i := 0
	for {
		if pc, file, line, ok := runtime.Caller(i); !ok {
			break
		} else {
			methodName := "unnamed"
			if f := runtime.FuncForPC(pc); f != nil {
				methodName = f.Name()
			}
			traceLine := bugsnagStacktrace{
				File:       file,
				LineNumber: strconv.Itoa(line),
				Method:     methodName,
			}
			stacktrace = append(stacktrace, traceLine)
		}
		i += 1
	}
	return stacktrace
}

示例#29
文件: validation.go 项目: purohit/revel

func (v *Validation) apply(chk Validator, obj interface{}) *ValidationResult {
	if chk.IsSatisfied(obj) {
		return &ValidationResult{Ok: true}
	}

	// Get the default key.
	var key string
	if pc, _, line, ok := runtime.Caller(2); ok {
		f := runtime.FuncForPC(pc)
		if defaultKeys, ok := DefaultValidationKeys[f.Name()]; ok {
			key = defaultKeys[line]
		}
	} else {
		INFO.Println("Failed to get Caller information to look up Validation key")
	}

	// Add the error to the validation context.
	err := &ValidationError{
		Message: chk.DefaultMessage(),
		Key:     key,
	}
	v.Errors = append(v.Errors, err)

	// Also return it in the result.
	return &ValidationResult{
		Ok:    false,
		Error: err,
	}
}

示例#30
文件: timedmutex.go 项目: veteranlu/cockroach

// ThresholdLogger returns a timing function which calls 'record' for each
// measured duration and, for measurements exceeding 'warnDuration', invokes
// 'printf' with the passed context and a detailed stack trace.
func ThresholdLogger(
	ctx context.Context,
	warnDuration time.Duration,
	printf func(context.Context, string, ...interface{}),
	record TimingFn,
) TimingFn {
	return func(heldFor time.Duration) {
		record(heldFor)
		if heldFor > warnDuration {
			// NB: this doesn't use `util/caller.Lookup` because that would result
			// in an import cycle.
			pc, _, _, ok := runtime.Caller(2)
			fun := "?"
			if ok {
				if f := runtime.FuncForPC(pc); f != nil {
					fun = f.Name()
				}
			}

			printf(
				ctx, "mutex held by %s for %s (>%s):\n%s",
				fun, heldFor, warnDuration, debug.Stack(),
			)
		}
	}
}

展开阅读全文