Enhanced tracemode memory with a new flag (+recordStack) to record the stack trace...
authorFilippo Gioachin <gioachin@illinois.edu>
Mon, 17 Sep 2007 21:23:18 +0000 (21:23 +0000)
committerFilippo Gioachin <gioachin@illinois.edu>
Mon, 17 Sep 2007 21:23:18 +0000 (21:23 +0000)
src/ck-perf/trace-memory.C
src/ck-perf/trace-memory.h
src/ck-perf/trace.h
src/ck-perf/tracec.C
src/ck-perf/tracec.h

index 437b3da150b27971f75483e118c8092b1616d4fd..f1e0402a858b0354eae0c14f91e882daa942490c 100644 (file)
@@ -1,6 +1,6 @@
 #include "trace-memory.h"
 
-#define DefaultBufferSize  1000000
+#define DefaultBufferSize  10000
 
 #define DEBUGF(x) // CmiPrintf x
 
@@ -18,34 +18,50 @@ void _createTracememory(char **argv)
   CkpvAccess(_traces)->addTrace(CkpvAccess(_trace));
 }
 
-MemEntry::MemEntry() : type(0), where(0), size(0) { }
+MemEntry::MemEntry() : type(0), where(0), size(0), stackSize(0) { }
 
 void MemEntry::write(FILE *fp) {
   fprintf(fp, "%d %p", type, where);
-  if (type == MEMORY_MALLOC) fprintf(fp, " %d", size);
+  if (type == MEMORY_MALLOC) {
+    fprintf(fp, " %d", size);
+    fprintf(fp, " %d", stackSize);
+    void **stack = (void**)(this+1);
+    for (int i=0; i<stackSize; ++i) {
+      fprintf(fp, " %p", stack[i]);
+    }
+  }
   fprintf(fp, "\n");
 }
 
 TraceMemory::TraceMemory(char **argv) {
   usedBuffer = 0;
   firstTime = 1;
+  traceDisabled = false;
   logBufSize = DefaultBufferSize;
   if (CmiGetArgIntDesc(argv,"+memlogsize",&logBufSize, 
-                      "Log entries to buffer per I/O")) {
+                      "Log buffer size (in kB)")) {
     if (CkMyPe() == 0) {
-      CmiPrintf("Trace: logsize: %d\n", logBufSize);
+      CmiPrintf("Trace: logsize: %d kB\n", logBufSize);
     }
   }
-  logBuffer = new MemEntry[logBufSize];
+  recordStack = false;
+  if (CmiGetArgFlagDesc(argv,"+recordStack",
+               "Record stack trace for malloc")) {
+    recordStack = true;
+  }
+  logBufSize *= 1024;
+  logBuffer = (char *) ::malloc(logBufSize);
 }
 
