Imported Upstream version 1.1.0
[platform/upstream/oprofile.git] / libperf_events / operf_process_info.h
1 /*
2  * @file pe_profiling/operf_process_info.h
3  * This file contains functions for storing process information,
4  * handling exectuable mmappings, etc.
5  *
6  * @remark Copyright 2011 OProfile authors
7  * @remark Read the file COPYING
8  *
9  * Created on: Dec 7, 2011
10  * @author Maynard Johnson
11  * (C) Copyright IBM Corp. 2011
12  */
13
14 #ifndef OPERF_PROCESS_INFO_H_
15 #define OPERF_PROCESS_INFO_H_
16
17 #include <map>
18 #include <limits.h>
19 #include "op_types.h"
20 #include "cverb.h"
21
22 extern verbose vmisc;
23
24 struct operf_mmap {
25         u64 start_addr;
26         u64 end_addr;
27         u64 pgoff;
28         u32 pid;
29         bool is_anon_mapping;
30         bool is_hypervisor;
31         char filename[PATH_MAX];
32 };
33
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
37  * process.
38  *
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
47  * be "ET_EXEC").
48  *
49  * This class is designed to handle the possibility that MMAP events may occur for a process
50  * prior to the COMM event.
51  */
52 class operf_process_info {
53 public:
54         operf_process_info(pid_t tgid, const char * appname, bool app_arg_is_fullname,
55                            bool is_valid);
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);
75
76
77 private:
78         typedef enum {
79                 NOT_FULLNAME,
80                 MAYBE_FULLNAME,
81                 YES_FULLNAME
82         } op_fullname_t;
83         pid_t pid;
84         std::string _appname;
85         bool valid, appname_valid, look_for_appname_match;
86         bool forked;
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.
101          */
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);
107 };
108
109
110 #endif /* OPERF_PROCESS_INFO_H_ */