xref: /freebsd/usr.sbin/pmcstat/pmcstat_log.h (revision a0ee8cc6)
1 /*-
2  * Copyright (c) 2005-2007, Joseph Koshy
3  * Copyright (c) 2007 The FreeBSD Foundation
4  * Copyright (c) 2009, Fabien Thomas
5  * All rights reserved.
6  *
7  * Portions of this software were developed by A. Joseph Koshy under
8  * sponsorship from the FreeBSD Foundation and Google, Inc.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  * $FreeBSD$
32  */
33 
34 #ifndef	_PMCSTAT_LOG_H_
35 #define	_PMCSTAT_LOG_H_
36 
37 typedef const void *pmcstat_interned_string;
38 
39 /*
40  * A 'pmcstat_process' structure models processes.  Each process is
41  * associated with a set of pmcstat_pcmap structures that map
42  * addresses inside it to executable objects.  This set is implemented
43  * as a list, kept sorted in ascending order of mapped addresses.
44  *
45  * 'pp_pid' holds the pid of the process.  When a process exits, the
46  * 'pp_isactive' field is set to zero, but the process structure is
47  * not immediately reclaimed because there may still be samples in the
48  * log for this process.
49  */
50 
51 struct pmcstat_process {
52 	LIST_ENTRY(pmcstat_process) pp_next;	/* hash-next */
53 	pid_t			pp_pid;		/* associated pid */
54 	int			pp_isactive;	/* whether active */
55 	uintfptr_t		pp_entryaddr;	/* entry address */
56 	TAILQ_HEAD(,pmcstat_pcmap) pp_map;	/* address range map */
57 };
58 extern LIST_HEAD(pmcstat_process_hash_list, pmcstat_process) pmcstat_process_hash[PMCSTAT_NHASH];
59 
60 /*
61  * A 'pmcstat_image' structure describes an executable program on
62  * disk.  'pi_execpath' is a cookie representing the pathname of
63  * the executable.  'pi_start' and 'pi_end' are the least and greatest
64  * virtual addresses for the text segments in the executable.
65  * 'pi_gmonlist' contains a linked list of gmon.out files associated
66  * with this image.
67  */
68 
69 enum pmcstat_image_type {
70 	PMCSTAT_IMAGE_UNKNOWN = 0,	/* never looked at the image */
71 	PMCSTAT_IMAGE_INDETERMINABLE,	/* can't tell what the image is */
72 	PMCSTAT_IMAGE_ELF32,		/* ELF 32 bit object */
73 	PMCSTAT_IMAGE_ELF64,		/* ELF 64 bit object */
74 	PMCSTAT_IMAGE_AOUT		/* AOUT object */
75 };
76 
77 struct pmcstat_image {
78 	LIST_ENTRY(pmcstat_image) pi_next;	/* hash link */
79 	TAILQ_ENTRY(pmcstat_image) pi_lru;	/* LRU list */
80 	pmcstat_interned_string	pi_execpath;    /* cookie */
81 	pmcstat_interned_string pi_samplename;  /* sample path name */
82 	pmcstat_interned_string pi_fullpath;    /* path to FS object */
83 	pmcstat_interned_string pi_name;	/* display name */
84 
85 	enum pmcstat_image_type pi_type;	/* executable type */
86 
87 	/*
88 	 * Executables have pi_start and pi_end; these are zero
89 	 * for shared libraries.
90 	 */
91 	uintfptr_t	pi_start;	/* start address (inclusive) */
92 	uintfptr_t	pi_end;		/* end address (exclusive) */
93 	uintfptr_t	pi_entry;	/* entry address */
94 	uintfptr_t	pi_vaddr;	/* virtual address where loaded */
95 	int		pi_isdynamic;	/* whether a dynamic object */
96 	int		pi_iskernelmodule;
97 	pmcstat_interned_string pi_dynlinkerpath; /* path in .interp */
98 
99 	/* All symbols associated with this object. */
100 	struct pmcstat_symbol *pi_symbols;
101 	size_t		pi_symcount;
102 
103 	/* Handle to addr2line for this image. */
104 	FILE *pi_addr2line;
105 
106 	/*
107 	 * Plugins private data
108 	 */
109 
110 	/* gprof:
111 	 * An image can be associated with one or more gmon.out files;
112 	 * one per PMC.
113 	 */
114 	LIST_HEAD(,pmcstat_gmonfile) pi_gmlist;
115 };
116 extern LIST_HEAD(pmcstat_image_hash_list, pmcstat_image) pmcstat_image_hash[PMCSTAT_NHASH];
117 
118 /*
119  * A 'pmcstat_pcmap' structure maps a virtual address range to an
120  * underlying 'pmcstat_image' descriptor.
121  */
122 struct pmcstat_pcmap {
123 	TAILQ_ENTRY(pmcstat_pcmap) ppm_next;
124 	uintfptr_t	ppm_lowpc;
125 	uintfptr_t	ppm_highpc;
126 	struct pmcstat_image *ppm_image;
127 };
128 
129 /*
130  * Each function symbol tracked by pmcstat(8).
131  */
132 
133 struct pmcstat_symbol {
134 	pmcstat_interned_string ps_name;
135 	uint64_t	ps_start;
136 	uint64_t	ps_end;
137 };
138 
139 /*
140  * 'pmcstat_pmcrecord' is a mapping from PMC ids to human-readable
141  * names.
142  */
143 
144 struct pmcstat_pmcrecord {
145 	LIST_ENTRY(pmcstat_pmcrecord)	pr_next;
146 	pmc_id_t			pr_pmcid;
147 	int				pr_pmcin;
148 	pmcstat_interned_string		pr_pmcname;
149 	int				pr_samples;
150 	int				pr_dubious_frames;
151 	struct pmcstat_pmcrecord	*pr_merge;
152 };
153 extern LIST_HEAD(pmcstat_pmcs, pmcstat_pmcrecord) pmcstat_pmcs; /* PMC list */
154 
155 /*
156  * Misc. statistics
157  */
158 struct pmcstat_stats {
159 	int ps_exec_aout;	/* # a.out executables seen */
160 	int ps_exec_elf;	/* # elf executables seen */
161 	int ps_exec_errors;	/* # errors processing executables */
162 	int ps_exec_indeterminable; /* # unknown executables seen */
163 	int ps_samples_total;	/* total number of samples processed */
164 	int ps_samples_skipped; /* #samples filtered out for any reason */
165 	int ps_samples_unknown_offset;	/* #samples of rank 0 not in a map */
166 	int ps_samples_indeterminable;	/* #samples in indeterminable images */
167 	int ps_samples_unknown_function;/* #samples with unknown function at offset */
168 	int ps_callchain_dubious_frames;/* #dubious frame pointers seen */
169 };
170 extern struct pmcstat_stats pmcstat_stats; /* statistics */
171 
172 extern struct pmcstat_process *pmcstat_kernproc; /* kernel 'process' */
173 
174 extern int pmcstat_npmcs; /* PMC count. */
175 
176 /*
177  * Top mode global options.
178  */
179 extern float pmcstat_threshold; /* Threshold to filter node. */
180 extern int pmcstat_pmcinfilter; /* PMC index displayed. */
181 
182 /* Function prototypes */
183 const char *pmcstat_pmcid_to_name(pmc_id_t _pmcid);
184 const char *pmcstat_pmcindex_to_name(int pmcin);
185 struct pmcstat_pmcrecord *pmcstat_pmcindex_to_pmcr(int pmcin);
186 struct pmcstat_pcmap *pmcstat_process_find_map(struct pmcstat_process *_p,
187 	uintfptr_t _pc);
188 struct pmcstat_symbol *pmcstat_symbol_search(struct pmcstat_image *image,
189 	uintfptr_t addr);
190 const char *pmcstat_string_unintern(pmcstat_interned_string _is);
191 pmcstat_interned_string pmcstat_string_intern(const char *_s);
192 void pmcstat_image_determine_type(struct pmcstat_image *_image);
193 pmcstat_interned_string pmcstat_string_lookup(const char *_s);
194 int pmcstat_image_addr2line(struct pmcstat_image *image, uintfptr_t addr,
195     char *sourcefile, size_t sourcefile_len, unsigned *sourceline,
196     char *funcname, size_t funcname_len);
197 
198 #endif	/* _PMCSTAT_LOG_H_ */
199 
200