HPCToolkit
memleak.c
Go to the documentation of this file.
1 // -*-Mode: C++;-*- // technically C99
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL$
6 // $Id$
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2019, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 
48 /******************************************************************************
49  * system includes
50  *****************************************************************************/
51 
52 #include <stdlib.h>
53 #include <stddef.h>
54 #include <string.h>
55 #include <assert.h>
56 #include <unistd.h>
57 
58 
59 
60 /******************************************************************************
61  * libmonitor
62  *****************************************************************************/
63 
64 #include <monitor.h>
65 
66 
67 
68 /******************************************************************************
69  * local includes
70  *****************************************************************************/
71 
72 #include <hpcrun/hpcrun_options.h>
73 #include <hpcrun/disabled.h>
74 #include <hpcrun/metrics.h>
75 #include <sample_event.h>
76 #include "sample_source_obj.h"
77 #include "common.h"
78 #include <main.h>
80 #include "simple_oo.h"
81 #include <hpcrun/thread_data.h>
82 
83 #include <messages/messages.h>
84 #include <utilities/tokenize.h>
85 
86 static const unsigned int MAX_CHAR_FORMULA = 32;
87 
88 static int alloc_metric_id = -1;
89 static int free_metric_id = -1;
90 static int leak_metric_id = -1;
91 
92 
93 /******************************************************************************
94  * method definitions
95  *****************************************************************************/
96 
97 static void
98 METHOD_FN(init)
99 {
100  self->state = INIT;
101 
102  // reset static variables to their virgin state
103  alloc_metric_id = -1;
104  free_metric_id = -1;
105  leak_metric_id = -1;
106 }
107 
108 
109 static void
110 METHOD_FN(thread_init)
111 {
112  TMSG(MEMLEAK, "thread init (no action needed)");
113 }
114 
115 static void
116 METHOD_FN(thread_init_action)
117 {
118  TMSG(MEMLEAK, "thread action (noop)");
119 }
120 
121 static void
122 METHOD_FN(start)
123 {
124  TMSG(MEMLEAK,"starting MEMLEAK");
125 
126  TD_GET(ss_state)[self->sel_idx] = START;
127 }
128 
129 static void
130 METHOD_FN(thread_fini_action)
131 {
132  TMSG(MEMLEAK, "thread fini (noop)");
133 }
134 
135 static void
137 {
138  TMSG(MEMLEAK,"stopping MEMLEAK");
139  TD_GET(ss_state)[self->sel_idx] = STOP;
140 }
141 
142 
143 static void
144 METHOD_FN(shutdown)
145 {
146  METHOD_CALL(self,stop); // make sure stop has been called
147  self->state = UNINIT;
148 }
149 
150 
151 static bool
152 METHOD_FN(supports_event,const char *ev_str)
153 {
154  return hpcrun_ev_is(ev_str,"MEMLEAK");
155 }
156 
157 
158 // MEMLEAK creates two metrics: bytes allocated and Bytes Freed.
159 
160 static void
161 METHOD_FN(process_event_list,int lush_metrics)
162 {
166 
167  TMSG(MEMLEAK, "Setting up metrics for memory leak detection");
168 
169  hpcrun_set_metric_info(alloc_metric_id, "Bytes Allocated");
170  hpcrun_set_metric_info(free_metric_id, "Bytes Freed");
171 
172  metric_desc_t* memleak_metric = hpcrun_set_metric_info(leak_metric_id, "Bytes Leaked");
173 
174  char *buffer = hpcrun_malloc(sizeof(char) * MAX_CHAR_FORMULA);
175 
176  // leak = allocated - freed
177  sprintf(buffer, "$%d-$%d", alloc_metric_id, free_metric_id);
178  memleak_metric->formula = buffer;
179 }
180 
181 
182 //
183 // Event sets not relevant for this sample source
184 // Events are generated by user code
185 //
186 static void
187 METHOD_FN(gen_event_set,int lush_metrics)
188 {
189 }
190 
191 
192 //
193 //
194 //
195 static void
196 METHOD_FN(display_events)
197 {
198  printf("===========================================================================\n");
199  printf("Available memory leak detection events\n");
200  printf("===========================================================================\n");
201  printf("Name\t\tDescription\n");
202  printf("---------------------------------------------------------------------------\n");
203  printf("MEMLEAK\t\tThe number of bytes allocated and freed per dynamic context\n");
204  printf("\n");
205 }
206 
207 /***************************************************************************
208  * object
209  ***************************************************************************/
210 
211 //
212 // sync class is "SS_SOFTWARE" so that both synchronous and asynchronous sampling is possible
213 //
214 
215 #define ss_name memleak
216 #define ss_cls SS_SOFTWARE
217 #define ss_sort_order 30
218 
219 #include "ss_obj.h"
220 
221 
222 // ***************************************************************************
223 // Interface functions
224 // ***************************************************************************
225 
226 // increment the return count
227 //
228 // N.B. : This function is necessary to avoid exposing the retcnt_obj.
229 // For the case of the retcnt sample source, the handler (the trampoline)
230 // is separate from the sample source code.
231 // Consequently, the interaction with metrics must be done procedurally
232 
233 int
235 {
236  return alloc_metric_id;
237 }
238 
239 
240 int
242 {
243  if (hpcrun_is_initialized()) {
245  if (!td) return 0;
246  return (td->ss_state[obj_name().sel_idx] == START);
247  }
248  else {
249  return 0;
250  }
251 }
252 
253 
254 void
256 {
257  if (node != NULL) {
258  TMSG(MEMLEAK, "\talloc (cct node %p): metric[%d] += %d",
259  node, alloc_metric_id, incr);
261  node,
262  (cct_metric_data_t){.i = incr});
263  }
264 }
265 
266 
267 void
269 {
270  if (node != NULL) {
271  TMSG(MEMLEAK, "\tfree (cct node %p): metric[%d] += %d",
272  node, free_metric_id, incr);
273 
275  node,
276  (cct_metric_data_t){.i = incr});
277  }
278 }
thread_data_t * hpcrun_safe_get_td(void)
Definition: thread_data.c:140
int hpcrun_memleak_alloc_id()
Definition: memleak.c:234
#define obj_name()
Definition: ss_obj.h:71
static int free_metric_id
Definition: memleak.c:89
static void METHOD_FN(init)
Definition: memleak.c:98
bool hpcrun_is_initialized()
Definition: main.c:272
cct_node_t * node
Definition: cct.c:128
static void cct_metric_data_increment(int metric_id, cct_node_t *x, cct_metric_data_t incr)
Definition: cct2metrics.h:86
static int alloc_metric_id
Definition: memleak.c:88
static int leak_metric_id
Definition: memleak.c:90
int hpcrun_memleak_active()
Definition: memleak.c:241
static const unsigned int MAX_CHAR_FORMULA
Definition: memleak.c:86
source_state_t * ss_state
Definition: thread_data.h:150
void hpcrun_alloc_inc(cct_node_t *node, int incr)
Definition: memleak.c:255
int lush_metrics
Definition: main.c:188
void * hpcrun_malloc(size_t size)
Definition: mem.c:275
#define TD_GET(field)
Definition: thread_data.h:256
bool hpcrun_ev_is(const char *candidate, const char *event_name)
Definition: tokenize.c:194
#define TMSG(f,...)
Definition: messages.h:93
char * formula
Definition: hpcrun-fmt.h:378
void hpcrun_free_inc(cct_node_t *node, int incr)
Definition: memleak.c:268
#define METHOD_CALL(obj, meth,...)
Definition: simple_oo.h:87
#define NULL
Definition: ElfHelper.cpp:85
Definition: cct.c:96
int hpcrun_new_metric(void)
Definition: metrics.c:333
metric_desc_t * hpcrun_set_metric_info(int metric_id, const char *name)
Definition: metrics.c:423