Update ooo320-m1
[ooovba.git] / tools / source / debug / stcktree.cxx
blobcdfa807b4bd695ff2d9872c91e24148c9069388a
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: stcktree.cxx,v $
10 * $Revision: 1.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_tools.hxx"
34 #include <string.h>
36 #include <tools/debug.hxx>
38 // -----------------------------------------------------------------------
40 #if defined( DBG_UTIL ) && defined( WNT ) && defined( INTEL )
42 struct ImpDbgStackTree
44 ImpDbgStackTree* pLeft_;
45 ImpDbgStackTree* pRight_;
46 ImpDbgStackTree* pCaller_;
47 ImpDbgStackTree* pSub_;
48 ULONG nIP_;
49 ULONG nBytesLeak_;
50 ULONG nBytesPeak_;
51 ULONG nBytes_;
52 ULONG nCountLeak_;
53 ULONG nCountPeak_;
54 ULONG nCount_;
55 ULONG nMax_;
56 ULONG nMin_;
58 ImpDbgStackTree( ImpDbgStackTree* pSub, ULONG nIP );
59 ~ImpDbgStackTree();
61 ImpDbgStackTree* Add( ULONG nAlloc, ULONG* pBP, ULONG nIP );
62 void Print( int nLevel, ULONG nCount, ULONG nCountLeak );
63 void Print( int nLevel );
66 static ImpDbgStackTree* pImpDbgStackTreeRoot = NULL;
67 static ULONG* pImpDbgStackTreeBP = NULL;
68 static ULONG nImpDbgStackTreeMain = 0;
69 static int nImpDbgStackTreeSem = 0;
71 // -----------------------------------------------------------------------
73 ImpDbgStackTree::ImpDbgStackTree( ImpDbgStackTree* pSub, ULONG nIP )
75 pSub_ = pSub;
76 nIP_ = nIP;
77 pLeft_ = pRight_ = pCaller_ = NULL;
78 nBytesLeak_ = nBytesPeak_ = nBytes_ = 0;
79 nCountLeak_ = nCountPeak_ = nCount_ = 0;
82 // -----------------------------------------------------------------------
84 ImpDbgStackTree::~ImpDbgStackTree()
86 if ( pLeft_ )
87 delete pLeft_;
88 if ( pRight_ )
89 delete pRight_;
90 if ( pCaller_ )
91 delete pCaller_;
94 // -----------------------------------------------------------------------
96 void ImpDbgStackTree::Print( int nLevel, ULONG nCount, ULONG nCountLeak )
98 if ( pLeft_ )
99 pLeft_->Print( nLevel, nCount, nCountLeak );
101 if ( nCount_ >= nCount && nCountLeak_ >= nCountLeak )
103 if ( nMax_ == nMin_ )
105 ULONG nTemp = nCountLeak_ * nMin_;
106 DbgOutf( "%*c%08lx Count=%lu/%lu/%lu Bytes=%lu/%lu/%lu Size=%lu",
107 nLevel, ' ', nIP_,
108 nCount_, nCountPeak_, nCountLeak_,
109 nBytes_, nBytesPeak_, nTemp,
110 nMin_ );
112 else
114 DbgOutf( "%*c%08lx Count=%lu/%lu/%lu Bytes=%lu/%lu/%lu Size=%lu-%lu",
115 nLevel, ' ', nIP_,
116 nCount_, nCountPeak_, nCountLeak_,
117 nBytes_, nBytesPeak_, nBytesLeak_,
118 nMin_, nMax_ );
121 if ( pCaller_ )
122 if( nLevel > 3 && nCountLeak )
123 pCaller_->Print( nLevel + 1, nCount, 1 );
124 else
125 pCaller_->Print( nLevel + 1, nCount, nCountLeak );
128 if ( pRight_ )
129 pRight_->Print( nLevel, nCount, nCountLeak );
132 // -----------------------------------------------------------------------
134 void ImpDbgStackTree::Print( int nLevel )
136 if ( pSub_ )
137 pSub_->Print( nLevel + 1 );
138 DbgOutf( "%*c%08lx", nLevel, ' ',nIP_ );
141 // -----------------------------------------------------------------------
143 ImpDbgStackTree* ImpDbgStackTree::Add( ULONG nAlloc, ULONG *pBP, ULONG nIP )
145 if ( nIP < nIP_ )
147 if ( !pLeft_ )
148 pLeft_ = new ImpDbgStackTree( pSub_, nIP );
149 return pLeft_->Add( nAlloc, pBP, nIP );
151 if ( nIP > nIP_ )
153 if ( !pRight_ )
154 pRight_ = new ImpDbgStackTree( pSub_, nIP );
155 return pRight_->Add( nAlloc, pBP, nIP );
158 nCount_++;
159 nCountLeak_++;
160 if ( nCountLeak_ > nCountPeak_ )
161 nCountPeak_ = nCountLeak_;
162 nBytes_ += nAlloc;
163 nBytesLeak_ += nAlloc;
164 if ( nBytesLeak_ > nBytesPeak_ )
165 nBytesPeak_ = nBytesLeak_;
166 if ( nCount_ == 1 )
167 nMax_ = nMin_ = nAlloc;
168 else if ( nMax_ < nAlloc )
169 nMax_ = nAlloc;
170 else if ( nMin_ > nAlloc )
171 nMin_ = nAlloc;
173 if ( !(pBP[0] & 3) && (ULONG)pBP < pBP[0] && pBP[0] < (ULONG)pImpDbgStackTreeBP )
175 pBP = (ULONG*)pBP[0];
176 nIP = pBP[1];
177 if ( 0x01100000 <= nIP && nIP < 0x20000000 && nIP != nImpDbgStackTreeMain )
179 if ( !pCaller_ )
180 pCaller_ = new ImpDbgStackTree( this, nIP );
181 return pCaller_->Add( nAlloc, pBP, nIP );
183 else
184 return this;
187 return this;
190 // -----------------------------------------------------------------------
192 void DbgStartStackTree()
194 if ( !nImpDbgStackTreeMain )
196 ULONG* pBP;
197 __asm mov pBP, ebp;
199 pImpDbgStackTreeBP = (ULONG*)pBP[0];
200 nImpDbgStackTreeMain = pImpDbgStackTreeBP[1];
204 // -----------------------------------------------------------------------
206 void DbgEndStackTree()
208 if ( nImpDbgStackTreeMain )
210 nImpDbgStackTreeMain = 0;
211 if ( pImpDbgStackTreeRoot )
213 // Ausgaben ins File umleiten
214 DbgData* pData = DbgGetData();
215 ULONG nOldOut = pData->nTraceOut;
216 pData->nTraceOut = DBG_OUT_FILE;
218 DbgOutf( "Leak-Report" );
219 DbgOutf( "===========" );
220 DbgOutf( "Mem-StackTree:" );
221 DbgOutf( "{" );
222 pImpDbgStackTreeRoot->Print( 1, 1, 2 );
223 DbgOutf( "}" );
225 DbgOutf( "Alloc-Report" );
226 DbgOutf( "===========" );
227 DbgOutf( "Mem-StackTree:" );
228 DbgOutf( "{" );
229 pImpDbgStackTreeRoot->Print( 1, 1000, 0 ); // ???
230 DbgOutf( "}" );
232 pData->nTraceOut = nOldOut;
234 nImpDbgStackTreeSem++;
235 delete pImpDbgStackTreeRoot;
236 pImpDbgStackTreeRoot = NULL;
237 nImpDbgStackTreeSem--;
242 // -----------------------------------------------------------------------
244 void* DbgGetStackTree( ULONG nAlloc )
246 ImpDbgStackTree* pReturn = NULL;
248 if ( nImpDbgStackTreeMain && !nImpDbgStackTreeSem )
250 nImpDbgStackTreeSem++;
252 ULONG* pBP;
253 __asm mov pBP, ebp;
255 ULONG nIP = pBP[1];
256 if ( !pImpDbgStackTreeRoot )
257 pImpDbgStackTreeRoot = new ImpDbgStackTree( NULL, nIP );
258 pReturn = pImpDbgStackTreeRoot->Add( nAlloc, pBP, nIP );
259 nImpDbgStackTreeSem--;
262 return pReturn;
265 // -----------------------------------------------------------------------
267 void DbgFreeStackTree( void* pVoid, ULONG nAlloc )
269 ImpDbgStackTree* p = (ImpDbgStackTree*)pVoid;
271 if ( p && nImpDbgStackTreeMain && !nImpDbgStackTreeSem )
273 if ( nAlloc < p->nMin_ )
274 nAlloc = p->nMin_;
276 p->nCountLeak_--;
277 p->nBytesLeak_ -= nAlloc;
279 if ( p->nMax_ && 0xFFFFFFFF / p->nMax_ > p->nCountLeak_ )
281 if ( p->nBytesLeak_ > p->nMax_ * p->nCountLeak_ )
283 nAlloc += p->nBytesLeak_ - p->nMax_ * p->nCountLeak_;
284 p->nBytesLeak_ = p->nMax_ * p->nCountLeak_;
288 if ( p->pSub_ )
289 DbgFreeStackTree( (void*)(p->pSub_), nAlloc );
293 // -----------------------------------------------------------------------
295 void DbgPrintStackTree( void* pVoid )
297 ImpDbgStackTree* p = (ImpDbgStackTree*)pVoid;
299 if ( p && nImpDbgStackTreeMain && !nImpDbgStackTreeSem )
301 // Ausgaben ins File umleiten
302 DbgData* pData = DbgGetData();
303 ULONG nOldOut = pData->nTraceOut;
304 pData->nTraceOut = DBG_OUT_FILE;
306 DbgOutf( "Mem-StackTree:" );
307 DbgOutf( "{" );
308 p->Print( 1 );
309 DbgOutf( "}" );
311 pData->nTraceOut = nOldOut;
315 #else
317 void DbgStartStackTree() {}
318 void DbgEndStackTree() {}
319 void* DbgGetStackTree( ULONG ) { return NULL; }
320 void DbgFreeStackTree( void*, ULONG ) {}
321 void DbgPrintStackTree( void* ) {}
323 #endif