xref: /freebsd/usr.sbin/pmcstat/pmcstat_log.h (revision 3416500aef140042c64bc149cb1ec6620483bc44)
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 	pmcstat_interned_string	pi_execpath;    /* cookie */
80 	pmcstat_interned_string pi_samplename;  /* sample path name */
81 	pmcstat_interned_string pi_fullpath;    /* path to FS object */
82 	pmcstat_interned_string pi_name;	/* display name */
83 
84 	enum pmcstat_image_type pi_type;	/* executable type */
85 
86 	/*
87 	 * Executables have pi_start and pi_end; these are zero
88 	 * for shared libraries.
89 	 */
90 	uintfptr_t	pi_start;	/* start address (inclusive) */
91 	uintfptr_t	pi_end;		/* end address (exclusive) */
92 	uintfptr_t	pi_entry;	/* entry address */
93 	uintfptr_t	pi_vaddr;	/* virtual address where loaded */
94 	int		pi_isdynamic;	/* whether a dynamic object */
95 	int		pi_iskernelmodule;
96 	pmcstat_interned_string pi_dynlinkerpath; /* path in .interp */
97 
98 	/* All symbols associated with this object. */
99 	struct pmcstat_symbol *pi_symbols;
100 	size_t		pi_symcount;
101 
102 	/* Handle to addr2line for this image. */
103 	FILE *pi_addr2line;
104 
105 	/*
106 	 * Plugins private data
107 	 */
108 
109 	/* gprof:
110 	 * An image can be associated with one or more gmon.out files;
111 	 * one per PMC.
112 	 */
113 	LIST_HEAD(,pmcstat_gmonfile) pi_gmlist;
114 };
115 extern LIST_HEAD(pmcstat_image_hash_list, pmcstat_image) pmcstat_image_hash[PMCSTAT_NHASH];
116 
117 /*
118  * A 'pmcstat_pcmap' structure maps a virtual address range to an
119  * underlying 'pmcstat_image' descriptor.
120  */
121 struct pmcstat_pcmap {
122 	TAILQ_ENTRY(pmcstat_pcmap) ppm_next;
123 	uintfptr_t	ppm_lowpc;
124 	uintfptr_t	ppm_highpc;
125 	struct pmcstat_image *ppm_image;
126 };
127 
128 /*
129  * Each function symbol tracked by pmcstat(8).
130  */
131 
132 struct pmcstat_symbol {
133 	pmcstat_interned_string ps_name;
134 	uint64_t	ps_start;
135 	uint64_t	ps_end;
136 };
137 
138 /*
139  * 'pmcstat_pmcrecord' is a mapping from PMC ids to human-readable
140  * names.
141  */
142 
143 struct pmcstat_pmcrecord {
144 	LIST_ENTRY(pmcstat_pmcrecord)	pr_next;
145 	pmc_id_t			pr_pmcid;
146 	int				pr_pmcin;
147 	pmcstat_interned_string		pr_pmcname;
148 	int				pr_samples;
149 	int				pr_dubious_frames;
150 	struct pmcstat_pmcrecord	*pr_merge;
151 };
152 extern LIST_HEAD(pmcstat_pmcs, pmcstat_pmcrecord) pmcstat_pmcs; /* PMC list */
153 
154 /*
155  * Misc. statistics
156  */
157 struct pmcstat_stats {
158 	int ps_exec_aout;	/* # a.out executables seen */
159 	int ps_exec_elf;	/* # elf executables seen */
160 	int ps_exec_errors;	/* # errors processing executables */
161 	int ps_exec_indeterminable; /* # unknown executables seen */
162 	int ps_samples_total;	/* total number of samples processed */
163 	int ps_samples_skipped; /* #samples filtered out for any reason */
164 	int ps_samples_unknown_offset;	/* #samples of rank 0 not in a map */
165 	int ps_samples_indeterminable;	/* #samples in indeterminable images */
166 	int ps_samples_unknown_function;/* #samples with unknown function at offset */
167 	int ps_callchain_dubious_frames;/* #dubious frame pointers seen */
168 };
169 extern struct pmcstat_stats pmcstat_stats; /* statistics */
170 
171 extern struct pmcstat_process *pmcstat_kernproc; /* kernel 'process' */
172 
173 extern int pmcstat_npmcs; /* PMC count. */
174 
175 /*
176  * Top mode global options.
177  */
178 extern float pmcstat_threshold; /* Threshold to filter node. */
179 extern int pmcstat_pmcinfilter; /* PMC index displayed. */
180 
181 /* Function prototypes */
182 const char *pmcstat_pmcid_to_name(pmc_id_t _pmcid);
183 const char *pmcstat_pmcindex_to_name(int pmcin);
184 struct pmcstat_pmcrecord *pmcstat_pmcindex_to_pmcr(int pmcin);
185 struct pmcstat_pcmap *pmcstat_process_find_map(struct pmcstat_process *_p,
186 	uintfptr_t _pc);
187 struct pmcstat_symbol *pmcstat_symbol_search(struct pmcstat_image *image,
188 	uintfptr_t addr);
189 const char *pmcstat_string_unintern(pmcstat_interned_string _is);
190 pmcstat_interned_string pmcstat_string_intern(const char *_s);
191 void pmcstat_image_determine_type(struct pmcstat_image *_image);
192 pmcstat_interned_string pmcstat_string_lookup(const char *_s);
193 int pmcstat_image_addr2line(struct pmcstat_image *image, uintfptr_t addr,
194     char *sourcefile, size_t sourcefile_len, unsigned *sourceline,
195     char *funcname, size_t funcname_len);
196 
197 #endif	/* _PMCSTAT_LOG_H_ */
198 
199