VirtualBox

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

Last change on this file since 56291 was 56291, checked in by vboxsync, 10 years ago

include: Updated (C) year.

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

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