]>
git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - ubuntu/vbox/vboxguest/common/misc/assert.c
1 /* $Id: assert.cpp $ */
3 * IPRT - Assertions, common code.
7 * Copyright (C) 2006-2017 Oracle Corporation
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
28 /*********************************************************************************************************************************
30 *********************************************************************************************************************************/
31 #include <iprt/assert.h>
32 #include "internal/iprt.h"
37 #include <iprt/string.h>
38 #include <iprt/stdarg.h>
42 #include "internal/assert.h"
45 /*********************************************************************************************************************************
47 *********************************************************************************************************************************/
48 /** The last assert message, 1st part. */
49 RTDATADECL(char) g_szRTAssertMsg1
[1024];
50 RT_EXPORT_SYMBOL(g_szRTAssertMsg1
);
51 /** The last assert message, 2nd part. */
52 RTDATADECL(char) g_szRTAssertMsg2
[4096];
53 RT_EXPORT_SYMBOL(g_szRTAssertMsg2
);
54 /** The length of the g_szRTAssertMsg2 content.
56 static uint32_t volatile g_cchRTAssertMsg2
;
57 /** The last assert message, expression. */
58 RTDATADECL(const char * volatile) g_pszRTAssertExpr
;
59 RT_EXPORT_SYMBOL(g_pszRTAssertExpr
);
60 /** The last assert message, function name. */
61 RTDATADECL(const char * volatile) g_pszRTAssertFunction
;
62 RT_EXPORT_SYMBOL(g_pszRTAssertFunction
);
63 /** The last assert message, file name. */
64 RTDATADECL(const char * volatile) g_pszRTAssertFile
;
65 RT_EXPORT_SYMBOL(g_pszRTAssertFile
);
66 /** The last assert message, line number. */
67 RTDATADECL(uint32_t volatile) g_u32RTAssertLine
;
68 RT_EXPORT_SYMBOL(g_u32RTAssertLine
);
71 /** Set if assertions are quiet. */
72 static bool volatile g_fQuiet
= false;
73 /** Set if assertions may panic. */
74 static bool volatile g_fMayPanic
= true;
77 RTDECL(bool) RTAssertSetQuiet(bool fQuiet
)
79 return ASMAtomicXchgBool(&g_fQuiet
, fQuiet
);
81 RT_EXPORT_SYMBOL(RTAssertSetQuiet
);
84 RTDECL(bool) RTAssertAreQuiet(void)
86 return ASMAtomicUoReadBool(&g_fQuiet
);
88 RT_EXPORT_SYMBOL(RTAssertAreQuiet
);
91 RTDECL(bool) RTAssertSetMayPanic(bool fMayPanic
)
93 return ASMAtomicXchgBool(&g_fMayPanic
, fMayPanic
);
95 RT_EXPORT_SYMBOL(RTAssertSetMayPanic
);
98 RTDECL(bool) RTAssertMayPanic(void)
100 return ASMAtomicUoReadBool(&g_fMayPanic
);
102 RT_EXPORT_SYMBOL(RTAssertMayPanic
);
105 RTDECL(void) RTAssertMsg1(const char *pszExpr
, unsigned uLine
, const char *pszFile
, const char *pszFunction
)
108 * Fill in the globals.
110 ASMAtomicUoWritePtr(&g_pszRTAssertExpr
, pszExpr
);
111 ASMAtomicUoWritePtr(&g_pszRTAssertFile
, pszFile
);
112 ASMAtomicUoWritePtr(&g_pszRTAssertFunction
, pszFunction
);
113 ASMAtomicUoWriteU32(&g_u32RTAssertLine
, uLine
);
114 RTStrPrintf(g_szRTAssertMsg1
, sizeof(g_szRTAssertMsg1
),
115 "\n!!Assertion Failed!!\n"
117 "Location : %s(%d) %s\n",
118 pszExpr
, pszFile
, uLine
, pszFunction
);
121 * If not quiet, make noise.
123 if (!RTAssertAreQuiet())
125 RTERRVARS SavedErrVars
;
126 RTErrVarsSave(&SavedErrVars
);
130 RTLogBackdoorPrintf("\n!!Assertion Failed!!\n"
132 "Location : %s(%d) %s\n",
133 pszExpr
, pszFile
, uLine
, pszFunction
);
135 /** @todo fully integrate this with the logger... play safe a bit for now. */
136 rtR0AssertNativeMsg1(pszExpr
, uLine
, pszFile
, pszFunction
);
138 #else /* !IN_RING0 */
139 # if !defined(IN_RING3) && !defined(LOG_NO_COM)
140 # if 0 /* Enable this iff you have a COM port and really want this debug info. */
141 RTLogComPrintf("\n!!Assertion Failed!!\n"
143 "Location : %s(%d) %s\n",
144 pszExpr
, pszFile
, uLine
, pszFunction
);
148 PRTLOGGER pLog
= RTLogRelGetDefaultInstance();
151 RTLogRelPrintf("\n!!Assertion Failed!!\n"
153 "Location : %s(%d) %s\n",
154 pszExpr
, pszFile
, uLine
, pszFunction
);
155 # ifndef IN_RC /* flushing is done automatically in RC */
164 pLog
= RTLogDefaultInstance();
167 RTLogPrintf("\n!!Assertion Failed!!\n"
169 "Location : %s(%d) %s\n",
170 pszExpr
, pszFile
, uLine
, pszFunction
);
171 # ifndef IN_RC /* flushing is done automatically in RC */
178 /* print to stderr, helps user and gdb debugging. */
180 "\n!!Assertion Failed!!\n"
182 "Location : %s(%d) %s\n",
183 VALID_PTR(pszExpr
) ? pszExpr
: "<none>",
184 VALID_PTR(pszFile
) ? pszFile
: "<none>",
186 VALID_PTR(pszFunction
) ? pszFunction
: "");
189 #endif /* !IN_RING0 */
191 RTErrVarsRestore(&SavedErrVars
);
194 RT_EXPORT_SYMBOL(RTAssertMsg1
);
198 * Worker for RTAssertMsg2V and RTAssertMsg2AddV
200 * @param fInitial True if it's RTAssertMsg2V, otherwise false.
201 * @param pszFormat The message format string.
202 * @param va The format arguments.
204 static void rtAssertMsg2Worker(bool fInitial
, const char *pszFormat
, va_list va
)
215 cch
= RTStrPrintfV(g_szRTAssertMsg2
, sizeof(g_szRTAssertMsg2
), pszFormat
, vaCopy
);
216 ASMAtomicWriteU32(&g_cchRTAssertMsg2
, (uint32_t)cch
);
221 cch
= ASMAtomicReadU32(&g_cchRTAssertMsg2
);
222 if (cch
< sizeof(g_szRTAssertMsg2
) - 4)
225 cch
+= RTStrPrintfV(&g_szRTAssertMsg2
[cch
], sizeof(g_szRTAssertMsg2
) - cch
, pszFormat
, vaCopy
);
226 ASMAtomicWriteU32(&g_cchRTAssertMsg2
, (uint32_t)cch
);
232 * If not quiet, make some noise.
234 if (!RTAssertAreQuiet())
236 RTERRVARS SavedErrVars
;
237 RTErrVarsSave(&SavedErrVars
);
242 RTLogBackdoorPrintfV(pszFormat
, vaCopy
);
245 /** @todo fully integrate this with the logger... play safe a bit for now. */
246 rtR0AssertNativeMsg2V(fInitial
, pszFormat
, va
);
248 #else /* !IN_RING0 */
249 # if !defined(IN_RING3) && !defined(LOG_NO_COM)
250 # if 0 /* Enable this iff you have a COM port and really want this debug info. */
252 RTLogComPrintfV(pszFormat
, vaCopy
);
257 PRTLOGGER pLog
= RTLogRelGetDefaultInstance();
261 RTLogRelPrintfV(pszFormat
, vaCopy
);
263 # ifndef IN_RC /* flushing is done automatically in RC */
268 pLog
= RTLogDefaultInstance();
272 RTLogPrintfV(pszFormat
, vaCopy
);
274 # ifndef IN_RC /* flushing is done automatically in RC */
280 /* print to stderr, helps user and gdb debugging. */
281 char szMsg
[sizeof(g_szRTAssertMsg2
)];
283 RTStrPrintfV(szMsg
, sizeof(szMsg
), pszFormat
, vaCopy
);
285 fprintf(stderr
, "%s", szMsg
);
288 #endif /* !IN_RING0 */
290 RTErrVarsRestore(&SavedErrVars
);
295 RTDECL(void) RTAssertMsg2V(const char *pszFormat
, va_list va
)
297 rtAssertMsg2Worker(true /*fInitial*/, pszFormat
, va
);
299 RT_EXPORT_SYMBOL(RTAssertMsg2V
);
302 RTDECL(void) RTAssertMsg2AddV(const char *pszFormat
, va_list va
)
304 rtAssertMsg2Worker(false /*fInitial*/, pszFormat
, va
);
306 RT_EXPORT_SYMBOL(RTAssertMsg2AddV
);