1 /* Copyright (c) MediaArea.net SARL. All Rights Reserved.
2 *
3 * Use of this source code is governed by a zlib-style license that can
4 * be found in the License.txt file in the root of the source tree.
5 */
6
7 //---------------------------------------------------------------------------
8 #include "ZenLib/PreComp.h"
9 #ifdef __BORLANDC__
10 #pragma hdrstop
11 #endif
12 //---------------------------------------------------------------------------
13
14 //---------------------------------------------------------------------------
15 #include "ZenLib/Conf_Internal.h"
16 //---------------------------------------------------------------------------
17
18 //---------------------------------------------------------------------------
19 #if defined(ZENLIB_DEBUG)
20 //---------------------------------------------------------------------------
21 #include <iomanip>
22 #include <sstream>
23 #include "ZenLib/MemoryDebug.h"
24 #include "ZenLib/Ztring.h"
25 #ifdef WINDOWS
26 #include <io.h>
27 #else
28 #include <cstdio>
29 #endif
30 #include <fcntl.h>
31 #include <sys/stat.h>
32 using namespace std;
33 //---------------------------------------------------------------------------
34
35 namespace ZenLib
36 {
37
38 bool MemoryDebug::g_IsShutdown = false;
39 //***************************************************************************
40 // Constructors/destructor
41 //***************************************************************************
42
MemoryDebug()43 MemoryDebug::MemoryDebug()
44 {
45 }
46
~MemoryDebug()47 MemoryDebug::~MemoryDebug()
48 {
49 if (!m_Blocks.empty())
50 ReportLeaks();
51 g_IsShutdown = true;
52 }
53
54 //***************************************************************************
55 // Instance
56 //***************************************************************************
57
Instance()58 MemoryDebug& MemoryDebug::Instance()
59 {
60 static MemoryDebug Inst;
61 return Inst;
62 }
63
64 //***************************************************************************
65 // Reports
66 //***************************************************************************
67
ReportLeaks()68 void MemoryDebug::ReportLeaks()
69 {
70 Ztring m_File;
71 //std::ofstream m_File ("Debug_MemoryLeak.txt"); // Fichier de sortie
72
73 // D�tail des fuites
74 std::size_t TotalSize = 0;
75 for (TBlockMap::iterator i = m_Blocks.begin(); i != m_Blocks.end(); ++i)
76 {
77 // Ajout de la taille du bloc au cumul
78 TotalSize += i->second.Size;
79
80 // Inscription dans le fichier des informations sur le bloc courant
81 /*
82 m_File << "-> 0x" << std::hex << i->first << std::dec
83 << " | " << std::setw(7) << std::setfill(' ') << static_cast<int>(i->second.Size) << " bytes"
84 << " | " << i->second.File.c_str() << " (" << i->second.Line << ")" << std::endl;
85 */
86 m_File.append(__T("-> 0x"));
87 m_File.append(Ztring::ToZtring((size_t)i->first, 16));
88 m_File.append(__T(" | "));
89 Ztring Temp;
90 Temp.From_Number(static_cast<int>(i->second.Size));
91 while(Temp.size()<7)
92 Temp=__T(" ")+Temp;
93 m_File.append(Temp);
94 m_File.append(__T(" bytes"));
95 m_File.append(__T(" | "));
96 m_File.append(Ztring().From_Local(i->second.File.c_str()));
97 m_File.append(__T(" ("));
98 m_File.append(Ztring::ToZtring(i->second.Line));
99 m_File.append(__T(")"));
100 m_File.append(EOL);
101 }
102
103 // Affichage du cumul des fuites
104 /*
105 m_File << std::endl << std::endl << "-- "
106 << static_cast<int>(m_Blocks.size()) << " non-released blocs, "
107 << static_cast<int>(TotalSize) << " bytes --"
108 << std::endl;
109 */
110 m_File.append(EOL);
111 m_File.append(EOL);
112 m_File.append(__T("-- "));
113 m_File.append(Ztring::ToZtring(static_cast<int>(m_Blocks.size())));
114 m_File.append(__T(" non-released blocs, "));
115 m_File.append(Ztring::ToZtring(static_cast<int>(TotalSize)));
116 m_File.append(__T(" bytes --"));
117 m_File.append(EOL);
118
119 std::string ToWrite=m_File.To_Local().c_str();
120 int m_File_sav=open("Debug_MemoryLeak.txt", O_BINARY|O_RDWR |O_CREAT); // Fichier de sortie
121 write(m_File_sav, (int8u*)ToWrite.c_str(), ToWrite.size());
122 close(m_File_sav);
123 }
124
125 //***************************************************************************
126 // Memory management
127 //***************************************************************************
128
Allocate(std::size_t Size,const char * File,int Line,bool Array)129 void* MemoryDebug::Allocate(std::size_t Size, const char* File, int Line, bool Array)
130 {
131 // Allocation de la m�moire
132 void* Ptr = malloc(Size);
133
134 // Ajout du bloc � la liste des blocs allou�s
135 TBlock NewBlock;
136 NewBlock.Size = Size;
137 NewBlock.File = File;
138 NewBlock.Line = Line;
139 NewBlock.Array = Array;
140 m_Blocks[Ptr] = NewBlock;
141 return Ptr;
142 }
143
Free(void * Ptr,bool Array)144 void MemoryDebug::Free(void* Ptr, bool Array)
145 {
146 // Recherche de l'adresse dans les blocs allou�s
147 TBlockMap::iterator It = m_Blocks.find(Ptr);
148
149 // Si le bloc n'a pas �t� allou�, on g�n�re une erreur
150 if (It == m_Blocks.end())
151 {
152 // En fait �a arrive souvent, du fait que le delete surcharge est pris en compte meme la ou on n'inclue pas DebugNew.h,
153 // mais pas la macro pour le new
154 // Dans ce cas on d�truit le bloc et on quitte imm�diatement
155 free(Ptr);
156 return;
157 }
158
159 // Si le type d'allocation ne correspond pas, on g�n�re une erreur
160 if (It->second.Array != Array)
161 {
162 //throw CBadDelete(Ptr, It->second.File.c_str(), It->second.Line, !Array);
163 }
164
165 // Finalement, si tout va bien, on supprime le bloc et on loggiz tout �a
166 m_Blocks.erase(It);
167 m_DeleteStack.pop();
168
169 // Lib�ration de la m�moire
170 free(Ptr);
171 }
172
NextDelete(const char * File,int Line)173 void MemoryDebug::NextDelete(const char* File, int Line)
174 {
175 TBlock Delete;
176 Delete.File = File;
177 Delete.Line = Line;
178
179 m_DeleteStack.push(Delete);
180 }
181
182 //***************************************************************************
183 //
184 //***************************************************************************
185
186 } //NameSpace
187
188 #endif // defined(ZENLIB_DEBUG)
189