Beispiel #1
0
// printStackRecord prints the function + source line information
// for a single stack trace.
func printStackRecord(w io.Writer, stk []uintptr, allFrames bool) {
	show := allFrames
	frames := runtime.CallersFrames(stk)
	for {
		frame, more := frames.Next()
		name := frame.Function
		if name == "" {
			show = true
			fmt.Fprintf(w, "#\t%#x\n", frame.PC)
		} else if name != "runtime.goexit" && (show || !strings.HasPrefix(name, "runtime.")) {
			// Hide runtime.goexit and any runtime functions at the beginning.
			// This is useful mainly for allocation traces.
			show = true
			fmt.Fprintf(w, "#\t%#x\t%s+%#x\t%s:%d\n", frame.PC, name, frame.PC-frame.Entry, frame.File, frame.Line)
		}
		if !more {
			break
		}
	}
	if !show {
		// We didn't print anything; do it again,
		// and this time include runtime functions.
		printStackRecord(w, stk, true)
		return
	}
	fmt.Fprintf(w, "\n")
}
Beispiel #2
0
func (self *NotifierTrace) AddRuntimeFrames(frames *runtime.Frames) error {
	if self.Frames != nil {
		return errors.New("Already added frames")
	}

	if frames == nil {
		pc := make([]uintptr, 100, 100)
		num := runtime.Callers(3, pc)
		frames = runtime.CallersFrames(pc[:num])
	}

	notif_frames := make([]*NotifierFrame, 0, 100)
	for {
		fr, more := frames.Next()
		notif_frames = append(
			notif_frames,
			&NotifierFrame{
				Filename: fr.File,
				Line:     fr.Line,
				Method:   fr.Function,
			},
		)

		if !more {
			break
		}
	}

	self.Frames = notif_frames

	return nil
}
Beispiel #3
0
//export G2
func G2() {
	pc := make([]uintptr, 32)
	n := runtime.Callers(0, pc)
	cf := runtime.CallersFrames(pc[:n])
	var frames []runtime.Frame
	for {
		frame, more := cf.Next()
		frames = append(frames, frame)
		if !more {
			break
		}
	}

	want := []struct {
		function string
		line     int
	}{
		{"main.G2", 0},
		{"cFunction", 0x10200},
		{"cFunction", 0x200},
		{"cFunction", 0x10201},
		{"cFunction", 0x201},
		{"main.G1", 0},
		{"cFunction", 0x10100},
		{"cFunction", 0x100},
		{"main.TracebackContext", 0},
	}

	ok := true
	i := 0
wantLoop:
	for _, w := range want {
		for ; i < len(frames); i++ {
			if w.function == frames[i].Function {
				if w.line != 0 && w.line != frames[i].Line {
					fmt.Printf("found function %s at wrong line %#x (expected %#x)\n", w.function, frames[i].Line, w.line)
					ok = false
				}
				i++
				continue wantLoop
			}
		}
		fmt.Printf("did not find function %s in\n", w.function)
		for _, f := range frames {
			fmt.Println(f)
		}
		ok = false
		break
	}
	tracebackOK = ok
	if got := C.getContextCount(); got != 2 {
		fmt.Printf("at bottom contextCount == %d, expected 2\n", got)
		tracebackOK = false
	}
}
Beispiel #4
0
func getCallerFrame(i interface{}) *runtime.Frame {
	pc := reflect.ValueOf(i).Pointer()
	frames := runtime.CallersFrames([]uintptr{pc})
	if frames == nil {
		return nil
	}
	frame, _ := frames.Next()
	if frame.Entry == 0 {
		return nil
	}
	return &frame
}
Beispiel #5
0
Datei: pprof.go Projekt: kraj/gcc
// printStackRecord prints the function + source line information
// for a single stack trace.
func printStackRecord(w io.Writer, stk []uintptr, allFrames bool) {
	show := allFrames
	frames := runtime.CallersFrames(stk)
	for {
		frame, more := frames.Next()
		name := frame.Function

		// Hide runtime.goexit and any runtime functions at the beginning.
		// This is useful mainly for allocation traces.
		skip := name == "runtime.goexit"
		if !show {
			switch {
			case strings.HasPrefix(name, "runtime."):
				skip = true
			case strings.HasPrefix(name, "runtime_"):
				skip = true
			case !strings.Contains(name, ".") && strings.HasPrefix(name, "__go_"):
				skip = true
			}
		}

		if !show && name == "" {
			// This can happen due to http://gcc.gnu.org/PR65797.
		} else if name == "" {
			fmt.Fprintf(w, "#\t%#x\n", frame.PC)
		} else if !skip {
			show = true
			fmt.Fprintf(w, "#\t%#x\t%s+%#x\t%s:%d\n", frame.PC, name, frame.PC-frame.Entry, frame.File, frame.Line)
		}
		if !more {
			break
		}
	}
	if !show {
		// We didn't print anything; do it again,
		// and this time include runtime functions.
		printStackRecord(w, stk, true)
		return
	}
	fmt.Fprintf(w, "\n")
}
Beispiel #6
0
func testCallers(t *testing.T, pcs []uintptr, pan bool) {
	m := make(map[string]int, len(pcs))
	frames := runtime.CallersFrames(pcs)
	for {
		frame, more := frames.Next()
		if frame.Function != "" {
			m[frame.Function] = frame.Line
		}
		if !more {
			break
		}
	}

	var seen []string
	for k := range m {
		seen = append(seen, k)
	}
	t.Logf("functions seen: %s", strings.Join(seen, " "))

	var f3Line int
	if pan {
		f3Line = 23
	} else {
		f3Line = 26
	}
	want := []struct {
		name string
		line int
	}{
		{"f1", 14},
		{"f2", 18},
		{"f3", f3Line},
	}
	for _, w := range want {
		if got := m["runtime_test."+w.name]; got != w.line {
			t.Errorf("%s is line %d, want %d", w.name, got, w.line)
		}
	}
}