Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(49)

Side by Side Diff: src/pkg/runtime/debug/stack.go

Issue 4031041: code review 4031041: runtime/debug: new package (Closed)
Patch Set: code review 4031041: runtime/debug: new package Created 14 years, 2 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pkg/Makefile ('k') | src/pkg/runtime/debug/stack_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // The debug package contains facilities for programs to debug themselves
6 // while they are running.
7 package debug
8
9 import (
10 "bytes"
11 "fmt"
12 "io/ioutil"
13 "os"
14 "runtime"
15 )
16
17 var (
18 dunno = []byte("???")
19 centerDot = []byte("·")
20 dot = []byte(".")
21 )
22
23 // PrintStack prints to standard error the stack trace returned by Stack.
24 func PrintStack() {
25 os.Stderr.Write(stack())
26 }
27
28 // Stack() returns a formatted stack trace of the goroutine that calls it.
rsc 2011/01/19 18:31:42 s/()//
29 // For each routine, it includes the source line information and PC value,
30 // then attempts to discover, for Go functions, the calling function or
31 // method and the text of the line containing the invocation.
32 func Stack() []byte {
33 return stack()
34 }
35
36 // stack implements Stack(), skipping 2 frames
rsc 2011/01/19 18:31:42 s/()//
37 func stack() []byte {
38 buf := new(bytes.Buffer) // the returned data
39 // As we loop, we open files and read them. These variables record the c urrently
40 // loaded file.
41 var lines [][]byte
42 var lastFile string
43 for i := 2; ; i++ { // Caller we care about is the user, 2 frames up
44 pc, file, line, ok := runtime.Caller(i)
45 if !ok {
46 break
47 }
48 // Print this much at least. If we can't find the source, it wo n't show.
49 fmt.Fprintf(buf, "%s:%d (0x%x)\n", file, line, pc)
50 if file != lastFile {
51 data, err := ioutil.ReadFile(file)
52 if err != nil {
53 continue
54 }
55 lines = bytes.Split(data, []byte{'\n'}, -1)
56 lastFile = file
57 }
58 line-- // in stack trace, lines are 1-indexed but our array is 0 -indexed
59 fmt.Fprintf(buf, "\t%s: %s\n", function(pc), source(lines, line) )
60 }
61 return buf.Bytes()
62 }
63
64 // source returns a space-trimmed slice of the n'th line.
65 func source(lines [][]byte, n int) []byte {
66 if n < 0 || n >= len(lines) {
67 return dunno
68 }
69 return bytes.Trim(lines[n], " \t")
70 }
71
72 // function returns, if possible, the name of the function containing the PC.
73 func function(pc uintptr) []byte {
74 fn := runtime.FuncForPC(pc)
75 if fn == nil {
76 return dunno
77 }
78 name := []byte(fn.Name())
79 // The name includes the path name to the package, which is unnecessary
80 // since the file name is already included. Plus, it has center dots.
81 // That is, we see
82 // runtime/debug.*T·ptrmethod
83 // and want
84 // *T.ptrmethod
85 if period := bytes.Index(name, dot); period >= 0 {
86 name = name[period+1:]
87 }
88 name = bytes.Replace(name, centerDot, dot, -1)
89 return name
90 }
OLDNEW
« no previous file with comments | « src/pkg/Makefile ('k') | src/pkg/runtime/debug/stack_test.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b