~ubuntu-branches/ubuntu/raring/clucene-core/raring-proposed

« back to all changes in this revision

Viewing changes to src/CLucene/debug/memtracking.cpp

  • Committer: Package Import Robot
  • Author(s): Fathi Boudra
  • Date: 2012-08-11 09:33:38 UTC
  • mfrom: (1.1.5)
  • Revision ID: package-import@ubuntu.com-20120811093338-fgrx41ftqew3qt6a
Tags: 2.3.3.4-1
* New upstream release (Closes: #661703).
* Convert package to multiarch.
* Drop obsolete patches:
  - 01_add_missing_include_bug505667.diff
  - 02_posixness_fix_bug530308.diff
* Add patches:
  - Fixing_ZLIB_configuration_in_shared_CMakeLists.patch
  - Fix-pkgconfig-file-by-adding-clucene-shared-library.patch
  - Install-contribs-lib.patch
  - multiarch.patch
* Update debian/compat: bump to 8.
* Update debian/control:
  - update build dependencies (add cmake, libboost-dev and libz-dev).
  - bump Standards-Version to 3.9.3.
  - rename packages due to ABI bump: libclucene0ldbl -> libclucene-core1.
  - add libclucene-contribs1 package.
* Update debian/rules:
  - rewrite to use CMake.
  - add multiarch support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*------------------------------------------------------------------------------
2
 
* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
3
 
4
 
* Distributable under the terms of either the Apache License (Version 2.0) or 
5
 
* the GNU Lesser General Public License, as specified in the COPYING file.
6
 
------------------------------------------------------------------------------*/
7
 
#include "CLucene/StdHeader.h"
8
 
#include "CLucene/util/Misc.h"
9
 
 
10
 
bool _lucene_disable_debuglogging = true; //if LUCENE_ENABLE_CONSTRUCTOR_LOG is on, dont do log if this is true
11
 
bool _lucene_run_objectcheck = false; //run a memory check before deleting objects
12
 
int _lucene_counter_break = -1; //to break at this item, change this 
13
 
                                                         //and put break points at points below
14
 
 
15
 
CL_NS_USE(util)
16
 
CL_NS_DEF(debug)
17
 
 
18
 
#ifdef LUCENE_ENABLE_MEMLEAKTRACKING
19
 
int32_t _instance_counter = 0; //counter for initnumber
20
 
 
21
 
struct _file{
22
 
   int32_t refcount; ///times this has been used
23
 
   char* value; ///reference to the the basefile
24
 
}; //structure for name counting
25
 
struct _pointers{
26
 
   _file* file;
27
 
   int32_t initline;
28
 
   int32_t initnumber;
29
 
};//structure for pointer-filename references
30
 
 
31
 
typedef CL_NS(util)::CLSet<const char*,_file*,Compare::Char,Deletor::Dummy,Deletor::Void<_file> > defFile;
32
 
typedef CL_NS(util)::CLSet<LuceneBase*,_pointers*,Compare::Void<LuceneBase>,Deletor::Dummy,Deletor::Void<_pointers> > defPointer;
33
 
typedef CL_NS(util)::CLSet<const void*,_pointers*,Compare::Void<const void>,Deletor::Dummy,Deletor::Void<_pointers> > defVoid;
34
 
 
35
 
DEFINE_MUTEX(memleak_lock)
36
 
defFile LuceneBase_Files(false,true); //list of filenames used
37
 
defPointer LuceneBase_Pointers(false,true); //list of pointers counted
38
 
defVoid LuceneBase_Voids(false,true); //list of arbitary data added
39
 
 
40
 
//variables to trim filenames to just the base names
41
 
char _files_trim_string[CL_MAX_DIR];
42
 
int32_t _files_trim_start=-1;
43
 
 
44
 
//trim the filename and return the refcounted _file* structure
45
 
_file* get_file(const char* file){
46
 
        if ( _files_trim_start == -1 ){
47
 
                //this trims the start of the name file name so
48
 
                //that the whole of the filename is not stored - more asthetic :)
49
 
                //need to find the base
50
 
                _files_trim_start = strlen(__FILE__) - 21; //(length of debug/memtracking.cpp)
51
 
                strcpy(_files_trim_string,__FILE__);
52
 
                _files_trim_string[_files_trim_start] = 0;
53
 
        }
54
 
        if ( strncmp(file,_files_trim_string,_files_trim_start) == 0 ){
55
 
                //this file should be within the same directory area as we found lucenebase.cpp
56
 
                //to be, lets trim the start
57
 
                file+=_files_trim_start;
58
 
        }
59
 
 
60
 
   //now return an existing files structure (with refcount++) or create a new one
61
 
   defFile::iterator itr = LuceneBase_Files.find((const char*)file);
62
 
   if ( itr != LuceneBase_Files.end() ){
63
 
      _file* bf = itr->second;
64
 
      bf->refcount++;
65
 
      return bf;
66
 
   }else{
67
 
      _file* ref = new _file;
68
 
      ref->value = new char[strlen(file)+1]; //cannot use _CL_NEWARRAY otherwise recursion
69
 
          strcpy(ref->value,file);
70
 
 
71
 
      ref->refcount = 1;
72
 
          LuceneBase_Files.insert(pair<const char*,_file*>(ref->value,ref));
73
 
          return ref;
74
 
   }
75
 
}
76
 
 
77
 
void remove_file(_file* bf){
78
 
        bf->refcount--;
79
 
    if ( bf->refcount <= 0 ){
80
 
                        defFile::iterator fi = LuceneBase_Files.find(bf->value);
81
 
                        CND_PRECONDITION(fi!=LuceneBase_Files.end(),"fi==NULL");
82
 
                        delete[] bf->value;
83
 
            LuceneBase_Files.removeitr(fi);
84
 
    }
85
 
}
86
 
 
87
 
#ifdef LUCENE_ENABLE_CONSTRUCTOR_LOG
88
 
        void constructor_log(const char* type,const char* file,const int line, const int size){
89
 
                if ( _lucene_disable_debuglogging ){
90
 
                        FILE* f = fopen("clucene.log","a");
91
 
                        char buf[CL_MAX_DIR+5];
92
 
                        sprintf(buf,"%s,%s,%d,%d\n",type,file,line,size);
93
 
                        fwrite(buf,sizeof(char),strlen(buf),f);
94
 
                        fclose(f);
95
 
                }
96
 
        }
97
 
        #define CONSTRUCTOR_LOG(type,file,line,size) constructor_log(type,file,line,size)
98
 
#else
99
 
        #define CONSTRUCTOR_LOG(type,file,line,size)
100
 
#endif
101
 
 
102
 
////////////////////////////////////////////////////////////////////////////////
103
 
// the _CLNEW&_CLDELETE new/delete operators
104
 
////////////////////////////////////////////////////////////////////////////////
105
 
void* LuceneBase::operator new (size_t size, const char * file, int32_t line)
106
 
{
107
 
   SCOPED_LOCK_MUTEX(memleak_lock)
108
 
 
109
 
   void* p = malloc (size);
110
 
   LuceneBase* lb = (LuceneBase*)p;
111
 
 
112
 
   //create the pointer struct
113
 
   _file* br = get_file(file);
114
 
   _pointers* bp = new _pointers;
115
 
   bp->file = br;
116
 
   bp->initnumber = _instance_counter++;
117
 
   bp->initline = line;
118
 
 
119
 
   //associate this object with the pointer
120
 
   lb->__cl_initnum = bp->initnumber;
121
 
 
122
 
   //break if necessary
123
 
        if ( _lucene_counter_break == lb->__cl_initnum )
124
 
                CLDebugBreak(); //put break point here
125
 
 
126
 
        //add the pointer object
127
 
        LuceneBase_Pointers.insert(pair<LuceneBase*,_pointers*>(lb, bp));
128
 
 
129
 
        CONSTRUCTOR_LOG("newobj",file,line,size);
130
 
   return p;
131
 
132
 
void LuceneBase::operator delete (void *p, char const * file, int32_t line)
133
 
{
134
 
        SCOPED_LOCK_MUTEX(memleak_lock)
135
 
 
136
 
        LuceneBase* lb=(LuceneBase*)p;
137
 
 
138
 
        defPointer::iterator itr = LuceneBase_Pointers.find(lb);
139
 
    if ( itr != LuceneBase_Pointers.end() ){
140
 
      _pointers* bp = itr->second;
141
 
          remove_file(bp->file);
142
 
 
143
 
      LuceneBase_Pointers.removeitr(itr);
144
 
    }else{
145
 
       //break
146
 
    }
147
 
        free(p); 
148
 
149
 
 
150
 
///////////////////////////////////////////////////////////////////////////
151
 
// the generic new/delete operators
152
 
///////////////////////////////////////////////////////////////////////////
153
 
void* LuceneBase::operator new (size_t size)
154
 
{
155
 
        SCOPED_LOCK_MUTEX(memleak_lock)
156
 
 
157
 
        void* p = malloc (size);
158
 
        LuceneBase* lb = (LuceneBase*)p;
159
 
 
160
 
        //create the pointer struct
161
 
   _file* br = get_file("undefined");
162
 
   _pointers* bp = new _pointers;
163
 
   bp->file = br;
164
 
   bp->initnumber = _instance_counter++;
165
 
   bp->initline = -1;
166
 
 
167
 
   //associate this object with the pointer
168
 
   lb->__cl_initnum = bp->initnumber;
169
 
 
170
 
   //break if necessary
171
 
        if ( _lucene_counter_break == lb->__cl_initnum )
172
 
                CLDebugBreak();
173
 
 
174
 
        //add the pointer object
175
 
        LuceneBase_Pointers.insert(pair<LuceneBase*,_pointers*>(lb,bp));
176
 
        
177
 
        CONSTRUCTOR_LOG("newobj","unknown",-1,size);
178
 
   return p;
179
 
180
 
void LuceneBase::operator delete (void *p)
181
 
{
182
 
        SCOPED_LOCK_MUTEX(memleak_lock)
183
 
 
184
 
        LuceneBase* lb=(LuceneBase*)p;
185
 
 
186
 
        defPointer::iterator itr = LuceneBase_Pointers.find(lb);
187
 
        if ( itr != LuceneBase_Pointers.end() ){
188
 
                _pointers* bp = itr->second;
189
 
                remove_file(bp->file);
190
 
                LuceneBase_Pointers.removeitr(itr);
191
 
        }else{
192
 
                CLDebugBreak();
193
 
        }
194
 
        free(p); 
195
 
}
196
 
 
197
 
///////////////////////////////////////////////////////////////////////////
198
 
// other memtracking functions
199
 
///////////////////////////////////////////////////////////////////////////
200
 
void LuceneBase::__cl_unregister(const void* obj){
201
 
        SCOPED_LOCK_MUTEX(memleak_lock)
202
 
 
203
 
        LuceneBase* lb=(LuceneBase*)obj;
204
 
        defPointer::iterator itr = LuceneBase_Pointers.find(lb);
205
 
        CND_PRECONDITION(itr != LuceneBase_Pointers.end(),"__cl_unregister object not found");
206
 
        _pointers* bp = itr->second;
207
 
    LuceneBase_Pointers.removeitr(itr);
208
 
}
209
 
 
210
 
void* LuceneBase::__cl_voidpadd(void* data, const char* file, int line,size_t size){
211
 
        SCOPED_LOCK_MUTEX(memleak_lock)
212
 
 
213
 
        _file* br = get_file(file);
214
 
        _pointers* bp = new _pointers;
215
 
        bp->file = br;
216
 
        bp->initnumber = _instance_counter++;
217
 
        bp->initline = line;
218
 
 
219
 
        LuceneBase_Voids.insert(pair<void*,_pointers*>(data,bp));
220
 
        CONSTRUCTOR_LOG("newarr",file,line,size);
221
 
        return data;
222
 
}
223
 
void LuceneBase::__cl_voidpremove(const void* data, const char* file, int line){
224
 
        SCOPED_LOCK_MUTEX(memleak_lock)
225
 
        defVoid::iterator itr = LuceneBase_Voids.find(data);
226
 
    if ( itr != LuceneBase_Voids.end() ){
227
 
      _pointers* bp = itr->second;
228
 
      remove_file(bp->file);
229
 
      LuceneBase_Voids.removeitr(itr);
230
 
    }else{
231
 
       printf("Data deleted when not added with _CL_NEWARRAY in %s at %d\n",file,line);
232
 
    } 
233
 
}
234
 
 
235
 
 
236
 
////////////////////////////////////////////////////////////
237
 
 
238
 
 
239
 
////////////////////////////////////////////////////////////
240
 
//The lucene base memory leak printout functions
241
 
////////////////////////////////////////////////////////////
242
 
//static
243
 
void __internalcl_PrintUnclosedObject(bool isObject, string& sb,_pointers* bp,_file* bf, bool print){
244
 
        TCHAR ttmp[100];
245
 
        char atmp[100];
246
 
        
247
 
        sb.append("   ");
248
 
        {
249
 
                _i64tot(bp->initnumber,ttmp,10);
250
 
                STRCPY_TtoA(atmp,ttmp,100);
251
 
                sb.append(atmp);
252
 
        }
253
 
        if ( isObject ){
254
 
                sb.append("(obj). ");
255
 
        }else{
256
 
                sb.append(". ");
257
 
        }
258
 
        sb.append(bf->value);
259
 
        sb.append(", line ");
260
 
        {
261
 
                _i64tot(bp->initline,ttmp,10);
262
 
                STRCPY_TtoA(atmp,ttmp,100);
263
 
                sb.append(atmp);
264
 
        }
265
 
        sb.append("\n");
266
 
 
267
 
        if ( print && sb.length() > 0 ){
268
 
                printf("%s\n", sb.c_str());
269
 
                sb = "";
270
 
        }
271
 
}
272
 
char* __internalcl_GetUnclosedObjects(bool print){
273
 
        TCHAR ttmp[100];
274
 
        char atmp[100];
275
 
        SCOPED_LOCK_MUTEX(memleak_lock)
276
 
 
277
 
        string sb;
278
 
    bool unknowns = false;
279
 
        if ( LuceneBase_Pointers.size() > 0 ){
280
 
                {
281
 
                        _i64tot(LuceneBase_Pointers.size(),ttmp,10);
282
 
                        STRCPY_TtoA(atmp,ttmp,100);
283
 
                        sb.append(atmp);
284
 
                }
285
 
                sb.append(" clucene objects are still open\n");
286
 
 
287
 
                defPointer::iterator itr = LuceneBase_Pointers.begin();
288
 
                while ( itr != LuceneBase_Pointers.end() ){
289
 
                        _pointers* bp = itr->second;
290
 
                        _file* bf = bp->file;
291
 
 
292
 
                        if ( bp->initline == -1 )
293
 
                                unknowns = true;
294
 
                        __internalcl_PrintUnclosedObject(true, sb,bp,bf,print);
295
 
 
296
 
                        ++itr;
297
 
                }
298
 
 
299
 
                defVoid::iterator itr2 = LuceneBase_Voids.begin();
300
 
                while ( itr2 != LuceneBase_Voids.end() ){
301
 
                        _pointers* bp = itr2->second;
302
 
                        _file* bf = bp->file;
303
 
 
304
 
                        if ( bp->initline == -1 )
305
 
                                unknowns = true;
306
 
                        __internalcl_PrintUnclosedObject(false, sb,bp,bf,print);
307
 
 
308
 
                        itr2++;
309
 
                }
310
 
        }       
311
 
 
312
 
        if ( unknowns == true ){
313
 
                sb.append("*** Some memory was not created with _CLNEW and was not tracked... ***\n");
314
 
                sb.append("*** Use _CLNEW instead of new when creating CLucene objects ***\n");
315
 
                sb.append("*** Memory may also have not been freed in the current context ***\n");
316
 
        }
317
 
        
318
 
        if ( print ){
319
 
                if ( sb.length() > 0 ){
320
 
                        printf("%s\n", sb.c_str());
321
 
                        sb = "";
322
 
                }
323
 
                return NULL;
324
 
        }else{
325
 
                if ( sb.length() > 0 )
326
 
                        return STRDUP_AtoA(sb.c_str());
327
 
                else
328
 
                        return NULL;
329
 
        }
330
 
}
331
 
 
332
 
void LuceneBase::__cl_ClearMemory(){
333
 
        SCOPED_LOCK_MUTEX(memleak_lock)
334
 
 
335
 
        while ( LuceneBase_Files.size() > 0 ){
336
 
                defFile::iterator fi = LuceneBase_Files.begin();
337
 
                _file* f = fi->second;
338
 
                delete[] f->value;
339
 
        LuceneBase_Files.removeitr (fi);
340
 
        }
341
 
   LuceneBase_Pointers.clear();
342
 
   LuceneBase_Voids.clear();
343
 
}
344
 
char* LuceneBase::__cl_GetUnclosedObjects(){
345
 
        return __internalcl_GetUnclosedObjects(false);
346
 
}
347
 
//static
348
 
int32_t LuceneBase::__cl_GetUnclosedObjectsCount(){
349
 
    return LuceneBase_Pointers.size();
350
 
}
351
 
 
352
 
const char* LuceneBase::__cl_GetUnclosedObject(int32_t item){
353
 
        SCOPED_LOCK_MUTEX(memleak_lock)
354
 
 
355
 
   defPointer::iterator itr=LuceneBase_Pointers.begin();
356
 
   int32_t i=0;
357
 
   for ( ;itr!=LuceneBase_Pointers.end() && i<item ;itr++ ){
358
 
      ++i;
359
 
   }
360
 
   if ( itr != LuceneBase_Pointers.end() )
361
 
      return itr->second->file->value;
362
 
   else
363
 
      return NULL;
364
 
}
365
 
void LuceneBase::__cl_PrintUnclosedObjects(){
366
 
        __internalcl_GetUnclosedObjects(true);
367
 
}
368
 
////////////////////////////////////////////////////////////
369
 
 
370
 
#endif //LUCENE_ENABLE_MEMLEAKTRACKING
371
 
CL_NS_END