]> git.cworth.org Git - apitrace/commitdiff
Plug several leaks when retracing.
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Thu, 3 Nov 2011 19:35:53 +0000 (19:35 +0000)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Sat, 17 Mar 2012 23:41:30 +0000 (23:41 +0000)
Use a scoped allocator to help keep track of the things that need to be
freed.

retrace.hpp
retrace.py

index 57b8b052639085e6b8742bd5e395761f999577fe..dc11bb382243b13c51afe837c7fec40f6664a7de 100644 (file)
@@ -1,6 +1,6 @@
 /**************************************************************************
  *
- * Copyright 2011 Jose Fonseca
+ * Copyright 2011-2012 Jose Fonseca
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -80,6 +80,53 @@ public:
 };
 
 
+/**
+ * Similar to alloca(), but implemented with malloc.
+ */
+class ScopedAllocator
+{
+private:
+    void *next;
+
+public:
+    ScopedAllocator() :
+        next(NULL) {
+    }
+
+    inline void *
+    alloc(size_t size) {
+        if (!size) {
+            return NULL;
+        }
+
+        void * * buf = static_cast<void **>(malloc(sizeof(void *) + size));
+        if (!buf) {
+            return NULL;
+        }
+
+        *buf = next;
+        next = buf;
+
+        return &buf[1];
+    }
+
+    template< class T >
+    inline T *
+    alloc(size_t n = 1) {
+        return static_cast<T *>(alloc(sizeof(T) * n));
+    }
+
+    inline
+    ~ScopedAllocator() {
+        while (next) {
+            void *temp = *static_cast<void **>(next);
+            free(next);
+            next = temp;
+        }
+    }
+};
+
+
 void
 addRegion(unsigned long long address, void *buffer, unsigned long long size);
 
index 25e26093597df8fad5ff9ab5d0217d1ffb1c6069..1203a0992e4cebde23706c2fc5a90190d420986d 100644 (file)
@@ -72,7 +72,7 @@ class ValueDeserializer(stdapi.Visitor):
         print '    const trace::Array *__a%s = dynamic_cast<const trace::Array *>(&%s);' % (array.tag, rvalue)
         print '    if (__a%s) {' % (array.tag)
         length = '__a%s->values.size()' % array.tag
-        print '        %s = new %s[%s];' % (lvalue, array.type, length)
+        print '        %s = _allocator.alloc<%s>(%s);' % (lvalue, array.type, length)
         index = '__j' + array.tag
         print '        for (size_t {i} = 0; {i} < {length}; ++{i}) {{'.format(i = index, length = length)
         try:
@@ -86,7 +86,7 @@ class ValueDeserializer(stdapi.Visitor):
     def visitPointer(self, pointer, lvalue, rvalue):
         print '    const trace::Array *__a%s = dynamic_cast<const trace::Array *>(&%s);' % (pointer.tag, rvalue)
         print '    if (__a%s) {' % (pointer.tag)
-        print '        %s = new %s;' % (lvalue, pointer.type)
+        print '        %s = _allocator.alloc<%s>();' % (lvalue, pointer.type)
         try:
             self.visit(pointer.type, '%s[0]' % (lvalue,), '*__a%s->values[0]' % (pointer.tag,))
         finally:
@@ -212,6 +212,8 @@ class Retracer:
             print '    (void)call;'
             return
 
+        print '    retrace::ScopedAllocator _allocator;'
+        print '    (void)_allocator;'
         success = True
         for arg in function.args:
             arg_type = ConstRemover().visit(arg.type)