Browse Source

Merge pull request #70 from rauls5382/procmaps

Handle memory maps generated by logging
Raul Silvera 8 years ago
parent
commit
ecd093a0ce
1 changed files with 36 additions and 22 deletions
  1. 36
    22
      profile/legacy_profile.go

+ 36
- 22
profile/legacy_profile.go View File

509
 			continue
509
 			continue
510
 		}
510
 		}
511
 
511
 
512
-		if sectionTrigger(line) != unrecognizedSection {
512
+		if isMemoryMapSentinel(line) {
513
 			break
513
 			break
514
 		}
514
 		}
515
 
515
 
837
 	if m := threadzStartRE.FindStringSubmatch(line); m != nil {
837
 	if m := threadzStartRE.FindStringSubmatch(line); m != nil {
838
 		// Advance over initial comments until first stack trace.
838
 		// Advance over initial comments until first stack trace.
839
 		for s.Scan() {
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
 				break
841
 				break
842
 			}
842
 			}
843
 		}
843
 		}
853
 
853
 
854
 	locs := make(map[uint64]*Location)
854
 	locs := make(map[uint64]*Location)
855
 	// Recognize each thread and populate profile samples.
855
 	// Recognize each thread and populate profile samples.
856
-	for sectionTrigger(line) == unrecognizedSection {
856
+	for !isMemoryMapSentinel(line) {
857
 		if strings.HasPrefix(line, "---- no stack trace for") {
857
 		if strings.HasPrefix(line, "---- no stack trace for") {
858
 			line = ""
858
 			line = ""
859
 			break
859
 			break
944
 // parseAdditionalSections parses any additional sections in the
944
 // parseAdditionalSections parses any additional sections in the
945
 // profile, ignoring any unrecognized sections.
945
 // profile, ignoring any unrecognized sections.
946
 func parseAdditionalSections(s *bufio.Scanner, p *Profile) error {
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
 	if err := s.Err(); err != nil {
949
 	if err := s.Err(); err != nil {
950
 		return err
950
 		return err
951
 	}
951
 	}
952
-	return p.parseMemoryMapFromScanner(s)
952
+	return p.ParseMemoryMapFromScanner(s)
953
 }
953
 }
954
 
954
 
955
 // ParseProcMaps parses a memory map in the format of /proc/self/maps.
955
 // ParseProcMaps parses a memory map in the format of /proc/self/maps.
964
 func parseProcMapsFromScanner(s *bufio.Scanner) ([]*Mapping, error) {
964
 func parseProcMapsFromScanner(s *bufio.Scanner) ([]*Mapping, error) {
965
 	var mapping []*Mapping
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
 	var attrs []string
971
 	var attrs []string
968
 	var r *strings.Replacer
972
 	var r *strings.Replacer
969
 	const delimiter = "="
973
 	const delimiter = "="
970
 	for s.Scan() {
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
 			continue
980
 			continue
974
 		}
981
 		}
975
 
982
 
1005
 // /proc/self/maps, and overrides the mappings in the current profile.
1012
 // /proc/self/maps, and overrides the mappings in the current profile.
1006
 // It renumbers the samples and locations in the profile correspondingly.
1013
 // It renumbers the samples and locations in the profile correspondingly.
1007
 func (p *Profile) ParseMemoryMap(rd io.Reader) error {
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
 	mapping, err := parseProcMapsFromScanner(s)
1019
 	mapping, err := parseProcMapsFromScanner(s)
1013
 	if err != nil {
1020
 	if err != nil {
1014
 		return err
1021
 		return err
1054
 	return mapping, nil
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
 	"--- Memory map: ---",
1065
 	"--- Memory map: ---",
1066
 	"MAPPED_LIBRARIES:",
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
 func (p *Profile) addLegacyFrameInfo() {
1092
 func (p *Profile) addLegacyFrameInfo() {