[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash libbase/Makefile.am testsuite/libbase/Mak...
From: |
Rob Savoye |
Subject: |
[Gnash-commit] gnash libbase/Makefile.am testsuite/libbase/Mak... |
Date: |
Fri, 07 Mar 2008 01:02:22 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Rob Savoye <rsavoye> 08/03/07 01:02:21
Modified files:
libbase : Makefile.am
testsuite/libbase: Makefile.am
. : ChangeLog
Added files:
libbase : memory.h memory.cpp
testsuite/libbase: memtest.cpp
Log message:
* testsuite/libbase/memtest.cpp: New test case for the Memory
debugger for use by maintainers.
* testsuite/libbase/Makefile.am: Add new memory testv case.
* libbase/memory.{h,cpp}: New Memory class for analysing memory
allocation to find leaks and bloat.
* libbase/makefile.am: Add memory.*.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/Makefile.am?cvsroot=gnash&r1=1.96&r2=1.97
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/memory.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/memory.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/libbase/Makefile.am?cvsroot=gnash&r1=1.35&r2=1.36
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/libbase/memtest.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.5834&r2=1.5835
Patches:
Index: libbase/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/libbase/Makefile.am,v
retrieving revision 1.96
retrieving revision 1.97
diff -u -b -r1.96 -r1.97
--- libbase/Makefile.am 21 Jan 2008 20:55:44 -0000 1.96
+++ libbase/Makefile.am 7 Mar 2008 01:02:20 -0000 1.97
@@ -85,6 +85,7 @@
lirc.cpp \
log.cpp \
membuf.cpp \
+ memory.cpp \
network.cpp \
postscript.cpp \
rc.cpp \
@@ -118,6 +119,7 @@
image.h \
jpeg.h \
membuf.h \
+ memory.h \
network.h \
lirc.h \
log.h \
Index: testsuite/libbase/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/testsuite/libbase/Makefile.am,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -b -r1.35 -r1.36
--- testsuite/libbase/Makefile.am 21 Jan 2008 23:26:50 -0000 1.35
+++ testsuite/libbase/Makefile.am 7 Mar 2008 01:02:20 -0000 1.36
@@ -44,6 +44,7 @@
URLTest \
RcTest \
IntTypesTest \
+ memtest \
$(NULL)
if CURL
@@ -72,6 +73,9 @@
IntTypesTest_SOURCES = IntTypesTest.cpp
IntTypesTest_CPPFLAGS = -DSRCDIR="$(srcdir)"
+# Test the Memory class
+memtest_SOURCES = memtest.cpp
+
# LogTest_SOURCES = TCXXLog.cpp
# LogTest_CPPFLAGS = '-DBUILDDIR="$(abs_builddir)"'
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.5834
retrieving revision 1.5835
diff -u -b -r1.5834 -r1.5835
--- ChangeLog 6 Mar 2008 20:29:09 -0000 1.5834
+++ ChangeLog 7 Mar 2008 01:02:20 -0000 1.5835
@@ -1,3 +1,12 @@
+2008-03-06 Rob Savoye <address@hidden>
+
+ * testsuite/libbase/memtest.cpp: New test case for the Memory
+ debugger for use by maintainers.
+ * testsuite/libbase/Makefile.am: Add new memory testv case.
+ * libbase/memory.{h,cpp}: New Memory class for analysing memory
+ allocation to find leaks and bloat.
+ * libbase/makefile.am: Add memory.*.
+
2008-03-06 Sandro Santilli <address@hidden>
* server/array.cpp: there's no such thing as an Array.size member, and
Index: libbase/memory.h
===================================================================
RCS file: libbase/memory.h
diff -N libbase/memory.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libbase/memory.h 7 Mar 2008 01:02:19 -0000 1.1
@@ -0,0 +1,111 @@
+//
+// Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+//
+// This class is a memory allocation tracker used to optimize
+// the memory usage and find memory leaks.
+//
+#ifndef __MEMORY_H__
+#define __MEMORY_H__
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+// If we don't have support for mallinfo(), this code is useless
+#if HAVE_MALLINFO
+
+#include <cstdlib>
+#include <malloc.h>
+
+namespace gnash {
+
+class Memory {
+public:
+
+ // Borrowed from malloc.h and trimmed down.
+ struct small_mallinfo {
+ int line; // line number of this data sample
+ int arena; // non-mmapped space allocated from system
+ int uordblks; // total allocated space
+ int fordblks; // total free space
+ };
+ DSOEXPORT Memory();
+ DSOEXPORT Memory(int size);
+ DSOEXPORT ~Memory();
+
+ // Start collecting statistics. This can effect performance
+ void startStats();
+
+ // Stop collecting statistics
+ void endStats() { addStats();_collecting = false; };
+
+ // Erase all collected data and reset collections.
+ void reset();
+
+ // checkpoint()
+ void startCheckpoint() { _checkpoint[0] = mallinfo(); };
+ bool endCheckpoint();
+
+ // Add or retrieve mallinfo data
+ int addStats();
+ int addStats(int line);
+ int addStats(struct small_mallinfo *x);
+ int addStats(struct small_mallinfo *x, int line);
+ struct small_mallinfo *getStats() { return _info; };
+ struct small_mallinfo *operator[](int x) { return _info + x; };
+ int totalStats() { return _index; };
+
+ // Analyze memory usage
+ bool analyze();
+
+ // Dump the differences of bytes allocated between two samples
+ int diffStats();
+ int diffStats(int x, int y);
+
+ // Dump the vector of stored classes
+ void dump(struct mallinfo *x);
+ void dump(struct small_mallinfo *x);
+ void dump();
+private:
+ bool _collecting;
+ // For data logging, we want to store as little as possible
+ // so we don't impact the system too hard. Data logging memory
+ // allocations can generate a huge amount of data, so we have
+ // to be careful. We also can't use STL, as that does more
+ // memory allocations, which will confuse our statistics
+ // gathering.
+ struct small_mallinfo *_info;
+ // Since we aren't using STL, we have to store how much
+ // data storage we have ourselves.
+ size_t _size;
+ int _index;
+ // For checkpoints, we want the all the data
+ struct mallinfo _checkpoint[2];
+};
+
+} // end of gnash namespace
+
+#endif // end of HAVE_MALLINFO
+
+// end of __MEMORY_H__
+#endif
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:
Index: libbase/memory.cpp
===================================================================
RCS file: libbase/memory.cpp
diff -N libbase/memory.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libbase/memory.cpp 7 Mar 2008 01:02:20 -0000 1.1
@@ -0,0 +1,307 @@
+//
+// Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+//
+// This class is a memory allocation tracker used to optimize
+// the memory usage and find memory leaks.
+//
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+// If we don't have support for mallinfo(), this code is useless
+#if HAVE_MALLINFO
+
+#include <cstdlib>
+#include <malloc.h>
+#include <vector>
+
+#include "log.h"
+#include "memory.h"
+
+using namespace std;
+
+namespace gnash {
+
+RcInitFile& rcfile = gnash::RcInitFile::getDefaultInstance();
+
+
+const int DATALOG_SIZE = 1024;
+
+Memory::Memory()
+ : _collecting(false),
+ _info(0),
+ _size(0),
+ _index(0)
+{
+// GNASH_REPORT_FUNCTION;
+}
+
+
+Memory::Memory(int size)
+ : _collecting(false)
+{
+// GNASH_REPORT_FUNCTION;
+ _size = size;
+ _info = new struct small_mallinfo[DATALOG_SIZE];
+ reset();
+}
+
+Memory::~Memory()
+{
+// GNASH_REPORT_FUNCTION;
+ if (_info) {
+ delete _info;
+ }
+ _index = 0;
+ _size = 0;
+}
+
+// Erase all collected data and reset collections.
+void
+Memory::reset()
+{
+// GNASH_REPORT_FUNCTION;
+ if (_info) {
+ memset(_info, 0, _size);
+ }
+ _index = 0;
+}
+
+
+void
+Memory::startStats()
+{
+// GNASH_REPORT_FUNCTION;
+ _collecting = true;
+ if (_info == 0) {
+ log_debug("Allocating buffer for %d data samples",
+ DATALOG_SIZE);
+ _info = new struct small_mallinfo[DATALOG_SIZE];
+ reset();
+ }
+}
+
+int
+Memory::addStats(int line)
+{
+// GNASH_REPORT_FUNCTION;
+ if (_info) {
+ struct small_mallinfo *ptr = _info + _index;
+ addStats(ptr, line);
+ }
+
+ return _index;
+}
+
+int
+Memory::addStats()
+{
+// GNASH_REPORT_FUNCTION;
+ if (_info) {
+ struct small_mallinfo *ptr = _info + _index;
+ addStats(ptr, 0);
+ }
+
+ return _index;
+}
+
+
+int
+Memory::addStats(struct small_mallinfo *ptr)
+{
+// GNASH_REPORT_FUNCTION;
+ return addStats(ptr, 0);
+}
+
+int
+Memory::addStats(struct small_mallinfo *ptr, int line)
+{
+// GNASH_REPORT_FUNCTION;
+ struct mallinfo mal = mallinfo();
+
+// dump(&mal);
+ if ((ptr) && (_index < DATALOG_SIZE)) {
+ ptr->line = line;
+ ptr->arena = mal.arena;
+ ptr->uordblks = mal.uordblks;
+ ptr->fordblks = mal.fordblks;
+ _index++;
+ }
+
+ return _index;
+}
+
+// return true if we haven't leaked any memory
+bool
+Memory::endCheckpoint()
+{
+// GNASH_REPORT_FUNCTION;
+ _checkpoint[1] = mallinfo();
+ if (_checkpoint[1].uordblks == _checkpoint[0].uordblks) {
+ return true;
+ }
+
+ return false;
+}
+
+// Dump the differences of bytes allocated between two samples
+int
+Memory::diffStats()
+{
+// GNASH_REPORT_FUNCTION;
+ return diffStats(_index - 1, _index - 2);
+}
+
+int
+Memory::diffStats(int x, int y)
+{
+// GNASH_REPORT_FUNCTION;
+ if ((_info) && (x < DATALOG_SIZE) && (y < DATALOG_SIZE)) {
+ return (_info[x].uordblks - _info[y].uordblks);
+ }
+ return -1;
+}
+
+
+// Analyze memory usage
+bool
+Memory::analyze()
+{
+// GNASH_REPORT_FUNCTION;
+
+ int accumulate_allocated = 0;
+ int accumulate_freed = 0;
+
+ // System memory is what we get from brk(), the lowest level
+ // system call used by both malloc() or new().
+ cerr << endl << "System memory allocated in bytes: "
+ << _info->arena << endl;
+ int diff_arena = (_info + _index - 1)->arena - _info->arena;
+ if (diff_arena) {
+ cerr << "System memory change in bytes: " << diff_arena << endl;
+ }
+
+ int total_allocated = (_info + _index - 1)->uordblks - _info->uordblks;
+ cerr << "Total bytes allocated: " << total_allocated << endl;
+
+ if (_index > 1) {
+ for (int i=1; i<_index; i++) {
+ // See what was allocated between samples
+ struct small_mallinfo *ptr = _info + i;
+ int diff_allocated = (ptr->uordblks) - (ptr - 1)->uordblks;
+ if (diff_allocated > 0) {
+ accumulate_allocated += diff_allocated;
+ if (ptr->line && (ptr - 1)->line) {
+ cerr << "Allocated " << diff_allocated
+ << " bytes Between lines: " << (ptr - 1)->line
+ << " and " << ptr->line << endl;
+ } else {
+ cerr << "Allocated bytes: " << diff_allocated << endl;
+ }
+// same as diff_freed
+// } else {
+// if (diff_allocated != 0) {
+// cerr << "\tnew heap bytes: " << diff_allocated << endl;
+// }
+ }
+
+ // See what was freed between samples
+ int diff_freed = ptr->fordblks - (ptr - 1)->fordblks;
+ if (diff_freed > 0) {
+ accumulate_freed += diff_freed;
+ if (ptr->line && (ptr - 1)->line) {
+ cerr << "Freed " << diff_freed
+ << " bytes Between lines: " << (ptr - 1)->line
+ << " and " << ptr->line << endl;
+ } else {
+ cerr << "Freed bytes: " << diff_freed << endl;
+ }
+// Same as diif_allocated
+// } else {
+// if (diff_freed != 0) {
+// cerr << "\tnuked heap bytes: " << diff_freed << endl;
+// }
+ }
+ }
+ } else {
+ cerr << "Only have one sample" << endl;
+ dump();
+ }
+
+ // Sanity check on our calculations
+ if (total_allocated != (accumulate_allocated - accumulate_freed)) {
+ log_error("Calculations don't equal");
+ } else {
+ log_debug("Zero memory leaks for this program");
+ }
+ if ((_checkpoint[0].uordblks != 0) && (_checkpoint[1].uordblks != 0)) {
+ if (_checkpoint[1].uordblks == _checkpoint[0].uordblks) {
+ cerr << "The last checkpoint status was: "
+ << ((_checkpoint[1].uordblks == _checkpoint[0].uordblks)
+ ? "passed" : "failed") << endl;
+ }
+ }
+}
+
+
+// Dump the vector of stored classes
+void
+Memory::dump(struct mallinfo *ptr)
+{
+// GNASH_REPORT_FUNCTION;
+ cerr << "\tstruct mallinfo: Non-mmapped space allocated from system is: \""
+ << ptr->arena << "\"" << endl;
+ cerr << "\tstruct mallinfo: Total allocated space is: \""
+ << ptr->uordblks << "\"" << endl;
+ cerr << "\tstruct mallinfo: Total free space is: \""
+ << ptr->fordblks << "\"" << endl;
+}
+
+// Dump the vector of stored classes
+void
+Memory::dump(struct small_mallinfo *ptr)
+{
+// GNASH_REPORT_FUNCTION;
+ cerr << "\tLine number of sample: " << ptr->line << endl;
+ cerr << "\tNon-mmapped space allocated from system is: \""
+ << ptr->arena << "\"" << endl;
+ cerr << "\tTotal allocated space is: \""
+ << ptr->uordblks << "\"" << endl;
+ cerr << "\tTotal free space is: \""
+ << ptr->fordblks << "\"" << endl;
+}
+
+void
+Memory::dump()
+{
+// GNASH_REPORT_FUNCTION;
+
+ for (int i=0; i<_index; i++) {
+ cerr << "Mallinfo index: " << i << endl;
+ dump(_info + i);
+ }
+}
+
+} // end of gnash namespace
+
+#endif // end of HAVE_MALLINFO
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:
Index: testsuite/libbase/memtest.cpp
===================================================================
RCS file: testsuite/libbase/memtest.cpp
diff -N testsuite/libbase/memtest.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/libbase/memtest.cpp 7 Mar 2008 01:02:20 -0000 1.1
@@ -0,0 +1,177 @@
+//
+// Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include <vector>
+#include <string>
+
+#include "log.h"
+#include "memory.h"
+
+#ifdef HAVE_DEJAGNU_H
+#include "dejagnu.h"
+#else
+#include "check.h"
+#endif
+
+TestState runtest;
+
+long *test_leak();
+long *test_noleak();
+
+using namespace std;
+using namespace gnash;
+
+const int INTARRAYSIZE = 10;
+
+int
+main (int /*argc*/, char** /*argv*/) {
+ RcInitFile& rc = RcInitFile::getDefaultInstance();
+
+ LogFile& dbglogfile = LogFile::getDefaultInstance();
+ dbglogfile.setVerbosity();
+
+ int diff = 0;
+
+ // Parse the test config file
+ if (rc.parseFile("gnashrc")) {
+ runtest.pass ("rc.parseFile()");
+ } else {
+ runtest.fail ("rc.parseFile()");
+ }
+
+// If we don't have support for mallinfo(), this code is useless
+#if HAVE_MALLINFO
+ Memory mem;
+
+ mem.startStats();
+ mem.addStats(__LINE__); // take a sample
+ mem.addStats(__LINE__); // take a sample
+ diff = mem.diffStats();
+ if (mem.diffStats() == 0) {
+ runtest.pass("No allocations yet");
+ } else {
+ runtest.fail("No allocations yet");
+ }
+
+ Memory m1;
+ mem.addStats(__LINE__); // take a sample
+ diff = mem.diffStats();
+ if (diff == 16) {
+ runtest.pass("Memory");
+ } else {
+ runtest.fail("Memory");
+ }
+
+ char *x = new char[120];
+ mem.addStats(__LINE__); // take a sample
+ if (mem.diffStats() == 104) {
+ runtest.pass("Buffer allocation");
+ } else {
+ runtest.fail("Buffer allocation");
+ }
+
+ vector<string> sv;
+ sv.push_back("Hello World");
+ mem.addStats(__LINE__); // take a sample
+ if (mem.diffStats() == 64) {
+ runtest.pass("First string allocated");
+ } else {
+ runtest.fail("First string allocated");
+ }
+
+ sv.push_back("Aloha");
+ delete x;
+ mem.addStats(__LINE__); // take a sample
+ if (mem.diffStats() == -104) {
+ runtest.pass("Second string allocated");
+ } else {
+ runtest.fail("Second string allocated");
+ }
+
+ sv.push_back("Guten Tag");
+ mem.addStats(__LINE__); // take a sample
+ if (mem.diffStats() == 40) {
+ runtest.pass("Third string allocated");
+ } else {
+ runtest.fail("Third string allocated");
+ }
+
+ mem.startCheckpoint();
+ test_leak();
+ if (mem.endCheckpoint()) {
+ runtest.fail("leak");
+ } else {
+ runtest.pass("leak");
+ }
+ mem.addStats(__LINE__); // take a sample
+ if (mem.diffStats() == 40) {
+ runtest.pass("test_leak");
+ } else {
+ runtest.fail("test_leak");
+ }
+
+ mem.startCheckpoint();
+ test_noleak();
+ mem.addStats(__LINE__); // take a sample
+ if (mem.endCheckpoint()) {
+ runtest.pass("noleak");
+ } else {
+ runtest.fail("noleak");
+ }
+ if (mem.diffStats() == 0) {
+ runtest.pass("test_noleak");
+ } else {
+ runtest.fail("test_noleak");
+ }
+
+
+ mem.endStats();
+
+// mem.dump();
+
+ mem.analyze();
+#else
+ runtest.untested("No support for mallinfo()");
+#endif // end of HAVE_MALLINFO
+}
+
+// Allocate memory and forget to clean it up.
+long *
+test_leak()
+{
+ long *x = new long[INTARRAYSIZE];
+ for (int i=0; i<INTARRAYSIZE; i++) {
+ x[i] = i;
+ }
+ return x;
+}
+
+// Clean up after the other testcase
+long *
+test_noleak()
+{
+ long *x = test_leak();
+ delete x;
+
+ return 0;
+}
+
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] gnash libbase/Makefile.am testsuite/libbase/Mak...,
Rob Savoye <=