|
@@ -509,7 +509,7 @@ func parseHeap(b []byte) (p *Profile, err error) {
|
509
|
509
|
continue
|
510
|
510
|
}
|
511
|
511
|
|
512
|
|
- if sectionTrigger(line) != unrecognizedSection {
|
|
512
|
+ if isMemoryMapSentinel(line) {
|
513
|
513
|
break
|
514
|
514
|
}
|
515
|
515
|
|
|
@@ -837,7 +837,7 @@ func parseThread(b []byte) (*Profile, error) {
|
837
|
837
|
if m := threadzStartRE.FindStringSubmatch(line); m != nil {
|
838
|
838
|
// Advance over initial comments until first stack trace.
|
839
|
839
|
for s.Scan() {
|
840
|
|
- if line = s.Text(); sectionTrigger(line) != unrecognizedSection || strings.HasPrefix(line, "-") {
|
|
840
|
+ if line = s.Text(); isMemoryMapSentinel(line) || strings.HasPrefix(line, "-") {
|
841
|
841
|
break
|
842
|
842
|
}
|
843
|
843
|
}
|
|
@@ -853,7 +853,7 @@ func parseThread(b []byte) (*Profile, error) {
|
853
|
853
|
|
854
|
854
|
locs := make(map[uint64]*Location)
|
855
|
855
|
// Recognize each thread and populate profile samples.
|
856
|
|
- for sectionTrigger(line) == unrecognizedSection {
|
|
856
|
+ for !isMemoryMapSentinel(line) {
|
857
|
857
|
if strings.HasPrefix(line, "---- no stack trace for") {
|
858
|
858
|
line = ""
|
859
|
859
|
break
|
|
@@ -944,12 +944,12 @@ func parseThreadSample(s *bufio.Scanner) (nextl string, addrs []uint64, err erro
|
944
|
944
|
// parseAdditionalSections parses any additional sections in the
|
945
|
945
|
// profile, ignoring any unrecognized sections.
|
946
|
946
|
func parseAdditionalSections(s *bufio.Scanner, p *Profile) error {
|
947
|
|
- for sectionTrigger(s.Text()) != memoryMapSection && s.Scan() {
|
|
947
|
+ for !isMemoryMapSentinel(s.Text()) && s.Scan() {
|
948
|
948
|
}
|
949
|
949
|
if err := s.Err(); err != nil {
|
950
|
950
|
return err
|
951
|
951
|
}
|
952
|
|
- return p.parseMemoryMapFromScanner(s)
|
|
952
|
+ return p.ParseMemoryMapFromScanner(s)
|
953
|
953
|
}
|
954
|
954
|
|
955
|
955
|
// ParseProcMaps parses a memory map in the format of /proc/self/maps.
|
|
@@ -964,12 +964,19 @@ func ParseProcMaps(rd io.Reader) ([]*Mapping, error) {
|
964
|
964
|
func parseProcMapsFromScanner(s *bufio.Scanner) ([]*Mapping, error) {
|
965
|
965
|
var mapping []*Mapping
|
966
|
966
|
|
|
967
|
+ // If the memory-map sentinel is at column X, assume memory mappings
|
|
968
|
+ // also start at X. This is useful to eliminate logging information.
|
|
969
|
+ offset := memoryMapSentinelOffset(s.Text())
|
|
970
|
+
|
967
|
971
|
var attrs []string
|
968
|
972
|
var r *strings.Replacer
|
969
|
973
|
const delimiter = "="
|
970
|
974
|
for s.Scan() {
|
971
|
|
- line := strings.TrimSpace(s.Text())
|
972
|
|
- if line == "" {
|
|
975
|
+ line := s.Text()
|
|
976
|
+ if len(line) > offset {
|
|
977
|
+ line = line[offset:]
|
|
978
|
+ }
|
|
979
|
+ if line = strings.TrimSpace(line); line == "" {
|
973
|
980
|
continue
|
974
|
981
|
}
|
975
|
982
|
|
|
@@ -1005,10 +1012,10 @@ func parseProcMapsFromScanner(s *bufio.Scanner) ([]*Mapping, error) {
|
1005
|
1012
|
// /proc/self/maps, and overrides the mappings in the current profile.
|
1006
|
1013
|
// It renumbers the samples and locations in the profile correspondingly.
|
1007
|
1014
|
func (p *Profile) ParseMemoryMap(rd io.Reader) error {
|
1008
|
|
- return p.parseMemoryMapFromScanner(bufio.NewScanner(rd))
|
|
1015
|
+ return p.ParseMemoryMapFromScanner(bufio.NewScanner(rd))
|
1009
|
1016
|
}
|
1010
|
1017
|
|
1011
|
|
-func (p *Profile) parseMemoryMapFromScanner(s *bufio.Scanner) error {
|
|
1018
|
+func (p *Profile) ParseMemoryMapFromScanner(s *bufio.Scanner) error {
|
1012
|
1019
|
mapping, err := parseProcMapsFromScanner(s)
|
1013
|
1020
|
if err != nil {
|
1014
|
1021
|
return err
|
|
@@ -1054,25 +1061,32 @@ func parseMappingEntry(l string) (*Mapping, error) {
|
1054
|
1061
|
return mapping, nil
|
1055
|
1062
|
}
|
1056
|
1063
|
|
1057
|
|
-type sectionType int
|
1058
|
|
-
|
1059
|
|
-const (
|
1060
|
|
- unrecognizedSection sectionType = iota
|
1061
|
|
- memoryMapSection
|
1062
|
|
-)
|
1063
|
|
-
|
1064
|
|
-var memoryMapTriggers = []string{
|
|
1064
|
+var memoryMapSentinels = []string{
|
1065
|
1065
|
"--- Memory map: ---",
|
1066
|
1066
|
"MAPPED_LIBRARIES:",
|
1067
|
1067
|
}
|
1068
|
1068
|
|
1069
|
|
-func sectionTrigger(line string) sectionType {
|
1070
|
|
- for _, trigger := range memoryMapTriggers {
|
1071
|
|
- if strings.Contains(line, trigger) {
|
1072
|
|
- return memoryMapSection
|
|
1069
|
+// isMemoryMapSentinel returns true if the string contains one of the
|
|
1070
|
+// known sentinels for memory map information.
|
|
1071
|
+func isMemoryMapSentinel(line string) bool {
|
|
1072
|
+ for _, s := range memoryMapSentinels {
|
|
1073
|
+ if strings.Contains(line, s) {
|
|
1074
|
+ return true
|
|
1075
|
+ }
|
|
1076
|
+ }
|
|
1077
|
+ return false
|
|
1078
|
+}
|
|
1079
|
+
|
|
1080
|
+// memoryMapSentinelOffset returns the index of a known memory map
|
|
1081
|
+// sentinel in the string. If the string does not contain a sentinel,
|
|
1082
|
+// it returns 0.
|
|
1083
|
+func memoryMapSentinelOffset(line string) int {
|
|
1084
|
+ for _, s := range memoryMapSentinels {
|
|
1085
|
+ if i := strings.Index(line, s); i != -1 {
|
|
1086
|
+ return i
|
1073
|
1087
|
}
|
1074
|
1088
|
}
|
1075
|
|
- return unrecognizedSection
|
|
1089
|
+ return 0
|
1076
|
1090
|
}
|
1077
|
1091
|
|
1078
|
1092
|
func (p *Profile) addLegacyFrameInfo() {
|