// procEvent returns a procEntry event from the am_proc_start of am_proc_died event. // If extra fields are encountered, a warning is returned. If fields are missing, an error is returned. func procEvent(start int64, v string, t string) (*procEntry, string, error) { warning := "" switch t { case ProcStartEvent: // Expected format of v is: User,PID,UID,Process Name,Type,Component. parts := strings.Split(v, ",") if len(parts) < 6 { return nil, warning, fmt.Errorf("%s: got %d parts, want 6", ProcStartEvent, len(parts)) } if len(parts) > 6 { warning = fmt.Sprintf("%s: got %d parts, expected 6", ProcStartEvent, len(parts)) } if _, err := strconv.Atoi(parts[1]); err != nil { return nil, warning, fmt.Errorf("%s: could not parse pid %v: %v", ProcStartEvent, parts[1], err) } uid, err := packageutils.AppIDFromString(parts[2]) if err != nil { return nil, warning, fmt.Errorf("%s: could not parse uid %v: %v", ProcStartEvent, parts[2], err) } return &procEntry{ start: start, pid: parts[1], uid: fmt.Sprint(uid), process: parts[3], component: parts[5], }, warning, nil case ProcDiedEvent: // Expected format of v is: User,PID,Process Name. parts := strings.Split(v, ",") if len(parts) < 3 { return nil, warning, fmt.Errorf("%s: got %d parts, want 3", ProcDiedEvent, len(parts)) } if len(parts) > 3 { warning = fmt.Sprintf("%s: got %d parts, expected 3", ProcDiedEvent, len(parts)) } if _, err := strconv.Atoi(parts[1]); err != nil { return nil, warning, fmt.Errorf("%s: could not parse pid %v: %v", ProcDiedEvent, parts[1], err) } return &procEntry{ start: start, pid: parts[1], process: parts[2], }, warning, nil default: return nil, "", fmt.Errorf("unknown transition: %v", t) } }
// ExtractPIDMappings returns mappings from PID to app names and UIDs extracted from the bug report. func ExtractPIDMappings(contents string) (map[string][]AppInfo, []string) { var warnings []string mapping := make(map[string][]AppInfo) for _, line := range strings.Split(contents, "\n") { if m, result := historianutils.SubexpNames(pidRE, line); m { baseUID, err := packageutils.AppIDFromString(result["uid"]) uidStr := strconv.Itoa(int(baseUID)) if err != nil { uidStr = "" warnings = append(warnings, fmt.Sprintf("invalid uid: %s", result["uid"])) } mapping[result["pid"]] = append(mapping[result["pid"]], AppInfo{ Name: result["app"], UID: uidStr, }) } } return mapping, warnings }