CCTLib
Calling-context and data-object attribution library for Intel Pin
cctlib.H
Go to the documentation of this file.
1 // @COPYRIGHT@
2 // Licensed under MIT license.
3 // See LICENSE.TXT file in the project root for more information.
4 // ==============================================================
5 
6 #ifndef __CCTLIB_H__
7 #define __CCTLIB_H__
8 
9 
10 #include "pin.H"
11 #include <stdint.h>
12 #include <stdio.h>
13 #include <string>
14 #include <vector>
15 
16 #define MAX_CCT_PRINT_DEPTH (20)
17 #define MAX_CCT_PATH_DEPTH (100)
18 #define MAX_FILE_PATH (200)
19 
20 namespace PinCCTLib {
21 
22 using ContextHandle_t = uint32_t;
23 
24 // Enum representing different data object types
29 
30 // The handle representing a data object
31 using DataHandle_t = struct DataHandle_t {
32  uint8_t objectType;
33  union {
35  uint32_t symName;
36  };
37 #ifdef USE_TREE_BASED_FOR_DATA_CENTRIC
38 // Milind- I commented this out since it consumes too much space.
39 // Need to discuss with Xu on how we want to maintain this efficiently
40 #ifdef USE_TREE_WITH_ADDR
41  uint64_t beg_addr;
42  uint64_t end_addr;
43 #endif
44 #endif
45 };
46 
47 // Data type returned when a client tool queries GetFullCallingContext
48 using Context = struct Context {
49  std::string functionName;
50  std::string filePath;
51  std::string disassembly;
53  uint32_t lineNo;
54  ADDRINT ip;
55 };
56 
57 using HPCRunCCT_t = struct HPCRunCCT_t {
58  ContextHandle_t ctxtHandle1;
60  uint64_t metric;
61  int metric_id;
62 };
63 
64 // Client callback function to determine if it wants to track a given INS
65 using IsInterestingInsFptr = BOOL (*)(INS);
66 
67 // Client callback made from CCTLib for each instruction indicated to be tracked by the client.
68 using CCTLibInstrumentInsCallback = VOID (*)(INS, VOID*, const uint32_t);
69 
70 // Predefined callback for tracking no INS
71 inline BOOL InterestingInsNone(INS ins) {
72  return false;
73 }
74 
75 // Predefined callback for tracking all INS
76 inline BOOL InterestingInsAll(INS ins) {
77  return true;
78 }
79 
80 // Predefined callback for tracking all memory INS
81 inline BOOL InterestingInsMemoryAccess(INS ins) {
82  return (INS_MemoryOperandCount(ins) > 0);
83 }
84 
85 #define INTERESTING_INS_ALL (PinCCTLib::InterestingInsAll)
86 #define INTERESTING_INS_NONE (PinCCTLib::InterestingInsNone)
87 #define INTERESTING_INS_MEMORY_ACCESS (PinCCTLib::InterestingInsMemoryAccess)
88 
89 /*
90  Description:
91  CCTLib clients must call this before using CCTLib.
92  Note: For postmortem analysis call PinCCTLibInitForPostmortemAnalysis() instead.
93  Arguments:
94  isInterestingIns: a client tool callback that should return boolean true/false if a given INS needs to collect context. Following predefined values are available for client tools: INTERESTING_INS_ALL, INTERESTING_INS_NONE, and INTERESTING_INS_MEMORY_ACCESS.
95  logFile: file pointer where CCTLib will put its output data.
96  userCallback: a client callback that CCTLib calls on each INS for which isInterestingIns is true passing it userCallbackArg value. See one of the examples in tests directory for example usage.
97  doDataCentric: should be set to true if the client wants CCTLib to do data-centric attribution.
98  */
99 int PinCCTLibInit(IsInterestingInsFptr isInterestingIns, FILE* logFile, CCTLibInstrumentInsCallback userCallback, VOID* userCallbackArg, BOOL doDataCentric = false);
100 
101 /*
102  int PinCCTLibInitForPostmortemAnalysis(FILE* logFile, const std::string& serializedFilesDirectory);
103  Description:
104  Reads serialized CCT metadata and rebuilds CCTs for postmortem analysis.
105  Arguments:
106  logFile: file pointer where CCTLib will put its output data.
107  serializedFilesDirectory: Path to directory where previously files were serialized.
108 
109  Caution: This should never be called with PinCCTLibInit().
110  */
111 int PinCCTLibInitForPostmortemAnalysis(FILE* logFile, const std::string& serializedFilesDirectory);
112 
113 /*
114  Description:
115  Client tools call this API when they need the calling context handle (ContextHandle_t).
116  Arguments:
117  threadId: Pin's thread id of the asking thread.
118  opaqueHandle: handle passed by CCTLib to the client tool in its userCallback.
119  */
120 ContextHandle_t GetContextHandle(const THREADID id, const uint32_t slot);
121 
122 /*
123  Description:
124  Client tools call this API when they need the handle to a data object (DataHandle_t).
125  Arguments:
126  address: effectve address for which the data object is needed.
127  threadId: Pin's thread id of the asking thread.
128  */
129 DataHandle_t GetDataObjectHandle(VOID* address, const THREADID threadId);
130 /*
131  Description:
132  Client tools call this API when they need the char string for a symbol from string pool index.
133  Arguments:
134  index: a string pool index
135  */
136 char* GetStringFromStringPool(const uint32_t index);
137 /*
138  Description:
139  Prints the full calling context whose handle is ctxtHandle.
140  */
142 
143 /*
144  Description:
145  Returns the full calling context whose handle is ctxtHandle.
146 
147  Arguments:
148  ctxtHandle: is the context handle for which the full call path is requested.
149  contextVec: is a vector that will be populated with the full call path.
150  */
151 VOID GetFullCallingContext(const ContextHandle_t curCtxtHndle, std::vector<Context>& contextVec);
152 
153 /*
154  Description:
155  Serializes all CCTLib data into files for postmortem analysis.
156 
157  Arguments:
158  directoryForSerializationFiles: directory where serialized files are written.
159  */
160 void SerializeMetadata(const std::string& directoryForSerializationFiles = "");
161 
162 /*
163  Description:
164  Dumps all CCTs into DOT files for visualization.
165  */
166 void DottifyAllCCTs();
167 
168 #ifdef HAVE_METRIC_PER_IPNODE
169 void TraverseCCTBottomUp(const THREADID threadid, void (*opFunc)(const THREADID threadid, ContextHandle_t myHandle, ContextHandle_t parentHandle, void** myMetric, void** parentMetric));
170 void** GetIPNodeMetric(const THREADID id, const uint32_t slot);
171 #endif
172 
173 /*
174  Description:
175  Given two CCT handles, returns true if the call path from root to leaves, except the leaves themselves are the same.
176  */
178 
180 
181 /*
182  Description:
183  Given a ContextHandle, returns the childCtxtStartIdx of
184  the TraceNode that contains it. Two handles that live in
185  the SAME TraceNode return the same value from this call,
186  so it doubles as a compact "same-trace identifier" that
187  clients can use to compare two arbitrary ContextHandle_t's
188  without needing to peek into cctlib internals. Returns 0
189  for the reserved uninitialized handle 0.
190 
191  Motivation: shape-inspection clients (e.g. cct_shape_check)
192  need to identify "is ancestor X the same TraceNode as
193  handle Y?" -- e.g. to slice a chain at main's frame -- but
194  GetFullCallingContext returns a vector<Context> whose
195  ctxtHandle values are specific slots, not TraceNode
196  identifiers. GetTraceStartHandle lets clients canonicalize.
197  */
199 #ifdef USE_TREE_BASED_FOR_DATA_CENTRIC
200 //NOP
201 #elif !defined(USE_SHADOW_FOR_DATA_CENTRIC)
202 // by default use shadow memory technique
203 #define USE_SHADOW_FOR_DATA_CENTRIC
204 #endif
205 
206 void AppendLoadModulesToStream(std::iostream& ios);
207 void LogContexts(std::iostream& ios, ContextHandle_t ctxt1, ContextHandle_t ctxt2);
208 
209 // write the output into hpcviewer's format
210 int init_hpcrun_format(int argc, char* argv[], void (*mergeFunc)(void* des, void* src) = nullptr, uint64_t (*computeMetricVal)(void* metric) = nullptr, bool skip = false);
211 int hpcrun_create_metric(const char* name);
212 int newCCT_hpcrun_write(THREADID threadid);
213 int newCCT_hpcrun_build_cct(std::vector<HPCRunCCT_t*>& OldNodes, THREADID threadid);
214 int newCCT_hpcrun_selection_write(THREADID threadid);
215 
216 
217 void GetParentIPs(ContextHandle_t ctxtHandle, std::vector<ADDRINT>& parentIPs);
218 } // namespace PinCCTLib
219 
220 #endif
uint64_t computeMetricVal(void *metric)
void mergeFunc(void *des, void *src)
static uint64_t src[N]
int metric_id
Definition: cctlib.H:61
uint64_t metric
Definition: cctlib.H:60
DataHandle_t GetDataObjectHandle(VOID *address, const THREADID threadId)
Definition: cctlib.cpp:2495
BOOL InterestingInsNone(INS ins)
Definition: cctlib.H:71
int PinCCTLibInit(IsInterestingInsFptr isInterestingIns, FILE *logFile, CCTLibInstrumentInsCallback userCallback, VOID *userCallbackArg, BOOL doDataCentric=false)
Definition: cctlib.cpp:3132
ContextHandle_t ctxtHandle
Definition: cctlib.H:52
int hpcrun_create_metric(const char *name)
Definition: cctlib.cpp:4281
VOID(*)(INS, VOID *, const uint32_t) CCTLibInstrumentInsCallback
Definition: cctlib.H:68
int newCCT_hpcrun_write(THREADID threadid)
Definition: cctlib.cpp:4291
int newCCT_hpcrun_build_cct(std::vector< HPCRunCCT_t * > &OldNodes, THREADID threadid)
Definition: cctlib.cpp:4343
void DottifyAllCCTs()
Definition: cctlib.cpp:1731
struct HPCRunCCT_t { ContextHandle_t ctxtHandle1 HPCRunCCT_t
Definition: cctlib.H:58
BOOL InterestingInsMemoryAccess(INS ins)
Definition: cctlib.H:81
ContextHandle_t pathHandle
Definition: cctlib.H:34
void GetParentIPs(ContextHandle_t ctxtHandle, std::vector< ADDRINT > &parentIPs)
Definition: cctlib.cpp:2153
VOID PrintFullCallingContext(const ContextHandle_t ctxtHandle)
Definition: cctlib.cpp:2346
int PinCCTLibInitForPostmortemAnalysis(FILE *logFile, const std::string &serializedFilesDirectory)
Definition: cctlib.cpp:3183
ADDRINT ip
Definition: cctlib.H:54
struct Context { std::string functionName Context
Definition: cctlib.H:49
uint32_t lineNo
Definition: cctlib.H:53
VOID GetFullCallingContext(const ContextHandle_t curCtxtHndle, std::vector< Context > &contextVec)
Definition: cctlib.cpp:2339
bool HaveSameCallerPrefix(ContextHandle_t ctxt1, ContextHandle_t ctxt2)
Definition: cctlib.cpp:3241
ObjectTypeEnum
Definition: cctlib.H:25
@ UNKNOWN_OBJECT
Definition: cctlib.H:28
@ STACK_OBJECT
Definition: cctlib.H:25
@ DYNAMIC_OBJECT
Definition: cctlib.H:26
@ STATIC_OBJECT
Definition: cctlib.H:27
void SerializeMetadata(const std::string &directoryForSerializationFiles="")
Definition: cctlib.cpp:1878
bool IsSameSourceLine(ContextHandle_t ctxt1, ContextHandle_t ctxt2)
Definition: cctlib.cpp:3255
std::string disassembly
Definition: cctlib.H:51
int init_hpcrun_format(int argc, char *argv[], void(*mergeFunc)(void *des, void *src)=nullptr, uint64_t(*computeMetricVal)(void *metric)=nullptr, bool skip=false)
Definition: cctlib.cpp:4254
ContextHandle_t ctxtHandle2
Definition: cctlib.H:59
std::string filePath
Definition: cctlib.H:50
struct DataHandle_t { uint8_t objectType DataHandle_t
Definition: cctlib.H:32
ContextHandle_t GetContextHandle(const THREADID id, const uint32_t slot)
Definition: cctlib.cpp:1356
uint32_t ContextHandle_t
Definition: cctlib.H:22
int newCCT_hpcrun_selection_write(THREADID threadid)
Definition: cctlib.cpp:4369
BOOL InterestingInsAll(INS ins)
Definition: cctlib.H:76
void LogContexts(std::iostream &ios, ContextHandle_t ctxt1, ContextHandle_t ctxt2)
char * GetStringFromStringPool(const uint32_t index)
Definition: cctlib.cpp:802
ContextHandle_t GetTraceStartHandle(ContextHandle_t ctxtHandle)
Definition: cctlib.cpp:3249
void AppendLoadModulesToStream(std::iostream &ios)
uint32_t symName
Definition: cctlib.H:35
BOOL(*)(INS) IsInterestingInsFptr
Definition: cctlib.H:65
void * address