You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
248 lines
10 KiB
248 lines
10 KiB
|
|
/*--------------------------------------------------------------------*/ |
|
/*--- An xtree, tree of stacktraces with data pub_tool_xtree.h ---*/ |
|
/*--------------------------------------------------------------------*/ |
|
|
|
/* |
|
This file is part of Valgrind, a dynamic binary instrumentation |
|
framework. |
|
|
|
Copyright (C) 2015-2017 Philippe Waroquiers |
|
|
|
This program is free software; you can redistribute it and/or |
|
modify it under the terms of the GNU General Public License as |
|
published by the Free Software Foundation; either version 2 of the |
|
License, or (at your option) any later version. |
|
|
|
This program is distributed in the hope that it will be useful, but |
|
WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
General Public License for more details. |
|
|
|
You should have received a copy of the GNU General Public License |
|
along with this program; if not, write to the Free Software |
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
|
02111-1307, USA. |
|
|
|
The GNU General Public License is contained in the file COPYING. |
|
*/ |
|
|
|
#ifndef __PUB_TOOL_XTREE_H |
|
#define __PUB_TOOL_XTREE_H |
|
|
|
#include "pub_tool_basics.h" |
|
#include "pub_tool_execontext.h" |
|
|
|
//-------------------------------------------------------------------- |
|
// PURPOSE: an XTree is conceptually a set of stacktraces organised |
|
// as a tree structure. |
|
// A stacktrace (an Addr* ips, i.e. an array of IPs : Instruction Pointers) |
|
// can be added to the tree once transformed into an execontext (ec). |
|
// Some data (typically one or more integer values) can be attached to |
|
// leafs of the tree. |
|
// Non-leaf nodes data is build by combining (typically adding together) |
|
// the data of their children nodes. |
|
// An XTree can be output in various formats. |
|
// |
|
//-------------------------------------------------------------------- |
|
|
|
|
|
/* It's an abstract type. */ |
|
typedef struct _XTree XTree; |
|
|
|
/* 3 functions types used by an xtree to manipulate the data attached to leafs |
|
of an XTree. |
|
XT_init_data_t function is used to initialise (typically to 0) the data |
|
of a new node. |
|
XT_add_data_t function is used to add 'value' to the data 'to'. |
|
XT_sub_data_t function is used to substract 'value' from the data 'from'. |
|
|
|
Note that the add/sub functions can do whatever operations to |
|
combine/integrate value with/into to or from. In other words, add/sub |
|
functions are in fact equivalent to 'Reduce' functions. Add/sub is used |
|
as it is assumed that this module will be mostly used to follow |
|
resource consumption, which can be more clearly modelled with add/sub. |
|
For such resource consumption usage, typically, a call to add means that |
|
some additional resource has been allocated or consumed or ... by the |
|
given ExeContext. Similarly, a call to sub means that some resource |
|
has been released/freed/... by the given execontext. |
|
|
|
Note however that there is no constraints in what add (or sub) can do. For |
|
example, the add function could maintain Min/Max values, or an histogram of |
|
values, or ... */ |
|
typedef void (*XT_init_data_t) (void* value); |
|
typedef void (*XT_add_data_t) (void* to, const void* value); |
|
typedef void (*XT_sub_data_t) (void* from, const void* value); |
|
|
|
/* If not NULL, the XT_filter_IPs_t function is called when a new ec is inserted |
|
in the XTree. |
|
It indicates to the XTree to filter a range of IPs at the top and/or at |
|
the bottom of the ec Stacktrace : *top is the offset of the first IP to take |
|
into account. *n_ips_sel is the nr of IPs selected starting from *top. |
|
|
|
If XT_filter_IPs_t gives *n_ips_sel equal to 0, then the inserted ec will |
|
be fully ignored when outputting the xtree: |
|
the ec value(s) will not be counted in the XTree total, |
|
the ec will not be printed/shown. |
|
Note however that the filtering only influences the output of an XTree : |
|
the ec is still inserted in the XTree, and the XT_*_data_t functions are |
|
called in any case for such filtered ec. */ |
|
typedef void (*XT_filter_IPs_t) (Addr* ips, Int n_ips, |
|
UInt* top, UInt* n_ips_sel); |
|
|
|
/* Create new XTree, using given allocation and free function. |
|
This function never returns NULL. |
|
cc is the allocation cost centre. |
|
alloc_fn must not return NULL (that is, if it returns it must have |
|
succeeded.). |
|
See respective typedef for *_fn arguments. */ |
|
extern XTree* VG_(XT_create) ( Alloc_Fn_t alloc_fn, |
|
const HChar* cc, |
|
Free_Fn_t free_fn, |
|
Word dataSzB, |
|
XT_init_data_t init_data_fn, |
|
XT_add_data_t add_data_fn, |
|
XT_sub_data_t sub_data_fn, |
|
XT_filter_IPs_t filter_IPs_fn); |
|
|
|
|
|
/* General useful filtering functions. */ |
|
|
|
/* Filter functions below main, unless VG_(clo_show_below_main) is True. */ |
|
extern void VG_(XT_filter_maybe_below_main) |
|
(Addr* ips, Int n_ips, |
|
UInt* top, UInt* n_ips_sel); |
|
/* Same as VG_(XT_filter_maybe_below_main) but also filters one top function |
|
(typically to ignore the top level malloc/new/... fn). */ |
|
extern void VG_(XT_filter_1top_and_maybe_below_main) |
|
(Addr* ips, Int n_ips, |
|
UInt* top, UInt* n_ips_sel); |
|
|
|
/* Search in ips[0..n_ips-1] the first function which is main or below main |
|
and return its offset. |
|
If no main or below main is found, return n_ips-1 */ |
|
extern Int VG_(XT_offset_main_or_below_main)(Addr* ips, Int n_ips); |
|
|
|
|
|
/* Take a (frozen) snapshot of xt. |
|
Note that the resulting XTree is 'read-only' : calls to |
|
VG_(XT_add_to_*)/VG_(XT_sub_from_*) will assert. |
|
|
|
Note: to spare memory, some data is shared between an xt and all its |
|
snapshots. This memory is released when the last XTree using this memory |
|
is deleted. */ |
|
extern XTree* VG_(XT_snapshot)(XTree* xt); |
|
|
|
/* Non frozen dup currently not needed : |
|
extern XTree* VG_(XT_dup)(XTree* xt); */ |
|
|
|
/* Free all memory associated with an XTRee. */ |
|
extern void VG_(XT_delete)(XTree* xt); |
|
|
|
/* an Xecu identifies an exe context+its associated data in an XTree. */ |
|
typedef UInt Xecu; |
|
|
|
/* If not yet in xt, inserts the provided ec and initialises its |
|
data by calling init_data_fn. |
|
If already present (or after insertion), updates the data by calling |
|
add_data_fn. */ |
|
extern Xecu VG_(XT_add_to_ec)(XTree* xt, ExeContext* ec, const void* value); |
|
|
|
/* If not yet in xt, inserts the provided ec and initialises its |
|
data by calling init_data_fn. |
|
If already present (or after insertion), updates the data by calling |
|
sub_data_fn to substract value from the data associated to ec. */ |
|
extern Xecu VG_(XT_sub_from_ec)(XTree* xt, ExeContext* ec, const void* value); |
|
|
|
/* Same as (but more efficient than) VG_(XT_add_to_ec) and VG_(XT_sub_from_ec) |
|
for an ec already inserted in xt. */ |
|
extern void VG_(XT_add_to_xecu)(XTree* xt, Xecu xecu, const void* value); |
|
extern void VG_(XT_sub_from_xecu)(XTree* xt, Xecu xecu, const void* value); |
|
|
|
/* Return the nr of IPs selected for xecu. 0 means fully filtered. */ |
|
extern UInt VG_(XT_n_ips_sel)(XTree* xt, Xecu xecu); |
|
|
|
/* Return the ExeContext associated to the Xecu. */ |
|
extern ExeContext* VG_(XT_get_ec_from_xecu) (XTree* xt, Xecu xecu); |
|
|
|
/* -------------------- CALLGRIND/KCACHEGRIND OUTPUT FORMAT --------------*/ |
|
/* Prints xt in outfilename in callgrind/kcachegrind format. |
|
events is a comma separated list of events, used by |
|
kcachegrind/callgrind_annotate/... to name the value various components. |
|
An event can optionally have a longer description, separated from the |
|
event name by " : ", e.g. |
|
"curB : currently allocated Bytes,curBk : Currently allocated Blocks" |
|
img_value returns an image of the value. The image must be a space |
|
separated set of integers, matching the corresponding event in events. |
|
Note that the returned pointer can be static data. |
|
img_value can return NULL if value (and its associated ExeContext) should |
|
not be printed. |
|
*/ |
|
extern void VG_(XT_callgrind_print) |
|
(XTree* xt, |
|
const HChar* outfilename, |
|
const HChar* events, |
|
const HChar* (*img_value) (const void* value)); |
|
|
|
|
|
/* -------------------- MASSIF OUTPUT FORMAT --------------*/ |
|
// Time is measured either in i or ms or bytes, depending on the --time-unit |
|
// option. It's a Long because it can exceed 32-bits reasonably easily, and |
|
// because we need to allow negative values to represent unset times. |
|
typedef Long Time; |
|
|
|
typedef void MsFile; |
|
|
|
/* Create a new file or truncate existing file for printing xtrees in |
|
massif format. time_unit is a string describing the unit used |
|
in Massif_Header time. |
|
Produces a user error msg and returns NULL if file cannot be opened. |
|
Caller must VG_(XT_massif_close) the returned file. */ |
|
extern MsFile* VG_(XT_massif_open)(const HChar* outfilename, |
|
const HChar* desc, // can be NULL |
|
const XArray* desc_args, // can be NULL |
|
const HChar* time_unit); |
|
|
|
extern void VG_(XT_massif_close)(MsFile* fp); |
|
|
|
typedef |
|
struct { |
|
int snapshot_n; // starting at 0. |
|
Time time; |
|
|
|
ULong sz_B; // sum of values, only used when printing a NULL xt. |
|
ULong extra_B; |
|
ULong stacks_B; |
|
|
|
Bool detailed; |
|
Bool peak; |
|
|
|
/* top_node_desc: description for the top node. |
|
Typically for memory usage, give xt_heap_alloc_functions_desc. */ |
|
const HChar* top_node_desc; |
|
|
|
/* children with less than sig_threshold * total xt sz will be aggregated |
|
and printed as one single child. */ |
|
double sig_threshold; |
|
|
|
} Massif_Header; |
|
|
|
/* Prints xt in outfilename in massif format. |
|
If a NULL xt is provided, then only the header information is used |
|
to produce the (necessarily not detailed) snapshot. |
|
report_value must return the value to be used for the report production. |
|
It will typically be the nr of bytes allocated stored with the execontext |
|
but it could be anything measured with a ULong (e.g. the nr of blocks |
|
allocated, or a number of calls, ...). |
|
*/ |
|
extern void VG_(XT_massif_print) |
|
(MsFile* fp, |
|
XTree* xt, |
|
const Massif_Header* header, |
|
ULong (*report_value)(const void* value)); |
|
|
|
#endif // __PUB_TOOL_XTREE_H |
|
|
|
/*--------------------------------------------------------------------*/ |
|
/*--- end pub_tool_xtree.h ---*/ |
|
/*--------------------------------------------------------------------*/
|
|
|