HPCToolkit
cct_insert_backtrace.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 #include <stdint.h>
48 #include <stdbool.h>
49 #include <ucontext.h>
50 
51 #include <cct/cct_bundle.h>
52 #include <cct/cct.h>
53 #include <messages/messages.h>
54 #include <hpcrun/metrics.h>
55 // #include <hpcrun/unresolved.h>
56 
59 #include <lush/lush-backtrace.h>
60 #include <thread_data.h>
61 #include <hpcrun_stats.h>
62 #include <trace.h>
65 #include "frame.h"
68 #include "cct_insert_backtrace.h"
69 #include "cct_backtrace_finalize.h"
70 
71 
72 //--------------------------------------------------------------------------
73 // forward declaration
74 //--------------------------------------------------------------------------
75 
76 static cct_node_t*
77 help_hpcrun_backtrace2cct(cct_bundle_t* cct, ucontext_t* context,
78  int metricId, hpcrun_metricVal_t metricIncr,
79  int skipInner, int isSync, struct cct_custom_update_s *custom_update);
80 
81 
82 //
83 // Misc externals (not in an include file)
84 //
85 extern bool hpcrun_inbounds_main(void* addr);
86 
87 //--------------------------------------------------------------------------
88 // local variables
89 //--------------------------------------------------------------------------
90 // local variable records the on/off state of
91 // special recursive compression:
92 static bool retain_recursion = false;
93 
94 
95 //--------------------------------------------------------------------------
96 // Implementation
97 //--------------------------------------------------------------------------
98 
99 static cct_node_t*
101  frame_t* path_beg, frame_t* path_end)
102 {
103  TMSG(BT_INSERT, "%s : start", __func__);
104  if (!cct) return NULL; // nowhere to insert
105 
106 #if 0
107  if (path_beg < path_end) { // null backtrace
108  return cct_backtrace_null_handler(cct);
109  }
110 #endif
111 
112  ip_normalized_t parent_routine = ip_normalized_NULL;
113  for(; path_beg >= path_end; path_beg--){
114  if ( (! retain_recursion) &&
115  (path_beg >= path_end + 1) &&
116  ip_normalized_eq(&(path_beg->the_function), &(parent_routine)) &&
117  ip_normalized_eq(&(path_beg->the_function), &((path_beg-1)->the_function))) {
118  TMSG(REC_COMPRESS, "recursive routine compression!");
119  }
120  else {
121  cct_addr_t tmp =
122  (cct_addr_t) {.as_info = path_beg->as_info,
123  .ip_norm = path_beg->ip_norm,
124  .lip = path_beg->lip};
125  TMSG(BT_INSERT, "inserting addr (%d, %p)", tmp.ip_norm.lm_id, tmp.ip_norm.lm_ip);
126  cct = hpcrun_cct_insert_addr(cct, &tmp);
127  }
128  parent_routine = path_beg->the_function;
129  }
131  return cct;
132 }
133 
134 
135 //
136 //
137 void
139 {
140  TMSG(REC_COMPRESS, "retain_recursion set to %s", mode ? "true" : "false");
141  retain_recursion = mode;
142 }
143 
144 
145 // See usage in header.
146 cct_node_t*
147 hpcrun_cct_insert_backtrace(cct_node_t* treenode, frame_t* path_beg, frame_t* path_end)
148 {
149  TMSG(FENCE, "insert backtrace into treenode %p", treenode);
150  TMSG(FENCE, "backtrace below");
151  bool bt_ins = ENABLED(BT_INSERT);
152  if (ENABLED(FENCE)) {
153  ENABLE(BT_INSERT);
154  }
155 
156  cct_node_t* path = cct_insert_raw_backtrace(treenode, path_beg, path_end);
157  if (! bt_ins) DISABLE(BT_INSERT);
158 
159  // Put lush as_info class correction here
160 
161  // N.B. If 'frm' is a 1-to-1 bichord and 'path' is not (i.e., 'path'
162  // is M-to-1 or 1-to-M), then update the association of 'path' to
163  // reflect that 'path' is now a proxy for two bichord types (1-to-1
164  // and M-to-1 or 1-to-M)
165 
167 
168  lush_assoc_t as_frm = lush_assoc_info__get_assoc(path_beg->as_info);
170 
171  if (as_frm == LUSH_ASSOC_1_to_1 && as_path != LUSH_ASSOC_1_to_1) {
172  // INVARIANT: path->as_info should be either M-to-1 or 1-to-M
174  }
175  return path;
176 }
177 
178 
179 
180 // See usage in header.
181 cct_node_t*
183  int metric_id,
184  frame_t* path_beg, frame_t* path_end,
185  cct_metric_data_t datum,
186  struct cct_custom_update_s *custom_update)
187 {
188  // user-custom cct before official backtrace
189  if (custom_update != NULL && custom_update->update_before_fn != NULL) {
190  treenode = custom_update->update_before_fn(cct, treenode, custom_update->data_aux);
191  }
192 
193  // the official backtrace insertion
194  cct_node_t* path = hpcrun_cct_insert_backtrace(treenode, path_beg, path_end);
195 
196  // user-custom cct after the official backtrace
197  if (custom_update != NULL && custom_update->update_after_fn != NULL) {
198  path = custom_update->update_after_fn(path, custom_update->data_aux);
199  }
200 
202 
203  metric_upd_proc_t* upd_proc = hpcrun_get_metric_proc(metric_id);
204  if (upd_proc) {
205  upd_proc(metric_id, mset, datum);
206  }
207 
208  // POST-INVARIANT: metric set has been allocated for 'path'
209 
210  return path;
211 }
212 
213 //
214 // Insert new backtrace in cct
215 //
216 
217 cct_node_t*
219  int metricId,
220  backtrace_t* bt,
221  cct_metric_data_t datum, void **trace_pc)
222 {
223  return hpcrun_cct_insert_backtrace_w_metric(NULL, node, metricId,
224  bt->beg + bt->len - 1,
225  bt->beg,
226  datum, NULL);
227 }
228 
229 
230 //-----------------------------------------------------------------------------
231 // function: hpcrun_backtrace2cct
232 // purpose:
233 // if successful, returns the leaf node representing the sample;
234 // otherwise, returns NULL.
235 //-----------------------------------------------------------------------------
236 
237 //
238 // TODO: one more flag:
239 // backtrace needs to either:
240 // IGNORE_TRAMPOLINE (usually, but not always called when isSync is true)
241 // PLACE_TRAMPOLINE (standard for normal async samples).
242 //
243 
244 cct_node_t*
245 hpcrun_backtrace2cct(cct_bundle_t* cct, ucontext_t* context,
246  int metricId, hpcrun_metricVal_t metricIncr,
247  int skipInner, int isSync, struct cct_custom_update_s *custom_update)
248 {
249  cct_node_t* n = NULL;
250  if (hpcrun_isLogicalUnwind()) {
251  TMSG(LUSH,"lush backtrace2cct invoked");
252  n = lush_backtrace2cct(cct, context, metricId, metricIncr, skipInner,
253  isSync);
254  }
255  else {
256  TMSG(BT_INSERT,"regular (NON-lush) backtrace2cct invoked");
257  n = help_hpcrun_backtrace2cct(cct, context,
258  metricId, metricIncr,
259  skipInner, isSync, custom_update);
260  }
261 
262  // N.B.: for lush_backtrace() it may be that n = NULL
263 
264  return n;
265 }
266 
267 
268 cct_node_t*
270  cct_bundle_t* cct,
271  bool partial,
272  backtrace_info_t *bt,
273  bool tramp_found
274 )
275 {
276  TMSG(FENCE, "Recording backtrace");
278  cct_node_t* cct_cursor = cct->tree_root;
279  TMSG(FENCE, "Initially picking tree root = %p", cct_cursor);
280  if (tramp_found) {
281  // start insertion below caller's frame, which is marked with the trampoline
282  cct_cursor = hpcrun_cct_parent(td->tramp_cct_node);
283  TMSG(FENCE, "Tramp found ==> cursor = %p", cct_cursor);
284  }
285  if (partial) {
286  cct_cursor = cct->partial_unw_root;
287  TMSG(FENCE, "Partial unwind ==> cursor = %p", cct_cursor);
288  }
289  if (bt->fence == FENCE_THREAD) {
290  cct_cursor = cct->thread_root;
291  TMSG(FENCE, "Thread stop ==> cursor = %p", cct_cursor);
292  }
293 
294 #if 0
295  // datacentric support: attach samples to data allocation cct
296  cct_node_t *data_node = TD_GET(mem_data.data_node);
297  if(data_node) {
298  cct_node_t *prefix = hpcrun_cct_insert_path_return_leaf(data_node, cct_cursor);
299  cct_cursor = prefix;
300  TD_GET(mem_data.data_node) = NULL;
301  }
302 #endif
303 
304  TMSG(FENCE, "sanity check cursor = %p", cct_cursor);
305  TMSG(FENCE, "further sanity check: bt->last frame = (%d, %p)",
306  bt->last->ip_norm.lm_id, bt->last->ip_norm.lm_ip);
307 
308  return hpcrun_cct_insert_backtrace(cct_cursor, bt->last, bt->begin);
309 
310 }
311 
312 
313 cct_node_t*
315  backtrace_info_t *bt, bool tramp_found,
316  int metricId, hpcrun_metricVal_t metricIncr,
317  struct cct_custom_update_s *custom_update)
318 {
319  TMSG(FENCE, "Recording backtrace");
320  TMSG(BT_INSERT, "Record backtrace w metric to id %d, incr = %d",
321  metricId, metricIncr.i);
322 
324  cct_node_t* cct_cursor = cct->tree_root;
325  TMSG(FENCE, "Initially picking tree root = %p", cct_cursor);
326  if (tramp_found) {
327  // start insertion below caller's frame, which is marked with the trampoline
328  cct_cursor = hpcrun_cct_parent(td->tramp_cct_node);
329  TMSG(FENCE, "Tramp found ==> cursor = %p", cct_cursor);
330  }
331  if (partial) {
332  cct_cursor = cct->partial_unw_root;
333  TMSG(FENCE, "Partial unwind ==> cursor = %p", cct_cursor);
334  }
335  if (bt->fence == FENCE_THREAD) {
336  cct_cursor = cct->thread_root;
337  TMSG(FENCE, "Thread stop ==> cursor = %p", cct_cursor);
338  }
339 
340  cct_cursor = cct_cursor_finalize(cct, bt, cct_cursor);
341 
342  TMSG(FENCE, "sanity check cursor = %p", cct_cursor);
343  TMSG(FENCE, "further sanity check: bt->last frame = (%d, %p)",
344  bt->last->ip_norm.lm_id, bt->last->ip_norm.lm_ip);
345 
346  return hpcrun_cct_insert_backtrace_w_metric(cct, cct_cursor, metricId,
347  bt->last, bt->begin,
348  (cct_metric_data_t) metricIncr,
349  custom_update);
350 
351 }
352 
353 
354 static cct_node_t*
355 help_hpcrun_backtrace2cct(cct_bundle_t* bundle, ucontext_t* context,
356  int metricId,
357  hpcrun_metricVal_t metricIncr,
358  int skipInner, int isSync,
359  struct cct_custom_update_s *custom_update)
360 {
361  bool tramp_found;
362 
364  backtrace_info_t bt;
365 
366  bool success = hpcrun_generate_backtrace(&bt, context, skipInner);
367 
368  assert(!success == bt.partial_unwind);
369 
370  tramp_found = bt.has_tramp;
371 
372  //
373  // Check to make sure node below monitor_main is "main" node
374  //
375  // TMSG(GENERIC1, "tmain chk");
376  if (ENABLED(CHECK_MAIN)) {
377  if ( bt.fence == FENCE_MAIN &&
378  ! bt.partial_unwind &&
379  ! tramp_found &&
380  (bt.last == bt.begin ||
382  hpcrun_bt_dump(TD_GET(btbuf_cur), "WRONG MAIN");
384  bt.partial_unwind = true;
385  }
386  }
387 
388  // bt.trace_pc = bt.begin->cursor.pc_unnorm; // JMC
389 
390  cct_backtrace_finalize(&bt, isSync);
391 
392  if (bt.partial_unwind) {
393  if (ENABLED(NO_PARTIAL_UNW)){
394  return NULL;
395  }
396 
397  TMSG(PARTIAL_UNW, "recording partial unwind from graceful failure, "
398  "len partial unw = %d", (bt.last - bt.begin)+1);
400  }
401 
402  cct_node_t* n =
404  tramp_found, metricId, metricIncr,
405  custom_update);
406 
407  // *trace_pc = bt.trace_pc; // JMC
408 
409  if (bt.n_trolls != 0) hpcrun_stats_trolled_inc();
410  hpcrun_stats_frames_total_inc((long)(bt.last - bt.begin + 1));
412 
413  if (ENABLED(USE_TRAMP)){
414  TMSG(TRAMP, "--NEW SAMPLE--: Remove old trampoline");
416  td->tramp_frame = td->cached_bt;
417  TMSG(TRAMP, "--NEW SAMPLE--: Insert new trampoline");
419  }
420 
421  return n;
422 }
void hpcrun_trampoline_insert(cct_node_t *node)
Definition: trampoline.c:167
fence_enum_t fence
#define ip_normalized_NULL
Definition: ip-normalized.h:83
void hpcrun_cct_terminate_path(cct_node_t *node)
Definition: cct.c:452
void hpcrun_stats_num_samples_dropped_inc(void)
Definition: hpcrun_stats.c:187
bool hpcrun_generate_backtrace(backtrace_info_t *bt, ucontext_t *context, int skipInner)
Definition: backtrace.c:307
metric_set_t * hpcrun_reify_metric_set(cct_node_id_t cct_id)
Definition: cct2metrics.c:115
static char * tmp
Definition: tokenize.c:63
static void * hpcrun_frame_get_unnorm(frame_t *frame)
Definition: frame.h:69
size_t len
Definition: backtrace.h:84
frame_t * beg
Definition: backtrace.h:85
void hpcrun_stats_frames_total_inc(long amt)
Definition: hpcrun_stats.c:291
#define DISABLE(f)
Definition: debug-flag.h:74
void hpcrun_stats_num_samples_partial_inc(void)
Definition: hpcrun_stats.c:203
void metric_upd_proc_t(int metric_id, metric_set_t *set, cct_metric_data_t datum)
Definition: metrics.h:79
cct_node_t * hpcrun_cct_insert_bt(cct_node_t *node, int metricId, backtrace_t *bt, cct_metric_data_t datum, void **trace_pc)
ip_normalized_t ip_norm
Definition: frame.h:61
static bool hpcrun_isLogicalUnwind()
hpcrun_cct_update_after_t update_after_fn
ip_normalized_t the_function
Definition: frame.h:62
static bool retain_recursion
cct_node_t * node
Definition: cct.c:128
static cct_node_t * cct_insert_raw_backtrace(cct_node_t *cct, frame_t *path_beg, frame_t *path_end)
cct_node_t * tree_root
Definition: cct_bundle.h:65
static cct_node_t * help_hpcrun_backtrace2cct(cct_bundle_t *cct, ucontext_t *context, int metricId, hpcrun_metricVal_t metricIncr, int skipInner, int isSync, struct cct_custom_update_s *custom_update)
cct_node_t * hpcrun_cct_record_backtrace(cct_bundle_t *cct, bool partial, backtrace_info_t *bt, bool tramp_found)
cct_node_t * hpcrun_cct_record_backtrace_w_metric(cct_bundle_t *cct, bool partial, backtrace_info_t *bt, bool tramp_found, int metricId, hpcrun_metricVal_t metricIncr, struct cct_custom_update_s *custom_update)
uintptr_t lm_ip
Definition: ip-normalized.h:78
#define ENABLE(f)
Definition: debug-flag.h:73
cct_node_t * hpcrun_cct_parent(cct_node_t *x)
Definition: cct.c:357
frame_t * cached_bt
Definition: thread_data.h:202
metric_upd_proc_t * hpcrun_get_metric_proc(int metric_id)
Definition: metrics.c:281
static char * prefix
Definition: common.c:164
frame_t * tramp_frame
Definition: thread_data.h:205
#define lush_assoc_info__set_assoc(x, new_as)
Definition: lush-support.h:264
cct_node_t * hpcrun_cct_insert_addr(cct_node_t *node, cct_addr_t *frm)
Definition: cct.c:405
cct_node_t * lush_backtrace2cct(cct_bundle_t *cct, ucontext_t *context, int metricId, hpcrun_metricVal_t metricIncr, int skipInner, int isSync)
lush_lip_t * lip
Definition: frame.h:64
struct cct_addr_t cct_addr_t
Definition: cct_addr.h:55
void hpcrun_stats_trolled_inc(void)
Definition: hpcrun_stats.c:275
ip_normalized_t ip_norm
Definition: cct_addr.h:66
static lush_assoc_t lush_assoc_info__get_assoc(lush_assoc_info_t x)
Definition: lush-support.h:215
cct_node_t * hpcrun_backtrace2cct(cct_bundle_t *cct, ucontext_t *context, int metricId, hpcrun_metricVal_t metricIncr, int skipInner, int isSync, struct cct_custom_update_s *custom_update)
lush_assoc_info_t as_info
Definition: cct_addr.h:60
#define TD_GET(field)
Definition: thread_data.h:256
cct_node_t * partial_unw_root
Definition: cct_bundle.h:74
cct_node_t * cct_cursor_finalize(cct_bundle_t *cct, backtrace_info_t *bt, cct_node_t *cursor)
cct_node_t * tramp_cct_node
Definition: thread_data.h:206
void hpcrun_stats_trolled_frames_inc(long amt)
Definition: hpcrun_stats.c:307
hpcrun_cct_update_before_t update_before_fn
enum lush_assoc lush_assoc_t
Definition: lush-support.h:164
#define TMSG(f,...)
Definition: messages.h:93
static bool ip_normalized_eq(const ip_normalized_t *a, const ip_normalized_t *b)
Definition: ip-normalized.h:94
#define NULL
Definition: ElfHelper.cpp:85
lush_assoc_info_t as_info
Definition: frame.h:60
cct_node_t * hpcrun_cct_insert_path_return_leaf(cct_node_t *path, cct_node_t *root)
Definition: cct.c:871
cct_node_t * hpcrun_cct_insert_backtrace(cct_node_t *treenode, frame_t *path_beg, frame_t *path_end)
cct_node_t * thread_root
Definition: cct_bundle.h:72
Definition: cct.c:96
Definition: frame.h:58
void hpcrun_bt_dump(frame_t *unwind, const char *tag)
Definition: backtrace.c:90
cct_addr_t * addr
Definition: cct.c:130
void cct_backtrace_finalize(backtrace_info_t *bt, int isSync)
<!-- ********************************************************************--> n<!-- HPCToolkit Experiment DTD --> n<!-- Version 2.1 --> n<!-- ********************************************************************--> n<!ELEMENT HPCToolkitExperiment(Header,(SecCallPathProfile|SecFlatProfile) *)> n<!ATTLIST HPCToolkitExperiment\n version CDATA #REQUIRED > n n<!-- ******************************************************************--> n n<!-- Info/NV:flexible name-value pairs:(n) ame;(t) ype;(v) alue --> n<!ELEMENT Info(NV *)> n<!ATTLIST Info\n n CDATA #IMPLIED > n<!ELEMENT NV EMPTY > n<!ATTLIST NV\n n CDATA #REQUIRED\n t CDATA #IMPLIED\n v CDATA #REQUIRED > n n<!-- ******************************************************************--> n<!-- Header --> n<!-- ******************************************************************--> n<!ELEMENT Header(Info *)> n<!ATTLIST Header\n n CDATA #REQUIRED > n n<!-- ******************************************************************--> n<!-- Section Header --> n<!-- ******************************************************************--> n<!ELEMENT SecHeader(MetricTable?, MetricDBTable?, TraceDBTable?, LoadModuleTable?, FileTable?, ProcedureTable?, Info *)> n n<!-- MetricTable:--> n<!ELEMENT MetricTable(Metric) * > n n<!-- Metric:(i) d;(n) ame --> n<!--(v) alue-type:transient type of values --> n<!--(t) ype:persistent type of metric --> n<!-- fmt:format;show;--> n<!ELEMENT Metric(MetricFormula *, Info?)> n<!ATTLIST Metric\n i CDATA #REQUIRED\n n CDATA #REQUIRED\n es CDATA #IMPLIED\n em CDATA #IMPLIED\n ep CDATA #IMPLIED\n v(raw|final|derived-incr|derived) \"raw\\ t (inclusive|exclusive|nil) \nil\\ partner CDATA #IMPLIED\ fmt CDATA #IMPLIED\ show (1|0) \1\\ show-percent (1|0) \1> n n<!-- MetricFormula represents derived metrics: (t)ype; (frm): formula --> n<!ELEMENT MetricFormula (Info?)> n<!ATTLIST MetricFormula\ t (combine|finalize) \finalize\\ i CDATA #IMPLIED\ frm CDATA #REQUIRED> n n<!-- Metric data, used in sections: (n)ame [from Metric]; (v)alue --> n<!ELEMENT M EMPTY> n<!ATTLIST M\ n CDATA #REQUIRED\ v CDATA #REQUIRED> n n<!-- MetricDBTable: --> n<!ELEMENT MetricDBTable (MetricDB)*> n n<!-- MetricDB: (i)d; (n)ame --> n<!-- (t)ype: persistent type of metric --> n<!-- db-glob: file glob describing files in metric db --> n<!-- db-id: id within metric db --> n<!-- db-num-metrics: number of metrics in db --> n<!-- db-header-sz: size (in bytes) of a db file header --> n<!ELEMENT MetricDB EMPTY> n<!ATTLIST MetricDB\ i CDATA #REQUIRED\ n CDATA #REQUIRED\ t (inclusive|exclusive|nil) \nil\\ partner CDATA #IMPLIED\ db-glob CDATA #IMPLIED\ db-id CDATA #IMPLIED\ db-num-metrics CDATA #IMPLIED\ db-header-sz CDATA #IMPLIED> n n<!-- TraceDBTable: --> n<!ELEMENT TraceDBTable (TraceDB)> n n<!-- TraceDB: (i)d --> n<!-- db-min-time: min beginning time stamp (global) --> n<!-- db-max-time: max ending time stamp (global) --> n<!ELEMENT TraceDB EMPTY> n<!ATTLIST TraceDB\ i CDATA #REQUIRED\ db-glob CDATA #IMPLIED\ db-min-time CDATA #IMPLIED\ db-max-time CDATA #IMPLIED\ db-header-sz CDATA #IMPLIED> n n<!-- LoadModuleTable assigns a short name to a load module --> n<!ELEMENT LoadModuleTable (LoadModule)*> n n<!ELEMENT LoadModule (Info?)> n<!ATTLIST LoadModule\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!-- FileTable assigns a short name to a file --> n<!ELEMENT FileTable (File)*> n n<!ELEMENT File (Info?)> n<!ATTLIST File\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!-- ProcedureTable assigns a short name to a procedure --> n<!ELEMENT ProcedureTable (Procedure)*> n n<!-- Info/NV: flexible name-value pairs: (n)ame; (t)ype; (v)alue --> n<!-- f: family of the procedure (fake, root, ...)--> n<!ELEMENT Procedure (Info?)> n<!ATTLIST Procedure\ i CDATA #REQUIRED\ n CDATA #REQUIRED\ f CDATA #IMPLIED> n n<!-- ****************************************************************** --> n<!-- Section: Call path profile --> n<!-- ****************************************************************** --> n<!ELEMENT SecCallPathProfile (SecHeader, SecCallPathProfileData)> n<!ATTLIST SecCallPathProfile\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!ELEMENT SecCallPathProfileData (PF|M)*> n<!-- Procedure frame --> n<!-- (i)d: unique identifier for cross referencing --> n<!-- (s)tatic scope id --> n<!-- (n)ame: a string or an id in ProcedureTable --> n<!-- (lm) load module: a string or an id in LoadModuleTable --> n<!-- (f)ile name: a string or an id in LoadModuleTable --> n<!-- (l)ine range: \beg-end\ (inclusive range) --> n<!-- (a)lien: whether frame is alien to enclosing P --> n<!-- (str)uct: hpcstruct node id --> n<!-- (t)ype: hpcrun node type: memory access, variable declaration, ... --> n<!-- (v)ma-range-set: \{[beg-end), [beg-end)...}\ --> n<!ELEMENT PF (PF|Pr|L|C|S|M)*> n<!ATTLIST PF\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ n CDATA #REQUIRED\ lm CDATA #IMPLIED\ f CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Procedure (static): GOAL: replace with 'P' --> n<!ELEMENT Pr (Pr|L|C|S|M)*> n<!ATTLIST Pr\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ n CDATA #REQUIRED\ lm CDATA #IMPLIED\ f CDATA #IMPLIED\ l CDATA #IMPLIED\ a (1|0) \0\\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Callsite (a special StatementRange) --> n<!ELEMENT C (PF|M)*> n<!ATTLIST C\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n n<!-- ****************************************************************** --> n<!-- Section: Flat profile --> n<!-- ****************************************************************** --> n<!ELEMENT SecFlatProfile (SecHeader, SecFlatProfileData)> n<!ATTLIST SecFlatProfile\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!ELEMENT SecFlatProfileData (LM|M)*> n<!-- Load module: (i)d; (n)ame; (v)ma-range-set --> n<!ELEMENT LM (F|P|M)*> n<!ATTLIST LM\ i CDATA #IMPLIED\ n CDATA #REQUIRED\ v CDATA #IMPLIED> n<!-- File --> n<!ELEMENT F (P|L|S|M)*> n<!ATTLIST F\ i CDATA #IMPLIED\ n CDATA #REQUIRED> n<!-- Procedure (Note 1) --> n<!ELEMENT P (P|A|L|S|C|M)*> n<!ATTLIST P\ i CDATA #IMPLIED\ n CDATA #REQUIRED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Alien (Note 1) --> n<!ELEMENT A (A|L|S|C|M)*> n<!ATTLIST A\ i CDATA #IMPLIED\ f CDATA #IMPLIED\ n CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Loop (Note 1,2) --> n<!ELEMENT L (A|Pr|L|S|C|M)*> n<!ATTLIST L\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ f CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Statement (Note 2) --> n<!-- (it): trace record identifier --> n<!ELEMENT S (S|M)*> n<!ATTLIST S\ i CDATA #IMPLIED\ it CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Note 1: Contained Cs may not contain PFs --> n<!-- Note 2: The 's' attribute is not used for flat profiles --> n
bool hpcrun_inbounds_main(void *addr)
Definition: main.c:284
void hpcrun_trampoline_remove(void)
Definition: trampoline.c:197
void hpcrun_set_retain_recursion_mode(bool mode)
cct_node_t * hpcrun_cct_insert_backtrace_w_metric(cct_bundle_t *cct, cct_node_t *treenode, int metric_id, frame_t *path_beg, frame_t *path_end, cct_metric_data_t datum, struct cct_custom_update_s *custom_update)
#define ENABLED(f)
Definition: debug-flag.h:76
thread_data_t *(* hpcrun_get_thread_data)(void)
Definition: thread_data.c:168
cct_addr_t * hpcrun_cct_addr(cct_node_t *node)
Definition: cct.c:369