| /* |
| * @file pe_profiling/operf_process_info.h |
| * This file contains functions for storing process information, |
| * handling exectuable mmappings, etc. |
| * |
| * @remark Copyright 2011 OProfile authors |
| * @remark Read the file COPYING |
| * |
| * Created on: Dec 7, 2011 |
| * @author Maynard Johnson |
| * (C) Copyright IBM Corp. 2011 |
| */ |
| |
| #ifndef OPERF_PROCESS_INFO_H_ |
| #define OPERF_PROCESS_INFO_H_ |
| |
| #include <map> |
| #include <limits.h> |
| #include "op_types.h" |
| #include "cverb.h" |
| |
| extern verbose vmisc; |
| |
| struct operf_mmap { |
| u64 start_addr; |
| u64 end_addr; |
| u64 pgoff; |
| bool is_anon_mapping; |
| bool is_hypervisor; |
| char filename[PATH_MAX]; |
| }; |
| |
| /* This class is designed to hold information about a process for which a COMM event |
| * has been recorded in the profile data: application name, process ID, and a map |
| * containing all of the libraries and executable anonymous memory mappings used by this |
| * process. |
| * |
| * The COMM event provides only a 16-char (possibly abbreviated) "comm" field for the |
| * executable's basename. If operf is being run in single-process mode vs system-wide, |
| * then we will know what the full pathname of the executable is, in which case, that |
| * will be the value stored in the app_name field; otherwise, as MMAP events are |
| * processed, we compare their basenames to the short name we got from the COMM event. |
| * The mmap'ing whose basename has the most matching characters is chosen to use as |
| * the full pathname of the application. TODO: It's possible that this choice may be wrong; |
| * we should verify the choice by looking at the ELF data (ELF header e_type field should |
| * be "ET_EXEC"). |
| * |
| * This class is designed to handle the possibility that MMAP events may occur for a process |
| * prior to the COMM event. |
| */ |
| class operf_process_info { |
| public: |
| operf_process_info(pid_t tgid, const char * appname, bool app_arg_is_fullname, |
| bool is_valid); |
| ~operf_process_info(void); |
| bool is_valid(void) { return (valid); } |
| bool is_appname_valid(void) { return (valid && appname_valid); } |
| void set_valid(void) { valid = true; } |
| void set_appname_valid(void) { appname_valid = true; } |
| bool is_forked(void) { return forked; } |
| void process_mapping(struct operf_mmap * mapping, bool do_self); |
| void process_hypervisor_mapping(u64 ip); |
| void connect_forked_process_to_parent(void); |
| void set_fork_info(operf_process_info * parent); |
| void add_forked_pid_association(operf_process_info * forked_pid) |
| { forked_processes.push_back(forked_pid); } |
| void copy_mappings_to_forked_process(operf_process_info * forked_pid); |
| void try_disassociate_from_parent(char * appname); |
| void remove_forked_process(pid_t forked_pid); |
| std::string get_app_name(void) { return _appname; } |
| const struct operf_mmap * find_mapping_for_sample(u64 sample_addr); |
| void set_appname(const char * appname, bool app_arg_is_fullname); |
| void check_mapping_for_appname(struct operf_mmap * mapping); |
| |
| |
| private: |
| typedef enum { |
| NOT_FULLNAME, |
| MAYBE_FULLNAME, |
| YES_FULLNAME |
| } op_fullname_t; |
| pid_t pid; |
| std::string _appname; |
| bool valid, appname_valid, look_for_appname_match; |
| bool forked; |
| op_fullname_t appname_is_fullname; |
| std::string app_basename; |
| int num_app_chars_matched; |
| std::map<u64, struct operf_mmap *> mmappings; |
| std::map<u64, bool> mmappings_from_parent; |
| /* When a FORK event is received, we associate that forked process |
| * with its parent by adding it to the parent's forked_processes |
| * collection. The main reason we need this collection is because |
| * PERF_RECORD_MMAP events may arrive for the parent out of order, |
| * after a PERF_RECORD_FORK. Since forked processes inherit their |
| * parent's mmappings, we want to make sure those mmappings exist |
| * for the forked process so that samples may be properly attributed. |
| * Therefore, the various paths of adding mmapings to a parent, will |
| * also result in adding those mmappings to forked children. |
| */ |
| std::vector<operf_process_info *> forked_processes; |
| operf_process_info * parent_of_fork; |
| void set_new_mapping_recursive(struct operf_mmap * mapping, bool do_self); |
| int get_num_matching_chars(std::string mapped_filename, std::string & basename); |
| void find_best_match_appname_all_mappings(void); |
| }; |
| |
| |
| #endif /* OPERF_PROCESS_INFO_H_ */ |