-inline void TraceMemory::checkFlush() {
-  if (usedBuffer == logBufSize) {
+inline void TraceMemory::checkFlush(int increment) {
+  if (usedBuffer+increment >= logBufSize) {
     flush();
   }
 }
 
 inline void TraceMemory::flush() {
+  traceDisabled = true;
+  //CmiPrintf("[%d] TraceMemory::flush %d\n",CmiMyPe(),usedBuffer);
   char *mode;
   if (firstTime) mode = "w";
   else mode = "a";
@@ -60,21 +76,37 @@ inline void TraceMemory::flush() {
   if (!fp) {
     CmiAbort("Cannot open file for Memory log writing\n");
   }
-  for (int i=0; i<usedBuffer; ++i) logBuffer[i].write(fp);
+  //fprintf(fp, "begin flush\n");
+  for (int i=0; i<usedBuffer; i += sizeof(MemEntry) + ((MemEntry*)&logBuffer[i])->stackSize*sizeof(void*)) {
+    ((MemEntry*)&logBuffer[i])->write(fp);
+  }
+  //fprintf(fp, "end flush\n");
   fclose(fp);
   usedBuffer = 0;
+  traceDisabled = false;
 }
 
 void TraceMemory::traceClose() {
   flush();
 }
 
-void TraceMemory::malloc(void *where, int size) {
-  logBuffer[usedBuffer++].set(MEMORY_MALLOC, where, size);
-  checkFlush();
+void TraceMemory::malloc(void *where, int size, void **stack, int stackSize) {
+  if (!traceDisabled) {
+    int increment = sizeof(MemEntry) + (recordStack ? stackSize*sizeof(void*) : 0);
+    checkFlush(increment);
+    ((MemEntry*)&logBuffer[usedBuffer])->set(MEMORY_MALLOC, where, size);
+    if (recordStack) ((MemEntry*)&logBuffer[usedBuffer])->setStack(stackSize, stack);
+    usedBuffer += increment;
+    //CmiPrintf("[%d] TraceMemory::malloc  %d  (%p)\n",CmiMyPe(),usedBuffer,where);
+  }
 }
 
 void TraceMemory::free(void *where) {
-  logBuffer[usedBuffer++].set(MEMORY_FREE, where);
-  checkFlush();
+  if (!traceDisabled) {
+    int increment = sizeof(MemEntry);
+    checkFlush(increment);
+    ((MemEntry*)&logBuffer[usedBuffer])->set(MEMORY_FREE, where);
+    usedBuffer += increment;
+    //CmiPrintf("[%d] TraceMemory::free    %d  (%p)\n",CmiMyPe(),usedBuffer,where);
+  }
 }
index cd5177811242362bacc382f402c5ba64e089b5a2..9f4cb803ecd002eeb807673295bd22971f0085e6 100644 (file)
@@ -9,10 +9,12 @@
 /** A representant of a memory operation */
 
 class MemEntry {
+  friend class TraceMemory;
  private:
   int type;
   void *where;
   int size;
+  int stackSize;
   
  public:  
   MemEntry();
@@ -21,6 +23,11 @@ class MemEntry {
     type = t;
     where = w;
     size = s;
+    stackSize = 0;
+  }
+  void setStack(int ss, void **s) {
+    stackSize = ss;
+    memcpy(this+1, s, ss*sizeof(void*));
   }
 };
 
@@ -33,14 +40,17 @@ class TraceMemory : public Trace {
   int firstTime;
   int logBufSize;
   int usedBuffer;
-  MemEntry *logBuffer;
-  void checkFlush();
+  bool recordStack;
+  char *logBuffer;
+  bool traceDisabled;
+
+  void checkFlush(int add);
   void flush();
  public:
   TraceMemory(char **argv);
   
   void traceClose();
-  void malloc(void *where, int size);
+  void malloc(void *where, int size, void **stack, int stackSize);
   void free(void *where);
 };
 
index 7352f720be6e71d61f5a14939149f1610e88212f..ad8e4fce90ce19ec84eed7d9e64fffb4323b8057 100644 (file)
@@ -128,7 +128,7 @@ class Trace {
     virtual void endFunc(int idx){}
 
     /* Memory tracing */
-    virtual void malloc(void *where, int size){}
+    virtual void malloc(void *where, int size, void **stack, int stackSize){}
     virtual void free(void *where){}
 
     /* for implementing thread listeners */
@@ -222,7 +222,7 @@ public:
     inline void endFunc(int idx){ ALLDO(endFunc(idx)); }
 
     /* Memory tracing */
-    inline void malloc(void *where, int size){ ALLDO(malloc(where,size)); }
+    inline void malloc(void *where, int size, void **stack, int stackSize){ ALLDO(malloc(where,size,stack,stackSize)); }
     inline void free(void *where){ ALLDO(free(where)); }
 
     /* calls for thread listener registration for each trace module */
@@ -269,7 +269,7 @@ extern "C" {
 #define _TRACE_DEQUEUE(env) _TRACE_ONLY(CkpvAccess(_traces)->dequeue(env))
 
 /* Memory tracing */
-#define _TRACE_MALLOC(where, size) _TRACE_ONLY(CkpvAccess(_traces)->malloc(where,size))
+#define _TRACE_MALLOC(where, size, stack, stackSize) _TRACE_ONLY(CkpvAccess(_traces)->malloc(where,size,stack,stackSize))
 #define _TRACE_FREE(where) _TRACE_ONLY(CkpvAccess(_traces)->free(where))
 
 
index 291e3bb086582e64049011c5153a7a9dd89fe964..8ee481faa8d1a9fd3b31755d590112a6791bcee6 100644 (file)
@@ -5,8 +5,8 @@
 
 extern "C" {
 
-  void traceMalloc_c(void *where, int size) {
-    _TRACE_MALLOC(where, size);
+  void traceMalloc_c(void *where, int size, void **stack, int stackSize) {
+    _TRACE_MALLOC(where, size, stack, stackSize);
   }
 
   void traceFree_c(void *where) {
index d037761a0a5a857bb0a1dad925e12cd14e250cb0..de3606d82b8096a173fe52e6761610706ca6b0de 100644 (file)
@@ -5,7 +5,7 @@
 extern "C" {
 #endif
 
-  extern void traceMalloc_c(void *where, int size);
+  extern void traceMalloc_c(void *where, int size, void **stack, int stackSize);
   extern void traceFree_c(void *where);
 
 #ifdef __cplusplus