8 #define __STDC_FORMAT_MACROS
13 #include <unordered_map>
18 #include <sys/types.h>
21 #include <semaphore.h>
28 #include <sys/syscall.h>
41 #include <sys/resource.h>
49 const char* ws =
" \t\n\r\f\v";
50 size_t b = s.find_first_not_of(ws);
51 if (b == std::string::npos) {
55 size_t e = s.find_last_not_of(ws);
56 s = s.substr(b, e - b + 1);
60 #include <libelf/libelf.h>
61 #include <libelf/gelf.h>
62 #elif defined(TARGET_LINUX)
66 "Unsupported platform"
72 #include <google/sparse_hash_map>
73 #include <google/dense_hash_map>
76 #include "xed-interface.h"
79 using google::sparse_hash_map;
85 #define USE_SPLAY_TREE
86 #define MAX_PATH_NAME 1024
87 #define MALLOC_FN_NAME "malloc"
88 #define CALLOC_FN_NAME "calloc"
89 #define REALLOC_FN_NAME "realloc"
90 #define FREE_FN_NAME "free"
93 #define CCTLIB_SERIALIZATION_DEFAULT_DIR_NAME "cctlib-database-"
95 #if defined(TARGET_IA32E)
97 #define MAX_IPNODES (1L << 32)
98 #elif defined(TARGET_IA32)
100 #define MAX_IPNODES (1L << 20)
102 "SHOULD NEVER REACH HERE"
106 #ifndef MAX_STRING_POOL_NODES
107 #if defined(TARGET_IA32E)
109 #define MAX_STRING_POOL_NODES (1L << 30)
110 #elif defined(TARGET_IA32)
112 #define MAX_STRING_POOL_NODES (1L << 20)
114 "SHOULD NEVER REACH HERE"
119 #define CACHE_LINE_SIZE (128)
122 #define GET_CONTEXT_HANDLE_FROM_IP_NODE_CHECKED(node) ((ContextHandle_t)((node) ? ((node)-GLOBAL_STATE.preAllocatedContextBuffer) : 0))
123 #define GET_IPNODE_FROM_CONTEXT_HANDLE_CHECKED(handle) ((handle) ? (GLOBAL_STATE.preAllocatedContextBuffer + (handle)) : NULL)
125 #define GET_CONTEXT_HANDLE_FROM_IP_NODE(node) ((ContextHandle_t)((node)-GLOBAL_STATE.preAllocatedContextBuffer))
126 #define GET_IPNODE_FROM_CONTEXT_HANDLE(handle) (GLOBAL_STATE.preAllocatedContextBuffer + handle)
127 #define IS_VALID_CONTEXT(c) (c != 0)
130 #define BREAK_HERE raise(SIGINT)
133 #define SERIALIZED_SHADOW_TRACE_IP_FILE_SUFFIX "/TraceMap.traceShadowMap"
134 #define SERIALIZED_CCT_FILE_PREFIX "/Thread-"
135 #define SERIALIZED_CCT_FILE_EXTN ".cct"
136 #define SERIALIZED_CCT_FILE_SUFFIX "-CCTMap.cct"
140 #define MAP_ANONYMOUS MAP_ANON
141 typedef uintptr_t _Unwind_Ptr;
144 struct _Unwind_Context;
149 struct SerializedTraceNode;
156 #ifdef USE_TREE_BASED_FOR_DATA_CENTRIC
160 #define UNLOCKED_AND_PREDECESSOR_WAS_WRITER (2)
164 struct ConcurrentReaderWriterTree_t;
165 using varSet = set<varType>;
180 #ifdef USE_TREE_BASED_FOR_DATA_CENTRIC
181 enum AccessStatus { START_READING = 0,
212 #ifdef USE_SPLAY_TREE
215 sparse_hash_map<ADDRINT, TraceNode*>* calleeTraceNodes;
218 #ifdef HAVE_METRIC_PER_IPNODE
224 struct QNode*
volatile next;
237 #ifndef USE_SPLAY_TREE
238 sparse_hash_map<ADDRINT, TraceNode*>::iterator gTraceIter;
291 #ifdef USE_TREE_BASED_FOR_DATA_CENTRIC
293 uint32_t rwLockStatus;
295 struct ConcurrentReaderWriterTree_t* tlsLatestConcurrentTree;
297 volatile uint8_t tlsMallocDSAccessStatus;
312 #ifdef USE_TREE_BASED_FOR_DATA_CENTRIC
323 varType(
void* s,
void* e, uint32_t handle, uint8_t type)
324 : start(s), end(e),
pathHandle(handle), objectType(type) {}
327 bool operator<(varType
const&
a, varType
const& b) {
328 return (ADDRINT)
a.start < (ADDRINT)b.start;
331 struct PendingOps_t {
335 PendingOps_t(
const uint8_t o, varType
const& v)
336 : operation(o), var(v) {}
342 struct ConcurrentReaderWriterTree_t {
343 vector<PendingOps_t> pendingOps;
380 #define MAX_METRICS (10)
381 #define MAX_LEN (128)
398 char disassemblyBuff[200];
407 struct sigaction sigAct;
449 #ifdef USE_TREE_BASED_FOR_DATA_CENTRIC
451 unordered_map<UINT32, vector<PendingOps_t>> staticVariablesInModule;
453 volatile ConcurrentReaderWriterTree_t* latestConcurrentTree;
455 ConcurrentReaderWriterTree_t concurrentReaderWriterTree[2];
467 if (INS_IsProcedureCall(ins))
479 static uint32_t traceKey = 0;
480 uint32_t key = __sync_fetch_and_add(&traceKey, 1);
482 if (key == UINT_MAX) {
483 fprintf(stderr,
"\n UINT_MAX traces created! Exiting...\n");
503 fprintf(stderr,
"\n");
504 vector<Context> contextVec;
507 for (uint32_t i = 0; i < contextVec.size(); i++) {
508 fprintf(stderr,
"\n%u:%p:%s:%s:%s:%u", contextVec[i].
ctxtHandle, (
void*)contextVec[i].
ip, contextVec[i].
disassembly.c_str(), contextVec[i].functionName.c_str(), contextVec[i].filePath.c_str(), contextVec[i].lineNo);
521 static int SetJmpOverride(
const CONTEXT* ctxt, THREADID tid, AFUNPTR gOriginalSetjmpRtn, jmp_buf
env) {
523 PIN_CallApplicationFunction(ctxt,
528 PIN_PARG(
void*),
env,
533 fprintf(stderr,
"\n Here due to SetJmp\n");
536 fprintf(stderr,
"\n Here due to LongJmp\n");
583 xed_decoded_inst_t xedd;
587 if (XED_ERROR_NONE == xed_decode(&xedd, (
const xed_uint8_t*)(
ip), 15)) {
588 return xed_decoded_inst_get_length(&xedd);
590 assert(0 &&
"failed to disassemble instruction");
597 xed_decoded_inst_t xedd;
601 if (XED_ERROR_NONE == xed_decode(&xedd, (
const xed_uint8_t*)(
ip), 15)) {
602 return XED_CATEGORY_CALL == xed_decoded_inst_get_category(&xedd);
604 assert(0 &&
"failed to disassemble instruction");
648 for (uint32_t i = 0; i < trace->
nSlots; ++i) {
649 if (ips[i] >= lo && ips[i] < hi)
669 ADDRINT* outHandlerLo,
670 ADDRINT* outHandlerHi,
673 RTN targetRtn = RTN_FindByAddress(landingPadIp);
674 ADDRINT lo = 0, hi = 0;
675 if (RTN_Valid(targetRtn)) {
676 lo = RTN_Address(targetRtn);
677 hi = lo + RTN_Size(targetRtn);
716 ADDRINT lo = 0, hi = 0;
789 fprintf(
GLOBAL_STATE.
CCTLibLogFile,
"\nPreallocated IPNodes exhausted. CCTLib couldn't fit your application in its memory. Try a smaller program.\n");
807 uint32_t len = strlen(name) + 1;
811 fprintf(
GLOBAL_STATE.
CCTLibLogFile,
"\nPreallocated String Pool exhausted. CCTLib couldn't fit your application in its memory. Try by changing MAX_STRING_POOL_NODES macro.\n");
817 return oldStringPoolIndex;
827 #ifdef USE_SPLAY_TREE
832 #ifdef HAVE_METRIC_PER_IPNODE
833 ipNode->metric =
nullptr;
851 ADDRINT s = PIN_GetContextReg(ctxt, REG_STACK_PTR);
855 if (getrlimit(RLIMIT_STACK, &rlim)) {
856 cerr <<
"\n Failed to getrlimit()\n";
860 if (rlim.rlim_cur == RLIM_INFINITY) {
861 cerr <<
"\n Need a finite stack size. Dont use unlimited.\n";
868 #ifdef USE_TREE_BASED_FOR_DATA_CENTRIC
869 tdata->tlsMallocDSAccessStatus = END_READING;
900 ADDRINT rtnStart = RTN_Address(rtn);
913 const RtnInfo* p = &it->second;
924 std::vector<ADDRINT> rets;
925 for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) {
926 if (INS_IsProcedureCall(ins) &&
927 INS_IsDirectControlFlow(ins) &&
928 INS_DirectControlFlowTargetAddress(ins) == rtnStart) {
929 rets.push_back(INS_NextAddress(ins));
940 info.
nReturnAddrs = (uint16_t)(rets.size() > UINT16_MAX ? UINT16_MAX : rets.size());
960 const RtnInfo* p = &ins.first->second;
972 printf(
"\n Calling from IP = %p", tracesIPs[slot]);
992 printf(
"\n Returning to the caller IP = %p", tracesIPs[offset]);
1008 const ADDRINT* returnAddrs, uint32_t n,
1009 THREADID threadId) {
1010 for (uint32_t i = 0; i < n; ++i) {
1011 if (returnAddrs[i] == retTarget)
1046 for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) {
1047 for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) {
1060 UINT32
id = IMG_Id(img);
1062 if (IMG_IsMainExecutable(img))
1077 if (numInterestingInstInTrace == 0)
1080 ADDRINT* ipShadow = (ADDRINT*)malloc((2 + numInterestingInstInTrace) *
sizeof(ADDRINT));
1082 ipShadow[0] = numInterestingInstInTrace;
1084 ipShadow[1] = IMG_Id(IMG_FindByAddress(TRACE_Address(trace)));
1088 for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) {
1089 for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) {
1092 if (INS_IsProcedureCall(ins)) {
1099 bool isDirectSelfRec = rinfo && rinfo->
hasSelfRec && INS_IsDirectControlFlow(ins) && INS_DirectControlFlowTargetAddress(ins) == rinfo->
rtnStart;
1100 if (!isDirectSelfRec) {
1102 INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)
SetCallInitFlag, IARG_UINT32, slot, IARG_THREAD_ID, IARG_END);
1107 if (isInterestingIns(ins))
1112 INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)
RememberSlotNoInTLS, IARG_UINT32, slot, IARG_THREAD_ID, IARG_END);
1116 ipShadow[slot + 2] = INS_Address(ins);
1118 }
else if (INS_IsRet(ins)) {
1129 IARG_CALL_ORDER, CALL_ORDER_LAST,
1130 IARG_BRANCH_TARGET_ADDR,
1133 IARG_THREAD_ID, IARG_END);
1135 INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)
GoUpCallChain, IARG_CALL_ORDER, CALL_ORDER_LAST, IARG_THREAD_ID, IARG_END);
1140 if (isInterestingIns(ins))
1145 INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)
RememberSlotNoInTLS, IARG_UINT32, slot, IARG_THREAD_ID, IARG_END);
1149 ipShadow[slot + 2] = INS_Address(ins);
1151 }
else if (isInterestingIns(ins)) {
1158 INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)
RememberSlotNoInTLS, IARG_UINT32, slot, IARG_THREAD_ID, IARG_END);
1162 ipShadow[slot + 2] = INS_Address(ins);
1182 static inline void InstrumentTraceEntry(uint32_t traceKey, uint32_t numInterestingInstInTrace, ADDRINT traceFirstIp, THREADID threadId) {
1231 #ifdef USE_SPLAY_TREE
1235 if (found && (traceKey == found->
key)) {
1243 static uint64_t traceNodeCnt = 0;
1246 if((traceNodeCnt % 100000) == 0)
1247 printf(
"\n Trace traceNodeCnt=%lu", traceNodeCnt);
1253 if (numInterestingInstInTrace) {
1257 newChild->
nSlots = numInterestingInstInTrace;
1261 for (uint32_t i = 0; i < numInterestingInstInTrace; i++) {
1273 newNode->
key = traceKey;
1274 newNode->
value = newChild;
1278 newNode->
left =
nullptr;
1279 newNode->
right =
nullptr;
1280 }
else if (traceKey < found->
key) {
1282 newNode->
right = found;
1283 found->
left =
nullptr;
1285 newNode->
left = found;
1287 found->
right =
nullptr;
1294 assert 0 &&
"not maintained");
1301 BBL bbl = TRACE_BblHead(trace);
1302 INS ins = BBL_InsHead(bbl);
1308 RTN rtn = TRACE_Rtn(trace);
1310 INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)
InstrumentTraceEntry, IARG_UINT32, traceKey, IARG_UINT32, numInterestingInstInTrace, IARG_ADDRINT, TRACE_Address(trace), IARG_THREAD_ID, IARG_END);
1315 static void OnSig(THREADID threadId, CONTEXT_CHANGE_REASON reason,
const CONTEXT* ctxtFrom,
1316 CONTEXT* ctxtTo, INT32 sig, VOID* v) {
1320 case CONTEXT_CHANGE_REASON_FATALSIGNAL:
1321 cerr <<
"\n FATAL SIGNAL";
1323 case CONTEXT_CHANGE_REASON_SIGNAL:
1329 case CONTEXT_CHANGE_REASON_SIGRETURN: {
1337 assert(0 &&
"\n BAD CONTEXT SWITCH");
1345 assert(slot < tData->tlsCurrentTraceNode->nSlots);
1352 assert(slot < tData->tlsCurrentTraceNode->nSlots);
1358 assert(slot < tData->tlsCurrentTraceNode->nSlots);
1362 #ifdef HAVE_METRIC_PER_IPNODE
1363 void** GetIPNodeMetric(
const THREADID
id,
const uint32_t slot) {
1365 assert(slot < tData->tlsCurrentTraceNode->nSlots);
1406 if(traceNode->nSlots == 0)
1409 IPNode* parentIPNode = traceNode->callerCtxtHndl ? traceNode->callerCtxtHndl : 0;
1411 ADDRINT moduleId = traceIPs[-1];
1415 for(uint32_t i = 0 ; i < traceNode->nSlots; i++) {
1416 fprintf(fp,
"\n%p:%p:%p:%lu", &traceNode->childCtxtStartIdx[i], (
void*)(traceIPs[i] - loadOffset), parentIPNode, moduleId);
1420 for(uint32_t i = 0 ; i < traceNode->nSlots; i++) {
1429 std::stringstream cctMapFilePath;
1431 FILE* fp = fopen(cctMapFilePath.str().c_str(),
"w");
1432 fprintf(fp,
"NodeId:IP:ParentId:ModuleId");
1465 for (uint32_t i = 0; i < traceNode->
nSlots; i++) {
1466 if ((ipNode[i]).calleeTraceNodes ==
nullptr) {
1477 uint32_t noMoreTrace;
1479 if (fread(&noMoreTrace,
sizeof(noMoreTrace), 1, fp) != 1) {
1480 fprintf(stderr,
"\n Failed to read at line %d\n", __LINE__);
1489 fseek(fp, -
sizeof(noMoreTrace), SEEK_CUR);
1493 fprintf(stderr,
"\n Failed to read at line %d\n", __LINE__);
1505 for (uint32_t i = 0; i < traceNode->
nSlots; i++) {
1511 if (childTrace ==
nullptr)
1517 newNode->
value = childTrace;
1523 newNode->
left =
nullptr;
1524 newNode->
right =
nullptr;
1536 newNode->
right = found;
1537 found->
left =
nullptr;
1539 newNode->
left = found;
1541 found->
right =
nullptr;
1554 std::stringstream cctMapFilePath;
1556 FILE* fp = fopen(cctMapFilePath.str().c_str(),
"wb");
1558 if (fp ==
nullptr) {
1559 fprintf(stderr,
"\n Failed to open %s in line %d. Exiting\n", cctMapFilePath.str().c_str(), __LINE__);
1565 fwrite(&threadId,
sizeof(tData->
tlsThreadId), 1, fp);
1576 struct stat statbuf;
1577 if (stat(path, &statbuf) != 0)
1579 return S_ISDIR(statbuf.st_mode);
1583 if (ext.size() > base.size())
1585 return std::equal(base.begin() + base.size() - ext.size(), base.end(), ext.begin());
1591 char resolvedPath[PATH_MAX];
1592 realpath(root.c_str(), resolvedPath);
1593 DIR* dirp = opendir(resolvedPath);
1594 if (
nullptr == dirp) {
1603 throw string(
"Directory does not exits" + root);
1606 while ((dp = readdir(dirp)) !=
nullptr) {
1607 char concatedPath[PATH_MAX];
1612 int written = snprintf(concatedPath,
sizeof(concatedPath),
1613 "%s/%s", resolvedPath, dp->d_name);
1614 if (written < 0 || (
size_t)written >=
sizeof(concatedPath))
1620 ret.push_back(
string(concatedPath));
1627 vector<string> serializedCCTFiles;
1629 for (uint32_t
id = 0;
id < serializedCCTFiles.size();
id++) {
1630 std::stringstream cctMapFilePath;
1631 cctMapFilePath << serializedCCTFiles[id];
1633 FILE* fp = fopen(cctMapFilePath.str().c_str(),
"rb");
1635 if (fp ==
nullptr) {
1637 fprintf(stderr,
"\n Failed to open %s in line %d. Exiting\n", cctMapFilePath.str().c_str(), __LINE__);
1644 if (fread(&threadId,
sizeof(threadId), 1, fp) != 1) {
1645 fprintf(stderr,
"\n Failed to read at line %d\n", __LINE__);
1653 fprintf(stderr,
"\n Failed to read at line %d\n", __LINE__);
1661 assert(fread(&dummy,
sizeof(uint8_t), 1, fp) == 0);
1677 static void DottifyCCTNode(TraceNode* traceNode, uint64_t parentDotId, FILE*
const fp);
1682 static void DottifyAllNodesOfSplayTree(
TraceSplay* node, uint64_t curDotId, FILE*
const fp) {
1687 DottifyAllNodesOfSplayTree(node->
left, curDotId, fp);
1691 DottifyAllNodesOfSplayTree(node->
right, curDotId, fp);
1697 if (node ==
nullptr)
1702 childTraces.push_back(node->
value);
1710 if (traceNode->
nSlots == 0) {
1714 uint64_t myDotId = ++
gDotId;
1715 fprintf(fp,
"\"%" PRIx64
"\" -> \"%" PRIx64
"\";\n", parentDotId, myDotId);
1716 vector<TraceNode*> childTraces;
1719 for (uint32_t i = 0; i < traceNode->
nSlots; i++) {
1725 for (vector<TraceNode*>::iterator it = childTraces.begin(); it != childTraces.end(); it++) {
1732 std::stringstream cctMapFilePath;
1734 FILE* fp = fopen(cctMapFilePath.str().c_str(),
"w");
1736 if (fp ==
nullptr) {
1737 fprintf(stderr,
"\n Failed to open %s in line %d. Exiting\n", cctMapFilePath.str().c_str(), __LINE__);
1741 fprintf(fp,
"digraph CCTLibGraph {\n");
1753 #define SERIALIZED_MODULE_MAP_SUFFIX "/ModuleMap.txt"
1757 FILE* fp = fopen(moduleFilePath.c_str(),
"w");
1759 if (fp ==
nullptr) {
1761 fprintf(stderr,
"\n Failed to open %s in line %d. Exiting\n", moduleFilePath.c_str(), __LINE__);
1765 unordered_map<UINT32, ModuleInfo>::iterator it;
1766 fprintf(fp,
"ModuleId\tModuleFile\tLoadOffset");
1769 fprintf(fp,
"\n%u\t%s\t%p", it->first, (it->second).moduleName.c_str(), (
void*)((it->second).imgLoadOffset));
1777 FILE* fp = fopen(moduleFilePath.c_str(),
"r");
1779 if (fp ==
nullptr) {
1781 fprintf(stderr,
"\n Failed to open %s in line %d. Exiting\n", moduleFilePath.c_str(), __LINE__);
1790 fscanf(fp,
"%s%s%s", path, path, path);
1792 while (EOF != fscanf(fp,
"%u%s%p", &moduleId, path, (
void**)&offset)) {
1805 FILE* fp = fopen(traceMapFilePath.c_str(),
"wb");
1807 if (fp ==
nullptr) {
1808 fprintf(stderr,
"\n Failed to open %s in line %d. Exiting\n", traceMapFilePath.c_str(), __LINE__);
1812 unordered_map<uint32_t, void*>::iterator it;
1817 fwrite(&(it->first),
sizeof(it->first), 1, fp);
1818 ADDRINT* ptr = (ADDRINT*)(it->second);
1819 uint32_t moduleId = (uint32_t)ptr[-1];
1821 ADDRINT nSlots = ptr[-2];
1826 for (ADDRINT i = 0; i < nSlots; i++) {
1827 ptr[i] = ptr[i] - offset;
1831 fwrite(ptr - 2,
sizeof(ADDRINT), ptr[-2] + 2, fp);
1840 FILE* fp = fopen(traceMapFilePath.c_str(),
"rb");
1842 if (fp ==
nullptr) {
1843 fprintf(stderr,
"\n Failed to open %s in line %d. Exiting\n", traceMapFilePath.c_str(), __LINE__);
1847 unordered_map<uint32_t, void*>::iterator it;
1851 while (fread(&traceKey,
sizeof(traceKey), 1, fp) == 1) {
1855 if (fread(&numSlots,
sizeof(ADDRINT), 1, fp) != 1) {
1856 fprintf(stderr,
"\n Failed to read in line %d. Exiting\n", __LINE__);
1861 ADDRINT*
array = (ADDRINT*)malloc((numSlots + 2) *
sizeof(ADDRINT));
1862 array[0] = numSlots;
1865 if (fread(&
array[1],
sizeof(ADDRINT), numSlots + 1, fp) != (numSlots + 1)) {
1866 fprintf(stderr,
"\n Failed to read in line %d. Exiting\n", __LINE__);
1879 if (!directoryForSerializationFiles.empty()) {
1883 std::stringstream ss;
1886 pid_t pid = getpid();
1897 if (stat(dir.c_str(), &st) != 0) {
1899 while (pos != string::npos) {
1900 pos = dir.find(
'/', pos + 1);
1901 string sub = (pos == string::npos) ? dir : dir.substr(0, pos);
1904 if (mkdir(sub.c_str(), 0755) != 0 && errno != EEXIST) {
1905 fprintf(stderr,
"\n failed to create directory %s: %s", sub.c_str(), strerror(errno));
1930 struct rusage rusage;
1931 getrusage(RUSAGE_SELF, &rusage);
1932 return (
size_t)(rusage.ru_maxrss);
1957 assert(ctxtHndle < traceNode->childCtxtStartIdx + traceNode->
nSlots);
1969 assert(ctxtHndle < traceNode->childCtxtStartIdx + traceNode->
nSlots);
1981 UINT32 moduleId = ptr[-1];
1993 xed_decoded_inst_t xedd;
1997 if (XED_ERROR_NONE == xed_decode(&xedd, (
const xed_uint8_t*)(
ip), 15)) {
2007 for (IMG img = APP_ImgHead(); IMG_Valid(img); img = IMG_Next(img)) {
2008 if (
ip >= IMG_LowAddress(img) &&
ip <= IMG_HighAddress(img)) {
2020 for(IMG img = APP_ImgHead(); IMG_Valid(img); img = IMG_Next(img)) {
2021 if((ADDRINT)di.
firstIP >= IMG_LowAddress(img) && (ADDRINT)di.
firstIP <= IMG_HighAddress(img)) {
2030 for(IMG img = APP_ImgHead(); IMG_Valid(img); img = IMG_Next(img)) {
2031 if((ADDRINT)di.
secondIP >= IMG_LowAddress(img) && (ADDRINT)di.
secondIP <= IMG_HighAddress(img)) {
2043 return (*((
unsigned char*)
ip) == 0xff) && (*((
unsigned char*)
ip + 1) == 0x25);
2047 #define NOT_ROOT_CTX (-1)
2077 #ifdef MULTI_THREADED
2082 struct sigaction old;
2094 if(parentThreadIPNode)
2102 if(PIN_UndecorateSymbolName(RTN_FindNameByAddress(
ip), UNDECORATION_COMPLETE) ==
".plt") {
2105 uint64_t nextByte = (uint64_t)
ip + 2;
2106 int* offset = (
int*) nextByte;
2107 uint64_t nextInst = (uint64_t)
ip + 6;
2108 ADDRINT loc = *((uint64_t*)(nextInst + *offset));
2144 curIPNode = curIPNode->parentTraceNode->callerCtxtHndl;
2149 sigaction(SIGSEGV, &old, 0);
2158 parentIPs.push_back(
ip);
2166 #ifdef MULTI_THREADED
2170 struct sigaction old;
2180 Context ctxt = {
"THREAD[" + std::to_string(threadCtx) +
"]_ROOT_CTXT" ,
"" ,
"" , curCtxtHndle , 0 , 0 };
2181 contextVec.push_back(ctxt);
2183 if (parentThreadCtxtHndl)
2191 if (PIN_UndecorateSymbolName(RTN_FindNameByAddress(
ip), UNDECORATION_COMPLETE) ==
".plt") {
2194 uint64_t nextByte = (uint64_t)
ip + 2;
2195 int* offset = (
int*)nextByte;
2196 uint64_t nextInst = (uint64_t)
ip + 6;
2197 ADDRINT loc = *((uint64_t*)(nextInst + *offset));
2205 contextVec.push_back(ctxt);
2209 contextVec.push_back(ctxt);
2214 contextVec.push_back(ctxt);
2220 Context ctxt = {
"CRASHED !!" ,
"" ,
"" , curCtxtHndle , 0 ,
ip };
2221 contextVec.push_back(ctxt);
2234 contextVec.push_back(ctxt);
2238 Context ctxt = {
"BAD IP !!" ,
"" ,
"" , curCtxtHndle , 0 ,
ip };
2239 contextVec.push_back(ctxt);
2245 Context ctxt = {
"Truncated call path (due to deep call chain)" ,
"" ,
"" , curCtxtHndle , 0 , 0 };
2246 contextVec.push_back(ctxt);
2252 sigaction(SIGSEGV, &old,
nullptr);
2258 #ifdef MULTI_THREADED
2262 struct sigaction old;
2270 Context ctxt = {
"THREAD[" + std::to_string(threadCtx) +
"]_ROOT_CTXT" ,
"" ,
"" , curCtxtHndle , 0 , 0 };
2271 contextVec.push_back(ctxt);
2275 if (parentThreadCtxtHndl)
2282 std::stringstream command;
2283 command <<
"addr2line -C -f -e " << modulePath <<
" " << std::hex <<
ip;
2284 FILE* fp = popen(command.str().c_str(),
"r");
2291 strcpy(functionName,
"FAILED_TO_READ");
2292 strcpy(fileName,
"FAILED_TO_READ");
2296 strcpy(fileName,
"FAILED_TO_READ");
2300 int len = strlen(fileName);
2303 for (linePos = len - 1; linePos >= 0; linePos--) {
2304 if (fileName[linePos] ==
':')
2308 lineNo = atoi(&fileName[linePos + 1]);
2309 fileName[linePos] =
'\0';
2313 strcpy(functionName,
"CRASHED!");
2314 strcpy(fileName,
"CRASHED!");
2319 string fnName(functionName);
2321 string flName(fileName);
2324 fnName , flName ,
"TODO-Disassmebly" , curCtxtHndle
2329 contextVec.push_back(ctxt);
2335 sigaction(SIGSEGV, &old,
nullptr);
2347 vector<Context> contextVec;
2354 for (uint32_t i = 0; i < contextVec.size(); i++) {
2355 fprintf(
GLOBAL_STATE.
CCTLibLogFile,
"\n%u:%p:%s:%s:%s:%u", contextVec[i].ctxtHandle, (
void*)contextVec[i].ip, contextVec[i].disassembly.c_str(), contextVec[i].functionName.c_str(), contextVec[i].filePath.c_str(), contextVec[i].lineNo);
2360 unordered_map<UINT32, ModuleInfo>::iterator it;
2363 << it->first <<
":" << (
void*)((it->second).imgLoadOffset) <<
":" << (it->second).moduleName;
2379 if (parentThreadCtxtHndl) {
2380 fprintf(stderr,
"\n Multi threading not supported for this prototype feature. Exiting\n");
2390 UINT32 moduleId = ptr[-1];
2391 ADDRINT
ip = ptr[slotNo];
2394 nip.
lm_id = moduleId;
2396 ctxt.push_back(nip);
2399 RTN r = RTN_FindByAddress(
ip);
2400 if (RTN_Invalid() != r && RTN_Name(r) ==
"main")
2408 vector<NormalizedIP> c1;
2409 vector<NormalizedIP> c2;
2412 for (uint32_t i = 0; i < c1.size(); i++)
2413 ios << c1[i].lm_id <<
"-" << (
void*)c1[i].offset <<
",";
2415 for (uint32_t i = 0; i < c2.size(); i++)
2416 ios <<
"," << c2[i].lm_id <<
"-" << (
void*)c2[i].offset;
2435 static void InitLocks() {
2446 char* envPath = getenv(
"OUTPUT_FILE");
2453 std::stringstream ss;
2456 pid_t pid = getpid();
2457 ss << hostname <<
"-" << pid;
2471 xed_state_init(&
GLOBAL_STATE.
cct_xed_state, XED_MACHINE_MODE_LONG_64, (xed_address_width_enum_t)0, XED_ADDRESS_WIDTH_64b);
2478 #ifdef USE_SHADOW_FOR_DATA_CENTRIC
2482 uint64_t endAddr = (uint64_t)addr + accessLen;
2483 uint32_t numInited = 0;
2485 for (uint64_t curAddr = (uint64_t)addr; curAddr < endAddr; curAddr +=
SHADOW_PAGE_SIZE) {
2489 for (
int i = 0; (i < maxBytesInThisPage) && numInited < accessLen; numInited++, i++) {
2490 status[i] = *initializer;
2500 if (addr > tData->
tlsStackEnd && addr < tData->tlsStackBase) {
2505 dataHandle = *(GetOrCreateShadowAddress<0>(
sm, (
size_t)addr));
2509 #elif defined(USE_TREE_BASED_FOR_DATA_CENTRIC)
2515 if (addr > tData->tlsStackEnd && addr < tData->tlsStackBase) {
2522 tData->tlsLatestConcurrentTree = (ConcurrentReaderWriterTree_t*)
GLOBAL_STATE.latestConcurrentTree;
2523 varSet* curTree = &(tData->tlsLatestConcurrentTree->tree);
2524 tData->tlsMallocDSAccessStatus = START_READING;
2529 varSet::iterator node = curTree->lower_bound(varType(addr, addr, 0 ,
UNKNOWN_OBJECT));
2531 if (node != curTree->begin() && node->start != addr)
2534 if (node != curTree->end() && (addr < node->start || addr >= node->end))
2535 node = curTree->end();
2537 if (node != curTree->end()) {
2538 record.objectType = node->objectType;
2539 record.pathHandle = node->pathHandle;
2542 #ifdef USE_TREE_WITH_ADDR
2543 record.beg_addr = (uint64_t)node->start;
2544 record.end_addr = (uint64_t)node->end;
2550 tData->tlsMallocDSAccessStatus = END_READING;
2557 assert(0 &&
"should never reach here");
2577 static void CaptureFree(
void* ptr, THREADID threadId);
2584 #ifdef USE_TREE_BASED_FOR_DATA_CENTRIC
2591 #ifdef USE_TREE_BASED_FOR_DATA_CENTRIC
2594 static void DUMP_STATUS(THREADID threadId,
int stuckon,
int calledFrom) {
2595 printf(
"\n STUCK! threadId = %d, stack waiting for %d, called from %s", threadId, stuckon, calledFrom == 0 ?
"malloc" :
"free");
2599 printf(
"\n Thread %d, tlsLatestMallocVarSet = %p, tlsMallocDSAccessStatus = %d", i, tData->tlsLatestMallocVarSet , tData->tlsMallocDSAccessStatus);
2605 static void WaitTillAllThreadsProgressIntoNewSet(varSet* latestVarSet, THREADID threadId,
int calledFrom) {
2611 while((tData->tlsLatestMallocVarSet != latestVarSet) && (tData->tlsMallocDSAccessStatus == START_READING)) {
2613 if(j++ == 0xffffff) {
2614 DUMP_STATUS(threadId, i, calledFrom);
2621 QNode*
volatile MCSLock =
nullptr;
2623 static void MCSAcquire(
QNode*
volatile* L,
QNode* I) {
2626 QNode* pred = (
QNode*)__sync_lock_test_and_set((uint64_t*)L, (uint64_t)I);
2631 while (I->status == LOCKED)
2636 static void MCSRelease(
QNode*
volatile* L,
QNode* I, uint8_t releaseVal) {
2637 if (I->next ==
nullptr) {
2638 if (__sync_bool_compare_and_swap((uint64_t*)L, (uint64_t)I, (uint64_t)NULL))
2641 while (I->next ==
nullptr)
2647 I->next->status = releaseVal;
2651 static void WaitTillAllThreadsProgressIntoNewSet(ConcurrentReaderWriterTree_t* latestTree) {
2656 while ((tData->tlsLatestConcurrentTree != latestTree) && (tData->tlsMallocDSAccessStatus == START_READING)) {
2662 static void ApplyPendingOperationsToTree(ConcurrentReaderWriterTree_t* threadFreeTree) {
2663 for (uint32_t i = 0; i < threadFreeTree->pendingOps.size(); i++) {
2664 switch (threadFreeTree->pendingOps[i].operation) {
2667 threadFreeTree->tree.insert(threadFreeTree->pendingOps[i].var);
2673 varSet::const_iterator iterThreadFreeTree = threadFreeTree->tree.lower_bound(threadFreeTree->pendingOps[i].var);
2678 if (threadFreeTree->pendingOps[i].var.start == iterThreadFreeTree->start) {
2679 threadFreeTree->tree.erase(*iterThreadFreeTree);
2681 fprintf(stderr,
"\n Can't delete %1d %p\n", threadFreeTree->pendingOps[i].var.objectType, threadFreeTree->pendingOps[i].var.start);
2688 assert(0 &&
"Should not reach here");
2694 threadFreeTree->pendingOps.clear();
2699 static void UpdateLockLessTree(THREADID threadId,
const vector<PendingOps_t>& ops) {
2700 static ThreadData dummyThreadData;
2704 tData = &dummyThreadData;
2710 tData->tlsMallocDSAccessStatus = WAITING_WRITE;
2712 MCSAcquire(&MCSLock, &mcsNode);
2714 tData->tlsMallocDSAccessStatus = WRITE_STARTED;
2715 ConcurrentReaderWriterTree_t* curTree = (ConcurrentReaderWriterTree_t*)
GLOBAL_STATE.latestConcurrentTree;
2716 ConcurrentReaderWriterTree_t* newTree = (curTree == (&
GLOBAL_STATE.concurrentReaderWriterTree[0])) ? (&
GLOBAL_STATE.concurrentReaderWriterTree[1]) : (&
GLOBAL_STATE.concurrentReaderWriterTree[0]);
2718 curTree->pendingOps.insert(curTree->pendingOps.end(), ops.begin(), ops.end());
2719 newTree->pendingOps.insert(newTree->pendingOps.end(), ops.begin(), ops.end());
2723 if(mcsNode.status != UNLOCKED_AND_PREDECESSOR_WAS_WRITER ) {
2725 WaitTillAllThreadsProgressIntoNewSet(curTree);
2730 WaitTillAllThreadsProgressIntoNewSet(curTree);
2734 ApplyPendingOperationsToTree(newTree);
2738 if(mcsNode.next == NULL ) {
2742 tData->tlsLatestConcurrentTree = newTree;
2743 MCSRelease(&MCSLock, &mcsNode, UNLOCKED);
2745 MCSRelease(&MCSLock, &mcsNode, UNLOCKED_AND_PREDECESSOR_WAS_WRITER);
2752 tData->tlsLatestConcurrentTree = newTree;
2753 MCSRelease(&MCSLock, &mcsNode, UNLOCKED);
2763 #ifdef USE_SHADOW_FOR_DATA_CENTRIC
2768 #elif defined(USE_TREE_BASED_FOR_DATA_CENTRIC)
2770 vector<PendingOps_t> ops(1, PendingOps_t(INSERT, v));
2771 UpdateLockLessTree(threadId, ops);
2773 assert(0 &&
"Should not reach here");
2778 #ifdef USE_SHADOW_FOR_DATA_CENTRIC
2780 #elif defined(USE_TREE_BASED_FOR_DATA_CENTRIC)
2784 vector<PendingOps_t> ops(1, PendingOps_t(DELETE, v));
2785 UpdateLockLessTree(threadId, ops);
2789 assert(0 &&
"Should not reach here");
2799 #ifdef USE_TREE_BASED_FOR_DATA_CENTRIC
2800 vector<PendingOps_t> ops;
2801 UINT32 imgId = IMG_Id(img);
2805 Elf_Scn* scn = NULL;
2806 Elf_Data* edata = NULL;
2810 struct stat elf_stats;
2811 int i, symbol_count;
2814 if ((fstat(fd, &elf_stats))) {
2815 printf(
"bss: could not fstat, so not monitor static variables\n");
2820 if ((base_ptr = (
char*)malloc(elf_stats.st_size)) ==
nullptr) {
2821 printf(
"could not malloc\n");
2826 if ((read(fd, base_ptr, elf_stats.st_size)) < elf_stats.st_size) {
2827 printf(
"could not read\n");
2833 if (elf_version(EV_CURRENT) == EV_NONE) {
2834 printf(
"WARNING Elf Library is out of date!\n");
2838 elf = elf_begin(fd, ELF_C_READ, NULL);
2841 while ((scn = elf_nextscn(elf, scn)) != NULL) {
2842 gelf_getshdr(scn, &shdr);
2844 if (shdr.sh_type == SHT_SYMTAB) {
2845 edata = elf_getdata(scn, edata);
2846 symbol_count = shdr.sh_size / shdr.sh_entsize;
2848 for (i = 0; i < symbol_count; i++) {
2849 if (gelf_getsym(edata, i, &sym) == NULL) {
2850 printf(
"gelf_getsym return NULL\n");
2851 printf(
"%s\n", elf_errmsg(elf_errno()));
2855 if ((sym.st_size == 0) || (ELF32_ST_TYPE(sym.st_info) != STT_OBJECT)) {
2859 #ifdef USE_SHADOW_FOR_DATA_CENTRIC
2862 char* symname = elf_strptr(elf, shdr.sh_link, sym.st_name);
2865 #elif defined(USE_TREE_BASED_FOR_DATA_CENTRIC)
2866 char* symname = elf_strptr(elf, shdr.sh_link, sym.st_name);
2868 varType vInsert((
void*)((IMG_LoadOffset(img)) + sym.st_value), (
void*)((IMG_LoadOffset(img)) + sym.st_value + sym.st_size), handle,
STATIC_OBJECT);
2869 varType vDelete((
void*)((IMG_LoadOffset(img)) + sym.st_value), (
void*)((IMG_LoadOffset(img)) + sym.st_value), handle,
STATIC_OBJECT);
2870 ops.push_back(PendingOps_t(INSERT, vInsert));
2872 GLOBAL_STATE.staticVariablesInModule[imgId].push_back(PendingOps_t(INSERT, vDelete));
2874 assert(0 &&
"Should not reach here");
2880 #ifdef USE_TREE_BASED_FOR_DATA_CENTRIC
2881 UpdateLockLessTree(PIN_ThreadId(), ops);
2887 #ifdef USE_SHADOW_FOR_DATA_CENTRIC
2890 UpdateLockLessTree(PIN_ThreadId(),
GLOBAL_STATE.staticVariablesInModule[IMG_Id(img)]);
2896 char* result = realpath(IMG_Name(img).c_str(),
filename);
2898 if (result ==
nullptr) {
2899 fprintf(stderr,
"\n failed to resolve path");
2909 #define PTHREAD_CREATE_RTN "pthread_create"
2910 #define ARCH_LONGJMP_RTN "__longjmp"
2911 #define SETJMP_RTN "_setjmp"
2913 #define LONGJMP_RTN ARCH_LONGJMP_RTN
2914 #define SIGSETJMP_RTN "sigsetjmp"
2916 #define SIGLONGJMP_RTN ARCH_LONGJMP_RTN
2917 #define UNWIND_SETIP "_Unwind_SetIP"
2918 #define UNWIND_RAISEEXCEPTION "_Unwind_RaiseException"
2919 #define UNWIND_RESUME "_Unwind_Resume"
2920 #define UNWIND_FORCEUNWIND "_Unwind_ForcedUnwind"
2921 #define UNWIND_RESUME_OR_RETHROW "_Unwind_Resume_or_Rethrow"
2923 RTN setjmpRtn = RTN_FindByName(img,
SETJMP_RTN);
2924 RTN longjmpRtn = RTN_FindByName(img,
LONGJMP_RTN);
2928 RTN unwindSetIpRtn = RTN_FindByName(img,
UNWIND_SETIP);
2936 cout <<
"\n Image name" << IMG_Name(img);
2939 if (RTN_Valid(pthread_createRtn)) {
2941 RTN_Open(pthread_createRtn);
2943 RTN_InsertCall(pthread_createRtn, IPOINT_AFTER, (AFUNPTR)
ThreadCreatePoint, IARG_THREAD_ID, IARG_END);
2944 RTN_Close(pthread_createRtn);
2949 if(RTN_Valid(setjmpRtn)) {
2951 RTN_ReplaceSignature(setjmpRtn, AFUNPTR(SetJmpOverride), IARG_CONST_CONTEXT, IARG_THREAD_ID, IARG_ORIG_FUNCPTR, IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_END);
2957 if (strstr(IMG_Name(img).c_str(),
"libc.so")) {
2958 if (RTN_Valid(setjmpRtn)) {
2960 RTN_Open(setjmpRtn);
2961 RTN_InsertCall(setjmpRtn, IPOINT_BEFORE, (AFUNPTR)
CaptureSigSetJmpCtxt, IARG_CALL_ORDER, CALL_ORDER_LAST, IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_THREAD_ID, IARG_END);
2962 RTN_Close(setjmpRtn);
2965 if (RTN_Valid(longjmpRtn)) {
2967 RTN_Open(longjmpRtn);
2968 RTN_InsertCall(longjmpRtn, IPOINT_BEFORE, (AFUNPTR)
HoldLongJmpBuf, IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_THREAD_ID, IARG_END);
2969 RTN_Close(longjmpRtn);
2972 if (RTN_Valid(sigsetjmpRtn)) {
2974 RTN_Open(sigsetjmpRtn);
2976 RTN_InsertCall(sigsetjmpRtn, IPOINT_BEFORE, (AFUNPTR)
CaptureSigSetJmpCtxt, IARG_CALL_ORDER, CALL_ORDER_LAST, IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_THREAD_ID, IARG_END);
2977 RTN_Close(sigsetjmpRtn);
2980 if (RTN_Valid(siglongjmpRtn)) {
2982 RTN_Open(siglongjmpRtn);
2983 RTN_InsertCall(siglongjmpRtn, IPOINT_BEFORE, (AFUNPTR)
HoldLongJmpBuf, IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_THREAD_ID, IARG_END);
2984 RTN_Close(siglongjmpRtn);
2987 if (RTN_Valid(archlongjmpRtn)) {
2989 RTN_Open(archlongjmpRtn);
2991 INS lastIns = RTN_InsTail(archlongjmpRtn);
2992 assert(INS_Valid(lastIns));
2993 assert(INS_IsBranch(lastIns));
2994 assert(!INS_IsDirectBranch(lastIns));
2995 INS_InsertCall(lastIns, IPOINT_TAKEN_BRANCH, (AFUNPTR)
RestoreSigLongJmpCtxt, IARG_THREAD_ID, IARG_END);
2997 RTN_Close(archlongjmpRtn);
3019 if (strstr(IMG_Name(img).c_str(),
"libgcc_s.so")) {
3020 if (RTN_Valid(unwindSetIpRtn)) {
3024 RTN_Open(unwindSetIpRtn);
3025 RTN_InsertCall(unwindSetIpRtn, IPOINT_BEFORE, (AFUNPTR)
CaptureLandingPadTarget, IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_FUNCARG_ENTRYPOINT_VALUE, 1, IARG_THREAD_ID, IARG_END);
3026 RTN_Close(unwindSetIpRtn);
3054 if (RTN_Valid(mallocRtn)) {
3055 RTN_Open(mallocRtn);
3057 RTN_InsertCall(mallocRtn, IPOINT_BEFORE, (AFUNPTR)
CaptureMallocSize, IARG_CALL_ORDER, CALL_ORDER_LAST, IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_THREAD_ID, IARG_END);
3059 RTN_InsertCall(mallocRtn, IPOINT_AFTER, (AFUNPTR)
CaptureMallocPointer, IARG_FUNCRET_EXITPOINT_VALUE, IARG_THREAD_ID, IARG_END);
3060 RTN_Close(mallocRtn);
3065 if (RTN_Valid(callocRtn)) {
3066 RTN_Open(callocRtn);
3068 RTN_InsertCall(callocRtn, IPOINT_BEFORE, (AFUNPTR)
CaptureCallocSize, IARG_CALL_ORDER, CALL_ORDER_LAST, IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_FUNCARG_ENTRYPOINT_VALUE, 1, IARG_THREAD_ID, IARG_END);
3070 RTN_InsertCall(callocRtn, IPOINT_AFTER, (AFUNPTR)
CaptureMallocPointer, IARG_FUNCRET_EXITPOINT_VALUE, IARG_THREAD_ID, IARG_END);
3071 RTN_Close(callocRtn);
3076 if (RTN_Valid(reallocRtn)) {
3077 RTN_Open(reallocRtn);
3079 RTN_InsertCall(reallocRtn, IPOINT_BEFORE, (AFUNPTR)
CaptureReallocSize, IARG_CALL_ORDER, CALL_ORDER_LAST, IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_FUNCARG_ENTRYPOINT_VALUE, 1, IARG_THREAD_ID, IARG_END);
3081 RTN_InsertCall(reallocRtn, IPOINT_AFTER, (AFUNPTR)
CaptureMallocPointer, IARG_FUNCRET_EXITPOINT_VALUE, IARG_THREAD_ID, IARG_END);
3082 RTN_Close(reallocRtn);
3087 if (RTN_Valid(freeRtn)) {
3089 RTN_InsertCall(freeRtn, IPOINT_BEFORE, (AFUNPTR)
CaptureFree, IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_THREAD_ID, IARG_END);
3096 RTN mainRtn = RTN_FindByName(img,
"main");
3097 if (!RTN_Valid(mainRtn)) {
3098 mainRtn = RTN_FindByName(img,
"MAIN");
3099 if (!RTN_Valid(mainRtn)) {
3100 mainRtn = RTN_FindByName(img,
"MAIN_");
3103 if (RTN_Valid(mainRtn)) {
3114 #ifdef USE_SHADOW_FOR_DATA_CENTRIC
3120 #ifdef USE_TREE_BASED_FOR_DATA_CENTRIC
3134 fprintf(stderr,
"\n CCTLib was initialized for postmortem analysis using PinCCTLibInitForPostmortemAnalysis! Exiting...\n");
3135 PIN_ExitApplication(-1);
3159 PIN_AddContextChangeFunction(
OnSig,
nullptr);
3165 if (doDataCentric) {
3176 PIN_AddFiniFunction(
Fini,
nullptr);
3185 fprintf(stderr,
"\n CCTLib was initialized for online collection using PinCCTLibInit! Exiting...\n");
3186 PIN_ExitApplication(-1);
3205 #ifdef HAVE_METRIC_PER_IPNODE
3206 static void BottomUpTraverse(TraceNode* node,
void (*opFunc)(
const THREADID threadid,
ContextHandle_t myHandle,
ContextHandle_t parentHandle,
void** myMetric,
void** parentMetric),
const THREADID threadid);
3208 static void BottomUpTraverseHelper(
TraceSplay* node,
void (*opFunc)(
const THREADID threadid,
ContextHandle_t myHandle,
ContextHandle_t parentHandle,
void** myMetric,
void** parentMetric),
const THREADID threadid) {
3212 BottomUpTraverseHelper(node->
left, opFunc, threadid);
3213 BottomUpTraverse(node->
value, opFunc, threadid);
3214 BottomUpTraverseHelper(node->
right, opFunc, threadid);
3216 static void BottomUpTraverse(TraceNode* node,
void (*opFunc)(
const THREADID threadid,
ContextHandle_t myHandle,
ContextHandle_t parentHandle,
void** myMetric,
void** parentMetric),
const THREADID threadid) {
3220 for (uint32_t i = 0; i < node->nSlots; i++) {
3226 assert(node->callerCtxtHndl);
3227 if (node->callerCtxtHndl) {
3235 void TraverseCCTBottomUp(
const THREADID threadid,
void (*opFunc)(
const THREADID threadid,
ContextHandle_t myHandle,
ContextHandle_t parentHandle,
void** myMetric,
void** parentMetric)) {
3237 BottomUpTraverse(tData->tlsRootTraceNode, opFunc, threadid);
3265 uint32_t lineNo1, lineNo2;
3266 string filePath1, filePath2;
3268 PIN_GetSourceLocation(ip1, NULL, (INT32*)&lineNo1, &filePath1);
3269 PIN_GetSourceLocation(ip2, NULL, (INT32*)&lineNo2, &filePath2);
3271 return static_cast<bool>(filePath1 == filePath2 && lineNo1 == lineNo2);
3280 #define HASH_PRIME 2001001003
3281 #define HASH_GEN 4001
3282 #define SPINLOCK_UNLOCKED_VALUE (0L)
3283 #define SPINLOCK_LOCKED_VALUE (1L)
3284 #define OSUtil_hostid_NULL (-1)
3285 #define INITIALIZE_SPINLOCK(x) \
3287 #define SPINLOCK_UNLOCKED INITIALIZE_SPINLOCK(SPINLOCK_UNLOCKED_VALUE)
3288 #define SPINLOCK_LOCKED INITIALIZE_SPINLOCK(SPINLOCK_LOCKED_VALUE)
3290 #define HPCRUN_FMT_NV_prog "program-name"
3291 #define HPCRUN_FMT_NV_progPath "program-path"
3292 #define HPCRUN_FMT_NV_envPath "env-path"
3293 #define HPCRUN_FMT_NV_jobId "job-id"
3294 #define HPCRUN_FMT_NV_mpiRank "mpi-id"
3295 #define HPCRUN_FMT_NV_tid "thread-id"
3296 #define HPCRUN_FMT_NV_hostid "host-id"
3297 #define HPCRUN_FMT_NV_pid "process-id"
3298 #define HPCRUN_SAMPLE_PROB "HPCRUN_PROCESS_FRACTION"
3299 #define HPCRUN_FMT_NV_traceMinTime "trace-min-time"
3300 #define HPCRUN_FMT_NV_traceMaxTime "trace-max-time"
3302 #define FILENAME_TEMPLATE "%s/%s-%06u-%03d-%08lx-%u-%d.%s"
3303 #define TEMPORARY "%s/%s-"
3306 #define FILES_RANDOM_GEN 4
3307 #define FILES_MAX_GEN 11
3308 #define FILES_EARLY 0x1
3309 #define FILES_LATE 0x2
3310 #define DEFAULT_PROB 0.1
3313 #if defined(LL_BODY) && defined(SC_BODY)
3315 #define read_modify_write(type, addr, expn, result) \
3319 result = (type)load_linked((unsigned long*)addr); \
3321 } while (!store_conditional((unsigned long*)addr, (unsigned long)__new)); \
3325 #define read_modify_write(type, addr, expn, result) \
3331 } while (compare_and_swap(addr, result, __new) != result); \
3335 #define compare_and_swap(addr, oldval, newval) \
3336 __sync_val_compare_and_swap(addr, oldval, newval)
3359 using size_t = uint16_t;
3363 MetricFlags_Ty_NULL = 0,
3365 MetricFlags_Ty_Final,
3366 MetricFlags_Ty_Derived
3371 MetricFlags_ValTy_NULL = 0,
3372 MetricFlags_ValTy_Incl,
3373 MetricFlags_ValTy_Excl
3378 MetricFlags_ValFmt_NULL = 0,
3379 MetricFlags_ValFmt_Int,
3380 MetricFlags_ValFmt_Real,
3385 bool isLogicalUnwind : 1;
3416 uint8_t
bits[2 * 8];
3438 volatile long thelock;
3454 MetricFlags_Ty_NULL,
3455 MetricFlags_ValTy_NULL,
3456 MetricFlags_ValFmt_NULL,
3473 MetricFlags_Ty_NULL,
3474 MetricFlags_ValTy_NULL,
3475 MetricFlags_ValFmt_NULL,
3485 .bits = 0x0000000000000000};
3519 extern int fputs(
const char* __restrict __s, FILE* __restrict __stream);
3522 uint64_t measurementGranularity, uint32_t raToCallsiteOfst);
3550 pid_t pid = getpid();
3556 char* jid =
nullptr;
3559 jid = getenv(
"COBALT_JOB_ID");
3564 jid = getenv(
"PBS_JOB_ID");
3569 jid = getenv(
"SLURM_JOB_ID");
3574 jid = getenv(
"JOB_ID");
3587 hostid = (uint32_t)gethostid();
3630 if (fs && fclose(fs) == EOF) {
3637 pid_t cur_pid = getpid();
3639 if (
mypid != cur_pid) {
3668 fd = open(
"/dev/urandom", O_RDONLY);
3669 printf(
"Inside hpcrun_files_next_id fd = %d\n", fd);
3671 read(fd, &id->
host,
sizeof(id->
host));
3674 gettimeofday(&tv,
nullptr);
3675 id->host += (tv.tv_sec << 20) + tv.tv_usec;
3676 id->
host &= 0x00ffffffff;
3682 char name[PATH_MAX];
3690 ret = snprintf(name, PATH_MAX,
FILENAME_TEMPLATE,
dirName.c_str(), fileName,
RANK, thread, id->
host,
mypid, id->
gen, suffix);
3692 if (ret >= PATH_MAX) {
3694 errno = ENAMETOOLONG;
3698 fd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0644);
3721 printf(
"cctlib_hpcrun: unable to open %s file: '%s': %s", suffix, name, strerror(errno));
3758 for (
int i = 0; i < 16; i++) {
3759 mdesc.flags.bits[i] = (uint8_t)0x00;
3762 mdesc.name = (
char*)name;
3763 mdesc.description = (
char*)name;
3765 mdesc.flags.fields.ty = MetricFlags_Ty_Raw;
3767 mdesc.flags.fields.valFmt =
valFmt;
3768 mdesc.flags.fields.show =
true;
3769 mdesc.flags.fields.showPercent =
true;
3770 mdesc.formula =
nullptr;
3771 mdesc.format =
nullptr;
3772 mdesc.is_frequency_metric =
false;
3803 const char* fileCharName =
filename->c_str();
3806 fs = fdopen(fd,
"w");
3816 char mpiRankStr[
bufSZ];
3817 mpiRankStr[0] =
'0';
3818 snprintf(mpiRankStr,
bufSZ,
"%d", 0);
3820 snprintf(tidStr,
bufSZ,
"%d", tID);
3821 char hostidStr[
bufSZ];
3825 char traceMinTimeStr[
bufSZ];
3826 snprintf(traceMinTimeStr,
bufSZ,
"%" PRIu64, (
unsigned long int)0);
3827 char traceMaxTimeStr[
bufSZ];
3828 snprintf(traceMaxTimeStr,
bufSZ,
"%" PRIu64, (
unsigned long int)0);
3832 static int global_arg_len = 9;
3858 unordered_map<UINT32, ModuleInfo>::iterator it, ito;
3861 if (it->second.id == 1) {
3873 if (it->second.id == 1) {
3878 it->second.id = num;
3907 uint64_t measurementGranularity, uint32_t raToCallsiteOfst) {
3926 uint32_t len = (str) ? strlen(str) : 0;
3929 for (i = 0; i < len; i++) {
3930 int c = fputc(str[i], outfs);
3942 int shift = 0, num_write = 0, c;
3944 for (shift = 8; shift >= 0; shift -= 8) {
3945 c = fputc(((v >> shift) & 0xff), fs);
3960 int shift = 0, num_write = 0, c;
3962 for (shift = 24; shift >= 0; shift -= 8) {
3963 c = fputc(((v >> shift) & 0xff), fs);
3976 int shift = 0, num_write = 0, c;
3978 for (shift = 56; shift >= 0; shift -= 8) {
3979 c = fputc(((v >> shift) & 0xff), fs);
3993 size_t num_write = 0;
3995 for (uint i = 0; i < size; ++i) {
3996 int c = fputc(val[i], fs);
4009 if (
nullptr == oldIPNode)
4017 #ifdef HAVE_METRIC_PER_IPNODE
4018 curIP->
metric = oldIPNode->metric;
4032 if (
nullptr == childCtxtStartIdx)
4039 for (i = 0; i < tNode->
nSlots; i++) {
4061 for (i = 0; i < nodes.size(); i++) {
4062 if (nodes.at(i)->IPAddress ==
address)
4073 #ifdef HAVE_METRIC_PER_IPNODE
4075 void* n = cur->metric;
4079 }
else if (!m && n) {
4093 static uint32_t IDGlobal = 2;
4094 uint32_t
id = __sync_fetch_and_add(&IDGlobal, 2);
4108 IMG im = IMG_FindByAddress(node->
IPAddress);
4109 if (node->
IPAddress == 0 || IMG_Id(im) == 0) {
4138 for (i = 0; i < nodes.size(); i++) {
4142 for (i = 0; i < nodes.size(); i++) {
4143 if (!nodes.at(i)->childIPNodes.empty()) {
4150 if (
nullptr == childCtxtStartIdx)
4155 findMain(curIPNode, childCtxtStartIdx->
left, mainNode);
4157 for (i = 0; i < tNode->
nSlots; i++) {
4172 for (i = 0; i < nodes.size(); i++) {
4173 if (nodes.at(i)->IPAddress ==
address)
4199 vector<Context> contextVec1, contextVec2;
4201 if (HPCRunNode->ctxtHandle1 == 0)
4209 for (int32_t i = contextVec1.size() - 1; i >= 0; i--) {
4226 if (HPCRunNode->ctxtHandle2 != 0) {
4228 for (int32_t i = contextVec2.size() - 1; i >= 0; i--) {
4241 cur->
metricVal[HPCRunNode->metric_id] += HPCRunNode->metric;
4243 cur->
metricVal[HPCRunNode->metric_id] = HPCRunNode->metric;
4257 for (i = 0; i < argc; i++) {
4258 if (strcmp(argv[i],
"--") == 0) {
4259 filename =
new string(basename(argv[i + 1]));
4265 int status = mkdir(
dirName.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
4299 vector<NewIPNode*> IPHandle;
4302 IPNode* mainNode =
nullptr;
4304 for (i = 0; i < cctlib->
nSlots; i++) {
4319 #ifdef HAVE_METRIC_PER_IPNODE
4322 rootIP->metric =
nullptr;
4326 for (i = 0; i < cctlib->
nSlots; i++) {
4328 IPHandle.push_back(nIP);
4361 vector<HPCRunCCT_t*>::iterator it;
4362 for (it = OldNodes.begin(); it != OldNodes.end(); ++it) {
4377 vector<NewIPNode*> IPHandle;
uint64_t computeMetricVal(void *metric)
void mergeFunc(void *des, void *src)
#define MAX_CCT_PRINT_DEPTH
#define MAX_CCT_PATH_DEPTH
#define GET_IPNODE_FROM_CONTEXT_HANDLE(handle)
#define HPCRUN_FMT_NV_pid
#define FILENAME_TEMPLATE
#define SERIALIZED_CCT_FILE_PREFIX
#define IS_VALID_CONTEXT(c)
#define CCTLIB_SERIALIZATION_DEFAULT_DIR_NAME
#define HPCRUN_FMT_NV_hostid
static void CCTLibTrimInPlace(std::string &s)
#define SPINLOCK_UNLOCKED_VALUE
#define SERIALIZED_MODULE_MAP_SUFFIX
#define HPCRUN_FMT_NV_traceMaxTime
#define HPCRUN_FMT_NV_progPath
#define HPCRUN_FMT_NV_jobId
#define HPCRUN_FMT_NV_prog
#define HPCRUN_FMT_NV_tid
#define SERIALIZED_SHADOW_TRACE_IP_FILE_SUFFIX
#define SERIALIZED_CCT_FILE_EXTN
#define OSUtil_hostid_NULL
#define SPINLOCK_UNLOCKED
#define SERIALIZED_CCT_FILE_SUFFIX
#define SPINLOCK_LOCKED_VALUE
#define HPCRUN_FMT_NV_envPath
#define HPCRUN_FMT_NV_traceMinTime
#define read_modify_write(type, addr, expn, result)
#define GET_IPNODE_FROM_CONTEXT_HANDLE_CHECKED(handle)
#define GET_CONTEXT_HANDLE_FROM_IP_NODE(node)
#define MAX_STRING_POOL_NODES
#define GET_CONTEXT_HANDLE_FROM_IP_NODE_CHECKED(node)
#define PTHREAD_CREATE_RTN
bool IsValidIP(DeadInfo di)
static uint64_t buf[ITERS]
static int hpcfmt_int4_fwrite(uint32_t val, FILE *outfs)
static VOID CaptureSigSetJmpCtxt(ADDRINT buf, THREADID threadId)
static void CaptureFree(void *ptr, THREADID threadId)
DataHandle_t GetDataObjectHandle(VOID *address, const THREADID threadId)
int PinCCTLibInit(IsInterestingInsFptr isInterestingIns, FILE *logFile, CCTLibInstrumentInsCallback userCallback, VOID *userCallbackArg, BOOL doDataCentric=false)
static void GetNormalizedIpVectorClippedToMainOneAheadIp(vector< NormalizedIP > &ctxt, ContextHandle_t curCtxtHndle)
size_t hpcio_beX_fwrite(uint8_t *val, size_t size, FILE *fs)
static const char HPCRUN_ProfileFnmSfx[]
ContextHandle_t ctxtHandle
static void DeserializeAllCCTs()
static void ThreadCapturePoint(ThreadData *tdata)
struct spinlock_s { volatile long thelock spinlock_t
static void InstrumentTraceEntry(uint32_t traceKey, uint32_t numInterestingInstInTrace, ADDRINT traceFirstIp, THREADID threadId)
static ThreadData * CCTLibGetTLS(const THREADID threadId)
int hpcrun_open_profile_file(int thread, const char *fileName)
int hpcrun_create_metric(const char *name)
IPNode * GetPINCCTContextFrom32BitIndex(ContextHandle_t index)
static bool IsCallInstruction(ADDRINT ip)
static VOID CCTLibInstrumentImageLoad(IMG img, VOID *v)
int hpcio_fclose(FILE *fs)
static VOID CCTLibFini(INT32 code, VOID *v)
static VOID CaptureLandingPadTarget(VOID *, ADDRINT landingPadIp, THREADID threadId)
VOID(*)(INS, VOID *, const uint32_t) CCTLibInstrumentInsCallback
static void InitDataCentric()
enum { MetricFlags_ValTy_NULL=0, MetricFlags_ValTy_Incl, MetricFlags_ValTy_Excl } MetricFlags_ValTy_t
struct metric_desc_properties_t { unsigned time :1 metric_desc_properties_t
int newCCT_hpcrun_write(THREADID threadid)
static void compute_static_var(char *filename, IMG img)
static void SetIPFromInfo(ContextHandle_t ctxtHndle, ADDRINT val)
static void InitMapFilePrefix()
static const char HPCRUN_FMT_VersionLen
static void SerializeMouleInfo()
static TraceNode * FindHandlerFrameForLandingPad(ADDRINT landingPadIp, ADDRINT *outHandlerLo, ADDRINT *outHandlerHi, ThreadData *tData)
static ADDRINT GetIPFromInfo(ContextHandle_t)
void AppendLoadModulesToStream(iostream &ios)
VOID CCTLibAppStartNotification(void *v)
int newCCT_hpcrun_build_cct(std::vector< HPCRunCCT_t * > &OldNodes, THREADID threadid)
struct HPCRunCCT_t { ContextHandle_t ctxtHandle1 HPCRunCCT_t
static ConcurrentShadowMemory< DataHandle_t > sm
ADDRINT GetNextTraceKey()
hpcrun_metricFlags_t flags
static VOID HoldLongJmpBuf(ADDRINT buf, THREADID threadId)
struct PinCCTLib::CCT_LIB_GLOBAL_STATE GLOBAL_STATE
metric_desc_properties_t properties
ContextHandle_t pathHandle
ContextHandle_t GetPINCCT32BitContextIndex(IPNode *node)
static const uint64_t default_measurement_granularity
static void GetDecodedInstFromIP(ADDRINT ip)
static spinlock_t files_lock
NewIPNode * findSameIPbyIP(vector< NewIPNode * > nodes, ADDRINT address)
struct epoch_flags_bitfield { bool isLogicalUnwind :1 epoch_flags_bitfield
void GetParentIPs(ContextHandle_t ctxtHandle, std::vector< ADDRINT > &parentIPs)
enum { MetricFlags_ValFmt_NULL=0, MetricFlags_ValFmt_Int, MetricFlags_ValFmt_Real, } MetricFlags_ValFmt_t
NewIPNode * constructIPNodeFromIP(NewIPNode *parentIP, ADDRINT address, uint64_t *nodeCount)
IPNode * GetPINCCTCurrentContextWithSlot(THREADID id, uint32_t slot)
static VOID DeleteStaticVar(IMG img, VOID *v)
void LogContexts(iostream &ios, ContextHandle_t ctxt1, ContextHandle_t ctxt2)
VOID CCTLibImage(IMG img, VOID *v)
static void InitBuffers()
size_t hpcio_be8_fwrite(const uint64_t *val, FILE *fs)
static int hpcrun_open_file(int thread, const char *suffix, int flags, const char *fileName)
static void InitSegHandler()
VOID PrintFullCallingContext(const ContextHandle_t ctxtHandle)
int PinCCTLibInitForPostmortemAnalysis(FILE *logFile, const std::string &serializedFilesDirectory)
FILE * lazy_open_data_file(int tID, std::string *filename)
static int hpcrun_files_next_id(struct fileid *id)
static VOID CaptureCallocSize(size_t arg0, size_t arg1, THREADID threadId)
static VOID CaptureMallocSize(size_t arg0, THREADID threadId)
static void VisitAllNodesOfSplayTree(TraceSplay *node, FILE *const fp)
static void GetLineFromInfo(const ADDRINT &ip, uint32_t &lineNo, string &filePath)
static int IsARootIPNode(ContextHandle_t curCtxtHndle)
static int hpcfmt_int8_fwrite(uint64_t val, FILE *outfs)
NewIPNode * findSameIP(vector< NewIPNode * > nodes, IPNode *node)
static void OnSig(THREADID threadId, CONTEXT_CHANGE_REASON reason, const CONTEXT *ctxtFrom, CONTEXT *ctxtTo, INT32 sig, VOID *v)
static VOID RememberSlotNoInTLS(uint32_t slot, THREADID threadId)
static const int HPCRUN_FMT_EndianLen
static VOID CaptureReallocSize(void *ptr, size_t arg1, THREADID threadId)
static void InitShadowSpaceForDataCentric(VOID *addr, uint32_t accessLen, DataHandle_t *initializer)
static int GetInstructionLength(ADDRINT ip)
static const char HPCRUN_FMT_Endian[]
static VOID GetFullCallingContextPostmortem(ContextHandle_t curCtxtHndle, vector< Context > &contextVec)
static const int HPCRUN_FMT_MagicLen
static int log_rename_done
static const char HPCRUN_FMT_EpochTag[]
struct Context { std::string functionName Context
static int hpcfmt_int2_fwrite(uint16_t val, FILE *outfs)
static void DottifyCCTNode(TraceNode *traceNode, uint64_t parentDotId, FILE *const fp)
void mergeIP(NewIPNode *prev, IPNode *cur, uint64_t *nodeCount)
size_t hpcio_be2_fwrite(const uint16_t *val, FILE *fs)
int fputs(const char *__restrict __s, FILE *__restrict __stream)
VOID GetFullCallingContext(const ContextHandle_t curCtxtHndle, std::vector< Context > &contextVec)
static bool IsDirectory(const char *path)
@ CCT_LIB_MODE_POSTMORTEM
@ CCT_LIB_MODE_COLLECTION
bool HaveSameCallerPrefix(ContextHandle_t ctxt1, ContextHandle_t ctxt2)
static const char HPCRUN_FMT_Magic[]
static void GetAllFilesInDirWithExtn(const string &root, const string &ext, vector< string > &ret)
void hpcrun_insert_path(NewIPNode *root, HPCRunCCT_t *HPCRunNode, uint64_t *nodeCount)
static int unsigned long fetch_and_store(volatile long *addr, long newval)
int hpcrun_fmt_hdrwrite(FILE *fs)
MetricFlags_ValTy_t valTy
MetricFlags_ValFmt_t valFmt
void SerializeMetadata(const std::string &directoryForSerializationFiles="")
static void findMain(IPNode *curIPNode, TraceSplay *childCtxtStartIdx, IPNode **mainNode)
static void DeserializeTraceIps()
bool IsSameSourceLine(ContextHandle_t ctxt1, ContextHandle_t ctxt2)
static VOID SetCallInitFlag(uint32_t slot, THREADID threadId)
static void ThreadCreatePoint(THREADID threadId)
static ContextHandle_t GetNextIPVecBuffer(uint32_t num)
static const RtnInfo * GetOrClassifyRoutine(RTN rtn)
struct QNode { struct QNode *volatile next QNode
int hpcrun_fmt_epochHdr_fwrite(FILE *fs, epoch_flags_t flags, uint64_t measurementGranularity, uint32_t raToCallsiteOfst)
BOOL IsCallOrRetIns(INS ins)
static void CCTLibInitThreadData(ThreadData *const tdata, CONTEXT *ctxt, THREADID threadId)
static void InitLogFile(FILE *logFile)
static VOID CCTLibThreadStart(THREADID threadid, CONTEXT *ctxt, INT32 flags, VOID *v)
void DeserializeMetadata(const string &directoryForSerializationFiles)
enum { MetricFlags_Ty_NULL=0, MetricFlags_Ty_Raw, MetricFlags_Ty_Final, MetricFlags_Ty_Derived } MetricFlags_Ty_t
static VOID MaybeGoUpCallChain(ADDRINT retTarget, const ADDRINT *returnAddrs, uint32_t n, THREADID threadId)
const metric_desc_t metricDesc_NULL
void tranverseIPs(NewIPNode *curIPNode, TraceSplay *childCtxtStartIdx, uint64_t *nodeCount)
static void CCTLibInstrumentTrace(TRACE trace, void *isInterestingIns)
static void SerializeAllCCTs()
void IPNode_fwrite(NewIPNode *node, FILE *fs)
int hpcrun_fmt_loadmap_fwrite(FILE *fs, const std::string &filename)
static TraceNode * DeserializeCCTNode(ContextHandle_t parentCtxtHndl, FILE *const fp)
struct hpcrun_metricFlags_fields { MetricFlags_Ty_t ty :8 hpcrun_metricFlags_fields
static void DeserializeMouleInfo()
int init_hpcrun_format(int argc, char *argv[], void(*mergeFunc)(void *des, void *src)=nullptr, uint64_t(*computeMetricVal)(void *metric)=nullptr, bool skip=false)
static void ListAllNodesOfSplayTree(TraceSplay *node, vector< TraceNode * > &childTraces)
static const int HPCRUN_FMT_EpochTagLen
static uint32_t GetNumInterestingInsInTrace(const TRACE &trace, IsInterestingInsFptr isInterestingIns)
static VOID GoUpCallChain(THREADID threadId)
void DumpCallStack(THREADID id, uint32_t slot)
static struct fileid earlyid
NewIPNode * constructIPNode(NewIPNode *parentIP, IPNode *oldIPNode, uint32_t parentID, uint64_t *nodeCount)
union epoch_flags_t { epoch_flags_bitfield fields epoch_flags_t
static VOID CaptureMallocPointer(void *ptr, THREADID threadId)
static epoch_flags_t epoch_flags
size_t hpcio_be4_fwrite(const uint32_t *val, FILE *fs)
static VOID PopulateIPReverseMapAndAccountTraceInstructions(TRACE trace, uint32_t traceKey, uint32_t numInterestingInstInTrace, IsInterestingInsFptr isInterestingIns, const RtnInfo *rinfo)
static VOID GetFullCallingContextInSitu(ContextHandle_t curCtxtHndle, vector< Context > &contextVec)
static void UpdateCurTraceAndIp(ThreadData *tData, TraceNode *const trace)
static bool endsWithExtn(const string &base, const string &ext)
const char * OSUtil_jobid()
static void SegvHandler(int)
static void hpcrun_files_init()
static void spinlock_unlock(spinlock_t *l)
static const char HPCRUN_FMT_Version[]
static void UpdateCurTraceOnly(ThreadData *tData, TraceNode *const trace)
int hpcfmt_str_fwrite(const char *str, FILE *outfs)
void hpcrun_set_metric_info_w_fn(int metric_id, const char *name, size_t period, FILE *fs)
struct DataHandle_t { uint8_t objectType DataHandle_t
ContextHandle_t GetContextHandle(const THREADID id, const uint32_t slot)
static VOID RestoreSigLongJmpCtxt(THREADID threadId)
static VOID ComputeVarBounds(IMG img, VOID *v)
VOID Fini(INT32 code, VOID *v)
static bool TraceIsInAddressRange(TraceNode *trace, ADDRINT lo, ADDRINT hi)
int newCCT_hpcrun_selection_write(THREADID threadid)
static const string & GetModulePathFromInfo(IPNode *ipNode)
IPNode * GetPINCCTCurrentContext(THREADID id)
static void spinlock_lock(spinlock_t *l)
volatile bool predecessorWasWriter
static int hpcfmt_intX_fwrite(uint8_t *val, size_t size, FILE *outfs)
int hpcrun_fmt_hdr_fwrite(FILE *fs, const char *arg1, const char *arg2)
static struct fileid lateid
char * GetStringFromStringPool(const uint32_t index)
ContextHandle_t GetTraceStartHandle(ContextHandle_t ctxtHandle)
static bool IsValidPLTSignature(const ADDRINT &ip)
static uint32_t GetNextStringPoolIndex(char *name)
static void SerializeCCTNode(TraceNode *traceNode, FILE *const fp)
struct metric_set_t metric_set_t
const hpcrun_metricFlags_t hpcrun_metricFlags_NULL
static uint32_t NO_MORE_TRACE_NODES_IN_SPLAY_TREE
BOOL(*)(INS) IsInterestingInsFptr
static void SerializeTraceIps()
static const uint32_t default_ra_to_callsite_distance
struct metric_desc_t { char *name metric_desc_t
static int log_rename_ret
union hpcrun_metricFlags_t { hpcrun_metricFlags_fields fields hpcrun_metricFlags_t
void tranverseNewCCT(vector< NewIPNode * > nodes, FILE *fs)
std::string env(const char *n)
#define PAGE_OFFSET(addr)
#define PIN_ExitProcess(a)
#define REGULAR_SPLAY_TREE(type, root, key, value, left, right)
static TraceSplay * splay(TraceSplay *root, uintptr_t key)
string CCTLibFilePathPrefix
volatile ContextHandle_t threadCreatorCtxtHndl
uint64_t(* computeMetricVal)(void *metric)
uint64_t curPreAllocatedContextBufferIndex
unordered_map< ADDRINT, RtnInfo > rtnSelfRecMap
xed_state_t cct_xed_state
XED state.
unordered_map< UINT32, ModuleInfo > ModuleInfoMap
CCTLibInstrumentInsCallback userInstrumentationCallback
IPNode * preAllocatedContextBuffer
unordered_map< uint32_t, void * > traceShadowMap
char metrics[MAX_METRICS][MAX_LEN]
VOID * userInstrumentationCallbackArg
volatile uint64_t threadCaptureCount
void(* mergeFunc)(void *des, void *src)
char * preAllocatedStringPool
uint32_t curPreAllocatedStringPoolIndex
char disassemblyBuff[200]
volatile TraceNode * threadCreatorTraceNode
PIN_RWMUTEX rtnSelfRecRWMutex
volatile uint64_t threadCreateCount
vector< ThreadData > deserializedCCTs
string serializationDirectory
TraceNode * parentTraceNode
TraceSplay * calleeTraceNodes
vector< NewIPNode * > childIPNodes
ADDRINT * selfRecReturnAddrs
ContextHandle_t childCtxtStartIdx
ContextHandle_t tlsRootCtxtHndl
ContextHandle_t tlsCurrentChildContextStartIndex
ContextHandle_t tlsParentThreadCtxtHndl
struct TraceNode * tlsCurrentTraceNode
size_t tlsDynamicMemoryAllocationSize
struct TraceNode * tlsPendingHandlerFrame
ContextHandle_t tlsDynamicMemoryAllocationPathHandle
ADDRINT tlsPendingLandingPadIp
ContextHandle_t tlsPendingHandlerCtxt
struct TraceNode * tlsParentThreadTraceNode
ContextHandle_t tlsCurrentCtxtHndl
NewIPNode * tlsHPCRunCCTRoot
ADDRINT tlsLongJmpHoldBuf
struct TraceNode * tlsRootTraceNode
sparse_hash_map< ADDRINT, ContextHandle_t > tlsLongJmpMap
ContextHandle_t childCtxtStartIdx
ContextHandle_t callerCtxtHndl