From a4257d87829e20337edbbf8cd9d3c528fd3e6568 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 3 Dec 2009 15:54:24 -0800 Subject: [PATCH] buffer: optional buffer debug output 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 | 1 + src/include/buffer.h | 23 +++++++++++ src/script/find_bufferleaks.pl | 75 +++++++--------------------------- 3 files changed, 39 insertions(+), 60 deletions(-) diff --git a/src/common/buffer.cc b/src/common/buffer.cc index dbe3c2e9af12e..a17b451291c47 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -20,6 +20,7 @@ #include #include +Spinlock buffer_lock("buffer_lock"); atomic_t buffer_total_alloc; diff --git a/src/include/buffer.h b/src/include/buffer.h index 43bb492ef2e07..43ce02ba0bfc5 100644 --- a/src/include/buffer.h +++ b/src/include/buffer.h @@ -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); diff --git a/src/script/find_bufferleaks.pl b/src/script/find_bufferleaks.pl index 152515d5e788e..55abc720d6060 100755 --- a/src/script/find_bufferleaks.pl +++ b/src/script/find_bufferleaks.pl @@ -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}"; } -- 2.39.5