2 * @file pe_profiling/operf_process_info.h
3 * This file contains functions for storing process information,
4 * handling exectuable mmappings, etc.
6 * @remark Copyright 2011 OProfile authors
7 * @remark Read the file COPYING
9 * Created on: Dec 7, 2011
10 * @author Maynard Johnson
11 * (C) Copyright IBM Corp. 2011
14 #ifndef OPERF_PROCESS_INFO_H_
15 #define OPERF_PROCESS_INFO_H_
31 char filename[PATH_MAX];
34 /* This class is designed to hold information about a process for which a COMM event
35 * has been recorded in the profile data: application name, process ID, and a map
36 * containing all of the libraries and executable anonymous memory mappings used by this
39 * The COMM event provides only a 16-char (possibly abbreviated) "comm" field for the
40 * executable's basename. If operf is being run in single-process mode vs system-wide,
41 * then we will know what the full pathname of the executable is, in which case, that
42 * will be the value stored in the app_name field; otherwise, as MMAP events are
43 * processed, we compare their basenames to the short name we got from the COMM event.
44 * The mmap'ing whose basename has the most matching characters is chosen to use as
45 * the full pathname of the application. TODO: It's possible that this choice may be wrong;
46 * we should verify the choice by looking at the ELF data (ELF header e_type field should
49 * This class is designed to handle the possibility that MMAP events may occur for a process
50 * prior to the COMM event.
52 class operf_process_info {
54 operf_process_info(pid_t tgid, const char * appname, bool app_arg_is_fullname,
56 ~operf_process_info(void);
57 bool is_valid(void) { return (valid); }
58 bool is_appname_valid(void) { return (valid && appname_valid); }
59 void set_valid(void) { valid = true; }
60 void set_appname_valid(void) { appname_valid = true; }
61 bool is_forked(void) { return forked; }
62 void process_mapping(struct operf_mmap * mapping, bool do_self);
63 void process_hypervisor_mapping(u64 ip);
64 void connect_forked_process_to_parent(void);
65 void set_fork_info(operf_process_info * parent);
66 void add_forked_pid_association(operf_process_info * forked_pid)
67 { forked_processes.push_back(forked_pid); }
68 void copy_mappings_to_forked_process(operf_process_info * forked_pid);
69 void try_disassociate_from_parent(char * appname);
70 void remove_forked_process(pid_t forked_pid);
71 std::string get_app_name(void) { return _appname; }
72 const struct operf_mmap * find_mapping_for_sample(u64 sample_addr, bool hypervisor_sample);
73 void set_appname(const char * appname, bool app_arg_is_fullname);
74 void check_mapping_for_appname(struct operf_mmap * mapping);
85 bool valid, appname_valid, look_for_appname_match;
87 op_fullname_t appname_is_fullname;
88 std::string app_basename;
89 int num_app_chars_matched;
90 std::map<u64, struct operf_mmap *> mmappings;
91 std::map<u64, bool> mmappings_from_parent;
92 /* When a FORK event is received, we associate that forked process
93 * with its parent by adding it to the parent's forked_processes
94 * collection. The main reason we need this collection is because
95 * PERF_RECORD_MMAP events may arrive for the parent out of order,
96 * after a PERF_RECORD_FORK. Since forked processes inherit their
97 * parent's mmappings, we want to make sure those mmappings exist
98 * for the forked process so that samples may be properly attributed.
99 * Therefore, the various paths of adding mmapings to a parent, will
100 * also result in adding those mmappings to forked children.
102 std::vector<operf_process_info *> forked_processes;
103 operf_process_info * parent_of_fork;
104 void set_new_mapping_recursive(struct operf_mmap * mapping, bool do_self);
105 int get_num_matching_chars(std::string mapped_filename, std::string & basename);
106 void find_best_match_appname_all_mappings(void);
110 #endif /* OPERF_PROCESS_INFO_H_ */