]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/tools/lldb-mi/MICmnLog.cpp
Fix a memory leak in if_delgroups() introduced in r334118.
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / tools / lldb-mi / MICmnLog.cpp
1 //===-- MICmnLog.cpp --------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // In-house headers:
10 #include "MICmnLog.h"
11 #include "MICmnLogMediumFile.h"
12 #include "MICmnResources.h"
13 #include "MIDriverMgr.h"
14 #include "MIUtilDateTimeStd.h"
15
16 //++
17 // Details: CMICmnLog constructor.
18 // Type:    Method.
19 // Args:    None.
20 // Return:  None.
21 // Throws:  None.
22 //--
23 CMICmnLog::CMICmnLog() : m_bEnabled(false), m_bInitializingATM(false) {
24   // Do not use this constructor, use Initialize()
25 }
26
27 //++
28 // Details: CMICmnLog destructor.
29 // Type:    Method.
30 // Args:    None.
31 // Return:  None.
32 // Throws:  None.
33 //--
34 CMICmnLog::~CMICmnLog() { Shutdown(); }
35
36 //++
37 // Details: Initialize resources for *this Logger.
38 // Type:    Method.
39 // Args:    None.
40 // Return:  MIstatus::success - Functional succeeded.
41 //          MIstatus::failure - Functional failed.
42 // Throws:  None.
43 //--
44 bool CMICmnLog::Initialize() {
45   m_clientUsageRefCnt++;
46
47   if (m_bInitialized)
48     return MIstatus::success;
49
50   ClrErrorDescription();
51
52   // Mediums set inside because explicitly initing in MIDriverMain.cpp causes
53   // compile errors with CAtlFile
54   CMICmnLogMediumFile &rFileLog(CMICmnLogMediumFile::Instance());
55   bool bOk = RegisterMedium(rFileLog);
56   if (bOk) {
57     // Set the Log trace file's header
58     const CMIUtilString &rCR(rFileLog.GetLineReturn());
59     CMIUtilDateTimeStd date;
60     CMIUtilString msg;
61     msg = CMIUtilString::Format(
62         "%s\n", CMIDriverMgr::Instance().GetAppVersion().c_str());
63     CMIUtilString logHdr(msg);
64     msg = CMIUtilString::Format(MIRSRC(IDS_LOG_MSG_CREATION_DATE),
65                                 date.GetDate().c_str(), date.GetTime().c_str(),
66                                 rCR.c_str());
67     logHdr += msg;
68     msg =
69         CMIUtilString::Format(MIRSRC(IDS_LOG_MSG_FILE_LOGGER_PATH),
70                               rFileLog.GetFileNamePath().c_str(), rCR.c_str());
71     logHdr += msg;
72
73     bOk = rFileLog.SetHeaderTxt(logHdr);
74
75     // Note log file medium's status is not available until we write at least
76     // once to the file (so just write the title 1st line)
77     m_bInitializingATM = true;
78     CMICmnLog::WriteLog(".");
79     if (!rFileLog.IsOk()) {
80       const CMIUtilString msg(
81           CMIUtilString::Format(MIRSRC(IDS_LOG_ERR_FILE_LOGGER_DISABLED),
82                                 rFileLog.GetErrorDescription().c_str()));
83       CMICmnLog::WriteLog(msg);
84     }
85     m_bInitializingATM = false;
86   }
87
88   m_bInitialized = bOk;
89
90   return bOk;
91 }
92
93 //++
94 // Details: Release resources for *this Logger.
95 // Type:    Method.
96 // Args:    None.
97 // Return:  MIstatus::success - Functional succeeded.
98 //          MIstatus::failure - Functional failed.
99 // Throws:  None.
100 //--
101 bool CMICmnLog::Shutdown() {
102   if (--m_clientUsageRefCnt > 0)
103     return MIstatus::success;
104
105   if (!m_bInitialized)
106     return MIstatus::success;
107
108   ClrErrorDescription();
109
110   const bool bOk = UnregisterMediumAll();
111
112   m_bInitialized = bOk;
113
114   return bOk;
115 }
116
117 //++
118 // Details: Enabled or disable *this Logger from writing any data to registered
119 // clients.
120 // Type:    Method.
121 // Args:    vbYes   - (R) True = Logger enabled, false = disabled.
122 // Return:  MIstatus::success - Functional succeeded.
123 //          MIstatus::failure - Functional failed.
124 // Throws:  None.
125 //--
126 bool CMICmnLog::SetEnabled(const bool vbYes) {
127   m_bEnabled = vbYes;
128
129   return MIstatus::success;
130 }
131
132 //++
133 // Details: Retrieve state whether *this Logger is enabled writing data to
134 // registered clients.
135 // Type:    Method.
136 // Args:    None.
137 // Return:  True = Logger enable.
138 //          False = disabled.
139 // Throws:  None.
140 //--
141 bool CMICmnLog::GetEnabled() const { return m_bEnabled; }
142
143 //++
144 // Details: Unregister all the Mediums registered with *this Logger.
145 // Type:    Method.
146 // Args:    None.
147 // Return:  MIstatus::success - Functional succeeded.
148 //          MIstatus::failure - Functional failed.
149 // Throws:  None.
150 //--
151 bool CMICmnLog::UnregisterMediumAll() {
152   MapMediumToName_t::const_iterator it = m_mapMediumToName.begin();
153   for (; it != m_mapMediumToName.end(); it++) {
154     IMedium *pMedium = (*it).first;
155     pMedium->Shutdown();
156   }
157
158   m_mapMediumToName.clear();
159
160   return MIstatus::success;
161 }
162
163 //++
164 // Details: Register a Medium with *this Logger.
165 // Type:    Method.
166 // Args:    vrMedium    - (R) The medium to register.
167 // Return:  MIstatus::success - Functional succeeded.
168 //          MIstatus::failure - Functional failed.
169 // Throws:  None.
170 //--
171 bool CMICmnLog::RegisterMedium(const IMedium &vrMedium) {
172   if (HaveMediumAlready(vrMedium))
173     return MIstatus::success;
174
175   IMedium *pMedium = const_cast<IMedium *>(&vrMedium);
176   if (!pMedium->Initialize()) {
177     const CMIUtilString &rStrMedName(pMedium->GetName());
178     const CMIUtilString &rStrMedErr(pMedium->GetError());
179     SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LOG_MEDIUM_ERR_INIT),
180                                               rStrMedName.c_str(),
181                                               rStrMedErr.c_str()));
182     return MIstatus::failure;
183   }
184
185   MapPairMediumToName_t pr(pMedium, pMedium->GetName());
186   m_mapMediumToName.insert(pr);
187
188   return MIstatus::success;
189 }
190
191 //++
192 // Details: Query the Logger to see if a medium is already registered.
193 // Type:    Method.
194 // Args:    vrMedium    - (R) The medium to query.
195 // Return:  True - registered.
196 //          False - not registered.
197 // Throws:  None.
198 //--
199 bool CMICmnLog::HaveMediumAlready(const IMedium &vrMedium) const {
200   IMedium *pMedium = const_cast<IMedium *>(&vrMedium);
201   const MapMediumToName_t::const_iterator it = m_mapMediumToName.find(pMedium);
202   return it != m_mapMediumToName.end();
203 }
204
205 //++
206 // Details: Unregister a medium from the Logger.
207 // Type:    Method.
208 // Args:    vrMedium    - (R) The medium to unregister.
209 // Return:  MIstatus::success - Functional succeeded.
210 //          MIstatus::failure - Functional failed.
211 // Throws:  None.
212 //--
213 bool CMICmnLog::UnregisterMedium(const IMedium &vrMedium) {
214   IMedium *pMedium = const_cast<IMedium *>(&vrMedium);
215   m_mapMediumToName.erase(pMedium);
216
217   return MIstatus::success;
218 }
219
220 //++
221 // Details: The callee client uses this function to write to the Logger. The
222 // data to be
223 //          written is given out to all the mediums registered. The verbosity
224 //          type parameter
225 //          indicates to the medium(s) the type of data or message given to it.
226 //          The medium has
227 //          modes of verbosity and depending on the verbosity set determines
228 //          which writes
229 //          go in to the logger.
230 //          The logger must be initialized successfully before a write to any
231 //          registered
232 //          can be carried out.
233 // Type:    Method.
234 // Args:    vData       - (R) The data to write to the logger.
235 //          veType      - (R) Verbosity type.
236 // Return:  MIstatus::success - Functional succeeded.
237 //          MIstatus::failure - Functional failed.
238 // Throws:  None.
239 //--
240 bool CMICmnLog::Write(const CMIUtilString &vData, const ELogVerbosity veType) {
241   if (!m_bInitialized && !m_bInitializingATM)
242     return MIstatus::success;
243   if (m_bRecursiveDive)
244     return MIstatus::success;
245   if (!m_bEnabled)
246     return MIstatus::success;
247
248   m_bRecursiveDive = true;
249
250   MIuint cnt = 0;
251   MIuint cntErr = 0;
252   {
253     MapMediumToName_t::const_iterator it = m_mapMediumToName.begin();
254     while (it != m_mapMediumToName.end()) {
255       IMedium *pMedium = (*it).first;
256       const CMIUtilString &rNameMedium = (*it).second;
257       MIunused(rNameMedium);
258       if (pMedium->Write(vData, veType))
259         cnt++;
260       else
261         cntErr++;
262
263       // Next
264       ++it;
265     }
266   }
267
268   bool bOk = MIstatus::success;
269   const MIuint mediumCnt = m_mapMediumToName.size();
270   if ((cnt == 0) && (mediumCnt > 0)) {
271     SetErrorDescription(MIRSRC(IDS_LOG_MEDIUM_ERR_WRITE_ANY));
272     bOk = MIstatus::failure;
273   }
274   if (bOk && (cntErr != 0)) {
275     SetErrorDescription(MIRSRC(IDS_LOG_MEDIUM_ERR_WRITE_MEDIUMFAIL));
276     bOk = MIstatus::failure;
277   }
278
279   m_bRecursiveDive = false;
280
281   return bOk;
282 }
283
284 //++
285 // Details: Short cut function call to write only to the Log file.
286 //          The logger must be initialized successfully before a write to any
287 //          registered
288 //          can be carried out.
289 // Type:    Static.
290 // Args:    vData   - (R) The data to write to the logger.
291 // Return:  MIstatus::success - Functional succeeded.
292 //          MIstatus::failure - Functional failed.
293 // Throws:  None.
294 //--
295 bool CMICmnLog::WriteLog(const CMIUtilString &vData) {
296   return CMICmnLog::Instance().Write(vData, CMICmnLog::eLogVerbosity_Log);
297 }
298
299 //++
300 // Details: Retrieve a string detailing the last error.
301 // Type:    Method.
302 // Args:    None,
303 // Return:  CMIUtilString.
304 // Throws:  None.
305 //--
306 const CMIUtilString &CMICmnLog::GetErrorDescription() const {
307   return m_strMILastErrorDescription;
308 }
309
310 //++
311 // Details: Set the internal description of the last error.
312 // Type:    Method.
313 // Args:    (R) String containing a description of the last error.
314 // Return:  None.
315 // Throws:  None.
316 //--
317 void CMICmnLog::SetErrorDescription(const CMIUtilString &vrTxt) const {
318   m_strMILastErrorDescription = vrTxt;
319 }
320
321 //++
322 // Details: Clear the last error.
323 // Type:    None.
324 // Args:    None.
325 // Return:  None.
326 // Throws:  None.
327 //--
328 void CMICmnLog::ClrErrorDescription() const {
329   m_strMILastErrorDescription = CMIUtilString("");
330 }