|
@@ -46,9 +46,23 @@ var (
|
46
|
46
|
threadzStartRE = regexp.MustCompile(`--- threadz \d+ ---`)
|
47
|
47
|
threadStartRE = regexp.MustCompile(`--- Thread ([[:xdigit:]]+) \(name: (.*)/(\d+)\) stack: ---`)
|
48
|
48
|
|
49
|
|
- procMapsRE = regexp.MustCompile(`([[:xdigit:]]+)-([[:xdigit:]]+)\s+([-rwxp]+)\s+([[:xdigit:]]+)\s+([[:xdigit:]]+):([[:xdigit:]]+)\s+([[:digit:]]+)\s*(\S+)?`)
|
50
|
|
-
|
51
|
|
- briefMapsRE = regexp.MustCompile(`\s*([[:xdigit:]]+)-([[:xdigit:]]+):\s*(\S+)(\s.*@)?([[:xdigit:]]+)?`)
|
|
49
|
+ // Regular expressions to parse process mappings. Support the format used by Linux /proc/.../maps and other tools.
|
|
50
|
+ // Recommended format:
|
|
51
|
+ // Start End object file name offset(optional) linker build id
|
|
52
|
+ // 0x40000-0x80000 /path/to/binary (@FF00) abc123456
|
|
53
|
+ spaceDigits = `\s+[[:digit:]]+`
|
|
54
|
+ hexPair = `\s+[[:xdigit:]]+:[[:xdigit:]]+`
|
|
55
|
+ oSpace = `\s*`
|
|
56
|
+ // Capturing expressions.
|
|
57
|
+ cHex = `(?:0x)?([[:xdigit:]]+)`
|
|
58
|
+ cHexRange = `\s*` + cHex + `[\s-]?` + oSpace + cHex + `:?`
|
|
59
|
+ cSpaceString = `(?:\s+(\S+))?`
|
|
60
|
+ cSpaceHex = `\s+([[:xdigit:]]+)`
|
|
61
|
+ cSpaceAtOffset = `(?:\s+\(@([[:xdigit:]]+)\))?`
|
|
62
|
+ cPerm = `(?:\s+([-rwxp]+))?`
|
|
63
|
+
|
|
64
|
+ procMapsRE = regexp.MustCompile(`^` + cHexRange + cPerm + cSpaceHex + hexPair + spaceDigits + cSpaceString + `\s*$`)
|
|
65
|
+ briefMapsRE = regexp.MustCompile(`^` + cHexRange + cPerm + cSpaceString + cSpaceAtOffset + cSpaceString + `\s*$`)
|
52
|
66
|
)
|
53
|
67
|
|
54
|
68
|
func isSpaceOrComment(line string) bool {
|
|
@@ -1008,45 +1022,36 @@ func (p *Profile) parseMemoryMapFromScanner(s *bufio.Scanner) error {
|
1008
|
1022
|
}
|
1009
|
1023
|
|
1010
|
1024
|
func parseMappingEntry(l string) (*Mapping, error) {
|
1011
|
|
- mapping := &Mapping{}
|
1012
|
|
- var err error
|
1013
|
|
- if me := procMapsRE.FindStringSubmatch(l); len(me) == 9 {
|
1014
|
|
- if !strings.Contains(me[3], "x") {
|
1015
|
|
- // Skip non-executable entries.
|
1016
|
|
- return nil, nil
|
1017
|
|
- }
|
1018
|
|
- if mapping.Start, err = strconv.ParseUint(me[1], 16, 64); err != nil {
|
1019
|
|
- return nil, errUnrecognized
|
1020
|
|
- }
|
1021
|
|
- if mapping.Limit, err = strconv.ParseUint(me[2], 16, 64); err != nil {
|
1022
|
|
- return nil, errUnrecognized
|
1023
|
|
- }
|
1024
|
|
- if me[4] != "" {
|
1025
|
|
- if mapping.Offset, err = strconv.ParseUint(me[4], 16, 64); err != nil {
|
1026
|
|
- return nil, errUnrecognized
|
1027
|
|
- }
|
1028
|
|
- }
|
1029
|
|
- mapping.File = me[8]
|
1030
|
|
- return mapping, nil
|
|
1025
|
+ var start, end, perm, file, offset, buildID string
|
|
1026
|
+ if me := procMapsRE.FindStringSubmatch(l); len(me) == 6 {
|
|
1027
|
+ start, end, perm, offset, file = me[1], me[2], me[3], me[4], me[5]
|
|
1028
|
+ } else if me := briefMapsRE.FindStringSubmatch(l); len(me) == 7 {
|
|
1029
|
+ start, end, perm, file, offset, buildID = me[1], me[2], me[3], me[4], me[5], me[6]
|
|
1030
|
+ } else {
|
|
1031
|
+ return nil, errUnrecognized
|
1031
|
1032
|
}
|
1032
|
1033
|
|
1033
|
|
- if me := briefMapsRE.FindStringSubmatch(l); len(me) == 6 {
|
1034
|
|
- if mapping.Start, err = strconv.ParseUint(me[1], 16, 64); err != nil {
|
1035
|
|
- return nil, errUnrecognized
|
1036
|
|
- }
|
1037
|
|
- if mapping.Limit, err = strconv.ParseUint(me[2], 16, 64); err != nil {
|
|
1034
|
+ var err error
|
|
1035
|
+ mapping := &Mapping{
|
|
1036
|
+ File: file,
|
|
1037
|
+ BuildID: buildID,
|
|
1038
|
+ }
|
|
1039
|
+ if perm != "" && !strings.Contains(perm, "x") {
|
|
1040
|
+ // Skip non-executable entries.
|
|
1041
|
+ return nil, nil
|
|
1042
|
+ }
|
|
1043
|
+ if mapping.Start, err = strconv.ParseUint(start, 16, 64); err != nil {
|
|
1044
|
+ return nil, errUnrecognized
|
|
1045
|
+ }
|
|
1046
|
+ if mapping.Limit, err = strconv.ParseUint(end, 16, 64); err != nil {
|
|
1047
|
+ return nil, errUnrecognized
|
|
1048
|
+ }
|
|
1049
|
+ if offset != "" {
|
|
1050
|
+ if mapping.Offset, err = strconv.ParseUint(offset, 16, 64); err != nil {
|
1038
|
1051
|
return nil, errUnrecognized
|
1039
|
1052
|
}
|
1040
|
|
- mapping.File = me[3]
|
1041
|
|
- if me[5] != "" {
|
1042
|
|
- if mapping.Offset, err = strconv.ParseUint(me[5], 16, 64); err != nil {
|
1043
|
|
- return nil, errUnrecognized
|
1044
|
|
- }
|
1045
|
|
- }
|
1046
|
|
- return mapping, nil
|
1047
|
1053
|
}
|
1048
|
|
-
|
1049
|
|
- return nil, errUnrecognized
|
|
1054
|
+ return mapping, nil
|
1050
|
1055
|
}
|
1051
|
1056
|
|
1052
|
1057
|
type sectionType int
|