VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/misc/assert.cpp@ 28117

Last change on this file since 28117 was 25536, checked in by vboxsync, 15 years ago

iprt/assert.h: Added RTAssertMsg2Add[Weak][V] for dumping the lock deadlock chain and stacks. Added the missing internal/assert.h file to the linux and freebsd kernel source trees.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 9.1 KB
Line 
1/* $Id: assert.cpp 25536 2009-12-21 11:06:08Z vboxsync $ */
2/** @file
3 * IPRT - Assertions, common code.
4 */
5
6/*
7 * Copyright (C) 2006-2009 Sun Microsystems, Inc.
8 *
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.
16 *
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.
22 *
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.
25 *
26 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31
32/*******************************************************************************
33* Header Files *
34*******************************************************************************/
35#include <iprt/assert.h>
36#include "internal/iprt.h"
37
38#include <iprt/asm.h>
39#include <iprt/log.h>
40#include <iprt/string.h>
41#include <iprt/stdarg.h>
42#ifdef IN_RING3
43# include <stdio.h>
44#endif
45#include "internal/assert.h"
46
47
48/*******************************************************************************
49* Global Variables *
50*******************************************************************************/
51/** The last assert message, 1st part. */
52RTDATADECL(char) g_szRTAssertMsg1[1024];
53RT_EXPORT_SYMBOL(g_szRTAssertMsg1);
54/** The last assert message, 2nd part. */
55RTDATADECL(char) g_szRTAssertMsg2[4096];
56RT_EXPORT_SYMBOL(g_szRTAssertMsg2);
57/** The length of the g_szRTAssertMsg2 content.
58 * @remarks Race. */
59static uint32_t volatile g_cchRTAssertMsg2;
60/** The last assert message, expression. */
61RTDATADECL(const char * volatile) g_pszRTAssertExpr;
62RT_EXPORT_SYMBOL(g_pszRTAssertExpr);
63/** The last assert message, function name. */
64RTDATADECL(const char * volatile) g_pszRTAssertFunction;
65RT_EXPORT_SYMBOL(g_pszRTAssertFunction);
66/** The last assert message, file name. */
67RTDATADECL(const char * volatile) g_pszRTAssertFile;
68RT_EXPORT_SYMBOL(g_pszRTAssertFile);
69/** The last assert message, line number. */
70RTDATADECL(uint32_t volatile) g_u32RTAssertLine;
71RT_EXPORT_SYMBOL(g_u32RTAssertLine);
72
73
74/** Set if assertions are quiet. */
75static bool volatile g_fQuiet = false;
76/** Set if assertions may panic. */
77static bool volatile g_fMayPanic = true;
78
79
80RTDECL(bool) RTAssertSetQuiet(bool fQuiet)
81{
82 return ASMAtomicXchgBool(&g_fQuiet, fQuiet);
83}
84RT_EXPORT_SYMBOL(RTAssertSetQuiet);
85
86
87RTDECL(bool) RTAssertAreQuiet(void)
88{
89 return ASMAtomicUoReadBool(&g_fQuiet);
90}
91RT_EXPORT_SYMBOL(RTAssertAreQuiet);
92
93
94RTDECL(bool) RTAssertSetMayPanic(bool fMayPanic)
95{
96 return ASMAtomicXchgBool(&g_fMayPanic, fMayPanic);
97}
98RT_EXPORT_SYMBOL(RTAssertSetMayPanic);
99
100
101RTDECL(bool) RTAssertMayPanic(void)
102{
103 return ASMAtomicUoReadBool(&g_fMayPanic);
104}
105RT_EXPORT_SYMBOL(RTAssertMayPanic);
106
107
108RTDECL(void) RTAssertMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
109{
110 /*
111 * Fill in the globals.
112 */
113 ASMAtomicUoWritePtr((void * volatile *)&g_pszRTAssertExpr, (void *)pszExpr);
114 ASMAtomicUoWritePtr((void * volatile *)&g_pszRTAssertFile, (void *)pszFile);
115 ASMAtomicUoWritePtr((void * volatile *)&g_pszRTAssertFunction, (void *)pszFunction);
116 ASMAtomicUoWriteU32(&g_u32RTAssertLine, uLine);
117 RTStrPrintf(g_szRTAssertMsg1, sizeof(g_szRTAssertMsg1),
118 "\n!!Assertion Failed!!\n"
119 "Expression: %s\n"
120 "Location : %s(%d) %s\n",
121 pszExpr, pszFile, uLine, pszFunction);
122
123 /*
124 * If not quiet, make noise.
125 */
126 if (!RTAssertAreQuiet())
127 {
128#ifdef IN_RING0
129# ifdef IN_GUEST_R0
130 RTLogBackdoorPrintf("\n!!Assertion Failed!!\n"
131 "Expression: %s\n"
132 "Location : %s(%d) %s\n",
133 pszExpr, pszFile, uLine, pszFunction);
134# endif
135 /** @todo fully integrate this with the logger... play safe a bit for now. */
136 rtR0AssertNativeMsg1(pszExpr, uLine, pszFile, pszFunction);
137
138#else /* !IN_RING0 */
139# if !defined(IN_RING3) && !defined(LOG_NO_COM)
140 RTLogComPrintf("\n!!Assertion Failed!!\n"
141 "Expression: %s\n"
142 "Location : %s(%d) %s\n",
143 pszExpr, pszFile, uLine, pszFunction);
144# endif
145
146 PRTLOGGER pLog = RTLogRelDefaultInstance();
147 if (pLog)
148 {
149 RTLogRelPrintf("\n!!Assertion Failed!!\n"
150 "Expression: %s\n"
151 "Location : %s(%d) %s\n",
152 pszExpr, pszFile, uLine, pszFunction);
153# ifndef IN_RC /* flushing is done automatically in RC */
154 RTLogFlush(pLog);
155# endif
156 }
157
158# ifndef LOG_ENABLED
159 if (!pLog)
160# endif
161 {
162 pLog = RTLogDefaultInstance();
163 if (pLog)
164 {
165 RTLogPrintf("\n!!Assertion Failed!!\n"
166 "Expression: %s\n"
167 "Location : %s(%d) %s\n",
168 pszExpr, pszFile, uLine, pszFunction);
169# ifndef IN_RC /* flushing is done automatically in RC */
170 RTLogFlush(pLog);
171# endif
172 }
173 }
174
175# ifdef IN_RING3
176 /* print to stderr, helps user and gdb debugging. */
177 fprintf(stderr,
178 "\n!!Assertion Failed!!\n"
179 "Expression: %s\n"
180 "Location : %s(%d) %s\n",
181 VALID_PTR(pszExpr) ? pszExpr : "<none>",
182 VALID_PTR(pszFile) ? pszFile : "<none>",
183 uLine,
184 VALID_PTR(pszFunction) ? pszFunction : "");
185 fflush(stderr);
186# endif
187#endif /* !IN_RING0 */
188 }
189}
190RT_EXPORT_SYMBOL(RTAssertMsg1);
191
192
193/**
194 * Worker for RTAssertMsg2V and RTAssertMsg2AddV
195 *
196 * @param fInitial True if it's RTAssertMsg2V, otherwise false.
197 * @param pszFormat The message format string.
198 * @param va The format arguments.
199 */
200static void rtAssertMsg2Worker(bool fInitial, const char *pszFormat, va_list va)
201{
202 va_list vaCopy;
203 size_t cch;
204
205 /*
206 * The global first.
207 */
208 if (fInitial)
209 {
210 va_copy(vaCopy, va);
211 cch = RTStrPrintfV(g_szRTAssertMsg2, sizeof(g_szRTAssertMsg2), pszFormat, vaCopy);
212 ASMAtomicWriteU32(&g_cchRTAssertMsg2, (uint32_t)cch);
213 va_end(vaCopy);
214 }
215 else
216 {
217 cch = ASMAtomicReadU32(&g_cchRTAssertMsg2);
218 if (cch < sizeof(g_szRTAssertMsg2) - 4)
219 {
220 va_copy(vaCopy, va);
221 cch += RTStrPrintfV(&g_szRTAssertMsg2[cch], sizeof(g_szRTAssertMsg2) - cch, pszFormat, vaCopy);
222 ASMAtomicWriteU32(&g_cchRTAssertMsg2, (uint32_t)cch);
223 va_end(vaCopy);
224 }
225 }
226
227 /*
228 * If not quiet, make some noise.
229 */
230 if (!RTAssertAreQuiet())
231 {
232#ifdef IN_RING0
233# ifdef IN_GUEST_R0
234 va_copy(vaCopy, va);
235 RTLogBackdoorPrintfV(pszFormat, vaCopy);
236 va_end(vaCopy);
237# endif
238 /** @todo fully integrate this with the logger... play safe a bit for now. */
239 rtR0AssertNativeMsg2V(fInitial, pszFormat, va);
240
241#else /* !IN_RING0 */
242# if !defined(IN_RING3) && !defined(LOG_NO_COM)
243 va_copy(vaCopy, va);
244 RTLogComPrintfV(pszFormat, vaCopy);
245 va_end(vaCopy);
246# endif
247
248 PRTLOGGER pLog = RTLogRelDefaultInstance();
249 if (pLog)
250 {
251 va_copy(vaCopy, va);
252 RTLogRelPrintfV(pszFormat, vaCopy);
253 va_end(vaCopy);
254# ifndef IN_RC /* flushing is done automatically in RC */
255 RTLogFlush(pLog);
256# endif
257 }
258
259 pLog = RTLogDefaultInstance();
260 if (pLog)
261 {
262 va_copy(vaCopy, va);
263 RTLogPrintfV(pszFormat, vaCopy);
264 va_end(vaCopy);
265# ifndef IN_RC /* flushing is done automatically in RC */
266 RTLogFlush(pLog);
267#endif
268 }
269
270# ifdef IN_RING3
271 /* print to stderr, helps user and gdb debugging. */
272 char szMsg[1024];
273 va_copy(vaCopy, va);
274 RTStrPrintfV(szMsg, sizeof(szMsg), pszFormat, vaCopy);
275 va_end(vaCopy);
276 fprintf(stderr, "%s", szMsg);
277 fflush(stderr);
278# endif
279#endif /* !IN_RING0 */
280 }
281
282}
283
284
285RTDECL(void) RTAssertMsg2V(const char *pszFormat, va_list va)
286{
287 rtAssertMsg2Worker(true /*fInitial*/, pszFormat, va);
288}
289RT_EXPORT_SYMBOL(RTAssertMsg2V);
290
291
292RTDECL(void) RTAssertMsg2AddV(const char *pszFormat, va_list va)
293{
294 rtAssertMsg2Worker(false /*fInitial*/, pszFormat, va);
295}
296RT_EXPORT_SYMBOL(RTAssertMsg2AddV);
297
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