parseGoCount parses a Go count profile (e.g., threadcreate or goroutine) and returns a new Profile.
(b []byte)
| 77 | // parseGoCount parses a Go count profile (e.g., threadcreate or |
| 78 | // goroutine) and returns a new Profile. |
| 79 | func parseGoCount(b []byte) (*Profile, error) { |
| 80 | s := bufio.NewScanner(bytes.NewBuffer(b)) |
| 81 | // Skip comments at the beginning of the file. |
| 82 | for s.Scan() && isSpaceOrComment(s.Text()) { |
| 83 | } |
| 84 | if err := s.Err(); err != nil { |
| 85 | return nil, err |
| 86 | } |
| 87 | m := countStartRE.FindStringSubmatch(s.Text()) |
| 88 | if m == nil { |
| 89 | return nil, errUnrecognized |
| 90 | } |
| 91 | profileType := m[1] |
| 92 | p := &Profile{ |
| 93 | PeriodType: &ValueType{Type: profileType, Unit: "count"}, |
| 94 | Period: 1, |
| 95 | SampleType: []*ValueType{{Type: profileType, Unit: "count"}}, |
| 96 | } |
| 97 | locations := make(map[uint64]*Location) |
| 98 | for s.Scan() { |
| 99 | line := s.Text() |
| 100 | if isSpaceOrComment(line) { |
| 101 | continue |
| 102 | } |
| 103 | if strings.HasPrefix(line, "---") { |
| 104 | break |
| 105 | } |
| 106 | m := countRE.FindStringSubmatch(line) |
| 107 | if m == nil { |
| 108 | return nil, errMalformed |
| 109 | } |
| 110 | n, err := strconv.ParseInt(m[1], 0, 64) |
| 111 | if err != nil { |
| 112 | return nil, errMalformed |
| 113 | } |
| 114 | fields := strings.Fields(m[2]) |
| 115 | locs := make([]*Location, 0, len(fields)) |
| 116 | for _, stk := range fields { |
| 117 | addr, err := strconv.ParseUint(stk, 0, 64) |
| 118 | if err != nil { |
| 119 | return nil, errMalformed |
| 120 | } |
| 121 | // Adjust all frames by -1 to land on top of the call instruction. |
| 122 | addr-- |
| 123 | loc := locations[addr] |
| 124 | if loc == nil { |
| 125 | loc = &Location{ |
| 126 | Address: addr, |
| 127 | } |
| 128 | locations[addr] = loc |
| 129 | p.Location = append(p.Location, loc) |
| 130 | } |
| 131 | locs = append(locs, loc) |
| 132 | } |
| 133 | p.Sample = append(p.Sample, &Sample{ |
| 134 | Location: locs, |
| 135 | Value: []int64{n}, |
| 136 | }) |
searching dependent graphs…