]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
buffer: optional buffer debug output
authorSage Weil <sage@newdream.net>
Thu, 3 Dec 2009 23:54:24 +0000 (15:54 -0800)
committerSage Weil <sage@newdream.net>
Fri, 4 Dec 2009 00:21:10 +0000 (16:21 -0800)
This interferes with the dout crap because we can't #include it, so you
need to turn all that output off to avoid getting jumbled output.  Or
better yet make sure you don't daemon() but still log dout to a file.

Fixed up the output parser to find leaks.

src/common/buffer.cc
src/include/buffer.h
src/script/find_bufferleaks.pl

index dbe3c2e9af12e1ef5cc24698a10c63cc7f2102cb..a17b451291c475ff7f31d70fbf82ea47a576e906 100644 (file)
@@ -20,6 +20,7 @@
 #include <errno.h>
 #include <fstream>
 
+Spinlock buffer_lock("buffer_lock");
 atomic_t buffer_total_alloc;
 
 
index 43bb492ef2e07c29c1abc24d17fbf84f250e07ed..43ce02ba0bfc505d2261feb9029de73852a732aa 100644 (file)
@@ -58,7 +58,20 @@ using std::string;
 #include "crc32c.h"
 #include "assert.h"
 
+#include "common/Spinlock.h"
+
 extern atomic_t buffer_total_alloc;
+extern Spinlock buffer_lock;
+
+//#define BUFFER_DEBUG
+
+#ifdef BUFFER_DEBUG
+# define bdout { buffer_lock.lock(); cout
+# define bendl std::endl; buffer_lock.unlock(); }
+#else
+# define bdout if (0) { cout
+# define bendl std::endl; }
+#endif
 
 class buffer {
   /*
@@ -138,13 +151,16 @@ private:
       else
        data = 0;
       inc_total_alloc(len);
+      bdout << "raw_char alloc " << (void *)data << " " << l << " " << buffer_total_alloc.test() << bendl;
     }
     raw_char(unsigned l, char *b) : raw(b, l) {
       inc_total_alloc(len);
+      bdout << "raw_char alloc " << (void *)data << " " << l << " " << buffer_total_alloc.test() << bendl;
     }
     ~raw_char() {
       delete[] data;
       dec_total_alloc(len);      
+      bdout << "raw_char free " << (void *)data << " " << buffer_total_alloc.test() << bendl;
     }
     raw* clone_empty() {
       return new raw_char(len);
@@ -159,13 +175,16 @@ private:
       else
        data = 0;
       inc_total_alloc(len);
+      bdout << "raw_malloc alloc " << (void *)data << " " << l << " " << buffer_total_alloc.test() << bendl;
     }
     raw_malloc(unsigned l, char *b) : raw(b, l) {
       inc_total_alloc(len);
+      bdout << "raw_malloc alloc " << (void *)data << " " << l << " " << buffer_total_alloc.test() << bendl;
     }
     ~raw_malloc() {
       free(data);
       dec_total_alloc(len);      
+      bdout << "raw_malloc free " << (void *)data << " " << buffer_total_alloc.test() << bendl;
     }
     raw* clone_empty() {
       return new raw_malloc(len);
@@ -189,10 +208,12 @@ private:
       if (!data)
        throw new bad_alloc;
       inc_total_alloc(len);
+      bdout << "raw_mmap alloc " << (void *)data << " " << l << " " << buffer_total_alloc.test() << bendl;
     }
     ~raw_mmap_pages() {
       ::munmap(data, len);
       dec_total_alloc(len);
+      bdout << "raw_mmap free " << (void *)data << " " << buffer_total_alloc.test() << bendl;
     }
     raw* clone_empty() {
       return new raw_mmap_pages(len);
@@ -213,10 +234,12 @@ private:
       if (!data)
        throw new bad_alloc;
       inc_total_alloc(len);
+      bdout << "raw_posix_aligned alloc " << (void *)data << " " << l << " " << buffer_total_alloc.test() << bendl;
     }
     ~raw_posix_aligned() {
       ::free((void*)data);
       dec_total_alloc(len);
+      bdout << "raw_posix_aligned free " << (void *)data << " " << buffer_total_alloc.test() << bendl;
     }
     raw* clone_empty() {
       return new raw_posix_aligned(len);
index 152515d5e788eb936fe2efd8e4245d2a206823f0..55abc720d60606cc94fb90d43eef5e86616e4824 100755 (executable)
@@ -2,68 +2,23 @@
 
 use strict;
 my %buffers;
-my %bufferlists;
-my %ref;
-my %mal;
+
 my $l = 1;
 while (<>) {
-       #print "$l: $_";
-
-       # cinode:auth_pin on inode [1000000002625 /gnu/blah_client_created. 0x89b7700] count now 1 + 0
-
-       if (/^buffer\.cons /) {
-               my ($x) = /(0x\S+)/;
-               $buffers{$x} = 1;
-       }
-       if (/^buffer\.des /) {
-               my ($x) = /(0x\S+)/;
-               die "des without cons at $l: $_" unless $buffers{$x};
-               delete $buffers{$x};
-               die "des with ref>0 at $l: $_" unless $ref{$x} == 0;
-               delete $ref{$x};
-       }
-
-       if (/^bufferlist\.cons /) {
-               my ($x) = /(0x\S+)/;
-               $bufferlists{$x} = 1;
-       }
-       if (/^bufferlist\.des /) {
-               my ($x) = /(0x\S+)/;
-               warn "des without cons at $l: $_" unless $bufferlists{$x};
-               delete $bufferlists{$x};
-       }
-
-
-       if (/^buffer\.malloc /) {
-               my ($x) = /(0x\S+)/;
-               $mal{$x} = 1;
-       }
-       if (/^buffer\.free /) {
-               my ($x) = /(0x\S+)/;
-               die "free with malloc at $l: $_" unless $mal{$x};
-               delete $mal{$x};
-       }
-
-       if (/^buffer\.get /) {
-               my ($x) = /(0x\S+)/;
-               $ref{$x}++;
-       }
-       if (/^buffer\.get /) {
-               my ($x) = /(0x\S+)/;
-               $ref{$x}--;
-       }
-
-$l++;
-}
-
-for my $x (keys %bufferlists) {
-       print "leaked bufferlist $x\n";
-}
-
-for my $x (keys %buffers) {
-       print "leaked buffer $x ref $ref{$x}\n";
+    #print "$l: $_";
+    
+    if (/^raw_(\w+) alloc (\S+)/) {
+       #print "alloc $2\n";
+       $buffers{$2} = "$l: $_";
+    }
+    if (/^raw_(\w+) free (\S+)/) {
+       #print "free $2\n";
+       print "free without alloc at $l: $_" unless $buffers{$2};
+       delete $buffers{$2};
+    }
+    $l++;
 }
 
-for my $x (keys %mal) {
-       print "leaked buffer dataptr $x ref $ref{$x}\n";
+for my $x (sort {$buffers{$a} <=> $buffers{$b}} keys %buffers) {
+    print "leaked $buffers{$x}";
 }