VirtualBox

source: vbox/trunk/include/VBox/com/errorprint.h@ 72949

Last change on this file since 72949 was 72949, checked in by vboxsync, 6 years ago

VBoxManage,manual: Added a new command called 'mediumio' to VBoxManage for making use of the IMediumIO interface.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.9 KB
Line 
1/** @file
2 * MS COM / XPCOM Abstraction Layer - Error Reporting.
3 *
4 * Error printing macros using shared functions defined in shared glue code.
5 * Use these CHECK_* macros for efficient error checking around calling COM
6 * methods.
7 */
8
9/*
10 * Copyright (C) 2009-2017 Oracle Corporation
11 *
12 * This file is part of VirtualBox Open Source Edition (OSE), as
13 * available from http://www.virtualbox.org. This file is free software;
14 * you can redistribute it and/or modify it under the terms of the GNU
15 * General Public License (GPL) as published by the Free Software
16 * Foundation, in version 2 as it comes in the "COPYING" file of the
17 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19 *
20 * The contents of this file may alternatively be used under the terms
21 * of the Common Development and Distribution License Version 1.0
22 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
23 * VirtualBox OSE distribution, in which case the provisions of the
24 * CDDL are applicable instead of those of the GPL.
25 *
26 * You may elect to license modified versions of this file under the
27 * terms and conditions of either the GPL or the CDDL or both.
28 */
29
30#ifndef ___VBox_com_errorprint_h
31#define ___VBox_com_errorprint_h
32
33#include <VBox/com/ErrorInfo.h>
34
35
36/** @defgroup grp_com_error_reporting Error Reporting
37 * @ingroup grp_com
38 * @{
39 */
40
41namespace com
42{
43
44// shared prototypes; these are defined in shared glue code and are
45// compiled only once for all front-ends
46void GluePrintErrorInfo(const com::ErrorInfo &info);
47void GluePrintErrorContext(const char *pcszContext, const char *pcszSourceFile, uint32_t uLine);
48void GluePrintRCMessage(HRESULT rc);
49void GlueHandleComError(ComPtr<IUnknown> iface, const char *pcszContext, HRESULT rc, const char *pcszSourceFile, uint32_t uLine);
50void GlueHandleComErrorProgress(ComPtr<IProgress> progress, const char *pcszContext, HRESULT rc,
51 const char *pcszSourceFile, uint32_t uLine);
52
53/**
54 * Extended macro that implements all the other CHECK_ERROR2XXX macros.
55 *
56 * Calls the method of the given interface and checks the return status code.
57 * If the status indicates failure, as much information as possible is reported
58 * about the error, including current source file and line.
59 *
60 * After reporting an error, the statement |stmtError| is executed.
61 *
62 * This macro family is intended for command line tools like VBoxManage, but
63 * could also be handy for debugging.
64 *
65 * @param type For defining @a hrc locally inside the the macro
66 * expansion, pass |HRESULT| otherwise |RT_NOTHING|.
67 * @param hrc Name of the HRESULT variable to assign the result of the
68 * method call to.
69 * @param iface The interface pointer (can be a smart pointer object).
70 * @param method The method to invoke together with the parameters.
71 * @param stmtError Statement to be executed after reporting failures. This
72 * can be a |break| or |return| statement, if so desired.
73 *
74 * @remarks Unlike CHECK_ERROR, CHECK_ERROR_RET and family, this macro family
75 * does not presuppose a |rc| variable but instead either let the user
76 * specify the variable to use or employs a local variable |hrcCheck|
77 * within its own scope.
78 *
79 * @sa CHECK_ERROR2, CHECK_ERROR2I, CHECK_ERROR2_STMT, CHECK_ERROR2I_STMT,
80 * CHECK_ERROR2_BREAK, CHECK_ERROR2I_BREAK, CHECK_ERROR2_RET,
81 * CHECK_ERROR2I_RET
82 */
83#define CHECK_ERROR2_EX(type, hrc, iface, method, stmtError) \
84 if (1) { \
85 type hrc = iface->method; \
86 if (SUCCEEDED(hrc)) \
87 { /*likely*/ } \
88 else \
89 { \
90 com::GlueHandleComError(iface, #method, (hrc), __FILE__, __LINE__); \
91 stmtError; \
92 } \
93 } else do { /* nothing */ } while (0)
94
95
96/**
97 * Calls the given method of the given interface and then checks if the return
98 * value (COM result code) indicates a failure. If so, prints the failed
99 * function/line/file, the description of the result code and attempts to
100 * query the extended error information on the current thread (using
101 * com::ErrorInfo) if the interface reports that it supports error information.
102 *
103 * Used by command line tools or for debugging and assumes the |HRESULT rc|
104 * variable is accessible for assigning in the current scope.
105 * @sa CHECK_ERROR2, CHECK_ERROR2I
106 */
107#define CHECK_ERROR(iface, method) \
108 do { \
109 rc = iface->method; \
110 if (FAILED(rc)) \
111 com::GlueHandleComError(iface, #method, rc, __FILE__, __LINE__); \
112 } while (0)
113/**
114 * Simplified version of CHECK_ERROR2_EX, no error statement or type necessary.
115 *
116 * @param hrc Name of the HRESULT variable to assign the result of the
117 * method call to.
118 * @param iface The interface pointer (can be a smart pointer object).
119 * @param method The method to invoke together with the parameters.
120 * @sa CHECK_ERROR2I, CHECK_ERROR2_EX
121 */
122#define CHECK_ERROR2(hrc, iface, method) CHECK_ERROR2_EX(RT_NOTHING, hrc, iface, method, (void)1)
123/**
124 * Simplified version of CHECK_ERROR2_EX that uses an internal variable
125 * |hrcCheck| for holding the result and have no error statement.
126 *
127 * @param iface The interface pointer (can be a smart pointer object).
128 * @param method The method to invoke together with the parameters.
129 * @sa CHECK_ERROR2, CHECK_ERROR2_EX
130 */
131#define CHECK_ERROR2I(iface, method) CHECK_ERROR2_EX(HRESULT, hrcCheck, iface, method, (void)1)
132
133
134/**
135 * Same as CHECK_ERROR except that it also executes the statement |stmt| on
136 * failure.
137 * @sa CHECK_ERROR2_STMT, CHECK_ERROR2I_STMT
138 */
139#define CHECK_ERROR_STMT(iface, method, stmt) \
140 do { \
141 rc = iface->method; \
142 if (FAILED(rc)) \
143 { \
144 com::GlueHandleComError(iface, #method, rc, __FILE__, __LINE__); \
145 stmt; \
146 } \
147 } while (0)
148/**
149 * Simplified version of CHECK_ERROR2_EX (no @a hrc type).
150 *
151 * @param hrc Name of the HRESULT variable to assign the result of the
152 * method call to.
153 * @param iface The interface pointer (can be a smart pointer object).
154 * @param method The method to invoke together with the parameters.
155 * @param stmt Statement to be executed after reporting failures.
156 * @sa CHECK_ERROR2I_STMT, CHECK_ERROR2_EX
157 */
158#define CHECK_ERROR2_STMT(hrc, iface, method, stmt) CHECK_ERROR2_EX(RT_NOTHING, hrc, iface, method, stmt)
159/**
160 * Simplified version of CHECK_ERROR2_EX that uses an internal variable
161 * |hrcCheck| for holding the result.
162 *
163 * @param iface The interface pointer (can be a smart pointer object).
164 * @param method The method to invoke together with the parameters.
165 * @param stmt Statement to be executed after reporting failures.
166 * @sa CHECK_ERROR2_STMT, CHECK_ERROR2_EX
167 */
168#define CHECK_ERROR2I_STMT(iface, method, stmt) CHECK_ERROR2_EX(HRESULT, hrcCheck, iface, method, stmt)
169
170
171/**
172 * Does the same as CHECK_ERROR(), but executes the |break| statement on
173 * failure.
174 * @sa CHECK_ERROR2_BREAK, CHECK_ERROR2I_BREAK
175 */
176#ifdef __GNUC__
177# define CHECK_ERROR_BREAK(iface, method) \
178 __extension__ \
179 ({ \
180 rc = iface->method; \
181 if (FAILED(rc)) \
182 { \
183 com::GlueHandleComError(iface, #method, rc, __FILE__, __LINE__); \
184 break; \
185 } \
186 })
187#else
188# define CHECK_ERROR_BREAK(iface, method) \
189 if (1) \
190 { \
191 rc = iface->method; \
192 if (FAILED(rc)) \
193 { \
194 com::GlueHandleComError(iface, #method, rc, __FILE__, __LINE__); \
195 break; \
196 } \
197 } \
198 else do {} while (0)
199#endif
200/**
201 * Simplified version of CHECK_ERROR2_EX that executes the |break| statement
202 * after error reporting (no @a hrc type).
203 *
204 * @param hrc The result variable (type HRESULT).
205 * @param iface The interface pointer (can be a smart pointer object).
206 * @param method The method to invoke together with the parameters.
207 * @sa CHECK_ERROR2I_BREAK, CHECK_ERROR2_EX
208 */
209#define CHECK_ERROR2_BREAK(hrc, iface, method) CHECK_ERROR2_EX(RT_NOTHING, hrc, iface, method, break)
210/**
211 * Simplified version of CHECK_ERROR2_EX that executes the |break| statement
212 * after error reporting and that uses an internal variable |hrcCheck| for
213 * holding the result.
214 *
215 * @param iface The interface pointer (can be a smart pointer object).
216 * @param method The method to invoke together with the parameters.
217 * @sa CHECK_ERROR2_BREAK, CHECK_ERROR2_EX
218 */
219#define CHECK_ERROR2I_BREAK(iface, method) CHECK_ERROR2_EX(HRESULT, hrcCheck, iface, method, break)
220/**
221 * Simplified version of CHECK_ERROR2_EX that executes the |stmt;break|
222 * statements after error reporting and that uses an internal variable
223 * |hrcCheck| for holding the result.
224 *
225 * @param iface The interface pointer (can be a smart pointer object).
226 * @param method The method to invoke together with the parameters.
227 * @param stmt Statement to be executed after reporting failures.
228 * @sa CHECK_ERROR2_BREAK, CHECK_ERROR2_EX
229 */
230#define CHECK_ERROR2I_BREAK_STMT(iface, method, stmt) CHECK_ERROR2_EX(HRESULT, hrcCheck, iface, method, stmt; break)
231
232
233/**
234 * Does the same as CHECK_ERROR(), but executes the |return ret| statement on
235 * failure.
236 * @sa CHECK_ERROR2_RET, CHECK_ERROR2I_RET
237 */
238#define CHECK_ERROR_RET(iface, method, ret) \
239 do { \
240 rc = iface->method; \
241 if (FAILED(rc)) \
242 { \
243 com::GlueHandleComError(iface, #method, rc, __FILE__, __LINE__); \
244 return (ret); \
245 } \
246 } while (0)
247/**
248 * Simplified version of CHECK_ERROR2_EX that executes the |return (rcRet)|
249 * statement after error reporting.
250 *
251 * @param hrc The result variable (type HRESULT).
252 * @param iface The interface pointer (can be a smart pointer object).
253 * @param method The method to invoke together with the parameters.
254 * @param rcRet What to return on failure.
255 */
256#define CHECK_ERROR2_RET(hrc, iface, method, rcRet) CHECK_ERROR2_EX(RT_NOTHING, hrc, iface, method, return (rcRet))
257/**
258 * Simplified version of CHECK_ERROR2_EX that executes the |return (rcRet)|
259 * statement after error reporting and that uses an internal variable |hrcCheck|
260 * for holding the result.
261 *
262 * @param iface The interface pointer (can be a smart pointer object).
263 * @param method The method to invoke together with the parameters.
264 * @param rcRet What to return on failure. Use |hrcCheck| to return
265 * the status code of the method call.
266 */
267#define CHECK_ERROR2I_RET(iface, method, rcRet) CHECK_ERROR2_EX(HRESULT, hrcCheck, iface, method, return (rcRet))
268
269
270/**
271 * Check the progress object for an error and if there is one print out the
272 * extended error information.
273 * @remarks Requires HRESULT variable named @a rc.
274 */
275#define CHECK_PROGRESS_ERROR(progress, msg) \
276 do { \
277 LONG iRc; \
278 rc = progress->COMGETTER(ResultCode)(&iRc); \
279 if (FAILED(rc) || FAILED(iRc)) \
280 { \
281 if (SUCCEEDED(rc)) rc = iRc; else iRc = rc; \
282 RTMsgError msg; \
283 com::GlueHandleComErrorProgress(progress, __PRETTY_FUNCTION__, iRc, __FILE__, __LINE__); \
284 } \
285 } while (0)
286
287/**
288 * Does the same as CHECK_PROGRESS_ERROR(), but executes the |break| statement
289 * on failure.
290 * @remarks Requires HRESULT variable named @a rc.
291 */
292#ifdef __GNUC__
293# define CHECK_PROGRESS_ERROR_BREAK(progress, msg) \
294 __extension__ \
295 ({ \
296 LONG iRc; \
297 rc = progress->COMGETTER(ResultCode)(&iRc); \
298 if (FAILED(rc) || FAILED(iRc)) \
299 { \
300 if (SUCCEEDED(rc)) rc = iRc; else iRc = rc; \
301 RTMsgError msg; \
302 com::GlueHandleComErrorProgress(progress, __PRETTY_FUNCTION__, iRc, __FILE__, __LINE__); \
303 break; \
304 } \
305 })
306#else
307# define CHECK_PROGRESS_ERROR_BREAK(progress, msg) \
308 if (1) \
309 { \
310 LONG iRc; \
311 rc = progress->COMGETTER(ResultCode)(&iRc); \
312 if (FAILED(rc) || FAILED(iRc)) \
313 { \
314 if (SUCCEEDED(rc)) rc = iRc; else iRc = rc; \
315 RTMsgError msg; \
316 com::GlueHandleComErrorProgress(progress, __PRETTY_FUNCTION__, iRc, __FILE__, __LINE__); \
317 break; \
318 } \
319 } \
320 else do {} while (0)
321#endif
322
323/**
324 * Does the same as CHECK_PROGRESS_ERROR(), but executes the |return ret|
325 * statement on failure.
326 */
327#define CHECK_PROGRESS_ERROR_RET(progress, msg, ret) \
328 do { \
329 LONG iRc; \
330 HRESULT hrcCheck = progress->COMGETTER(ResultCode)(&iRc); \
331 if (SUCCEEDED(hrcCheck) && SUCCEEDED(iRc)) \
332 { /* likely */ } \
333 else \
334 { \
335 RTMsgError msg; \
336 com::GlueHandleComErrorProgress(progress, __PRETTY_FUNCTION__, \
337 SUCCEEDED(hrcCheck) ? iRc : hrcCheck, __FILE__, __LINE__); \
338 return (ret); \
339 } \
340 } while (0)
341
342/**
343 * Asserts the given expression is true. When the expression is false, prints
344 * a line containing the failed function/line/file; otherwise does nothing.
345 */
346#define ASSERT(expr) \
347 do { \
348 if (!(expr)) \
349 { \
350 RTPrintf ("[!] ASSERTION FAILED at line %d: %s\n", __LINE__, #expr); \
351 Log (("[!] ASSERTION FAILED at line %d: %s\n", __LINE__, #expr)); \
352 } \
353 } while (0)
354
355
356/**
357 * Does the same as ASSERT(), but executes the |return ret| statement if the
358 * expression to assert is false;
359 * @remarks WARNING! @a expr is evalutated TWICE!
360 */
361#define ASSERT_RET(expr, ret) \
362 do { ASSERT(expr); if (!(expr)) return (ret); } while (0)
363
364/**
365 * Does the same as ASSERT(), but executes the |break| statement if the
366 * expression to assert is false;
367 * @remarks WARNING! @a expr is evalutated TWICE!
368 */
369#define ASSERT_BREAK(expr, ret) \
370 if (1) { ASSERT(expr); if (!(expr)) break; } else do {} while (0)
371
372} /* namespace com */
373
374
375/** @} */
376
377#endif
378
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette