| |
| /*--------------------------------------------------------------------*/ |
| /*--- 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 ---*/ |
| /*--------------------------------------------------------------------*/ |