blob: dea4f053f92ad59fafac58902b031096672b577b [file] [log] [blame]
njn132bfcc2005-06-04 19:16:06 +00001
2/*--------------------------------------------------------------------*/
3/*--- Assertions and panics. m_libcassert.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
10 Copyright (C) 2000-2005 Julian Seward
11 jseward@acm.org
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31#include "core.h"
32#include "pub_core_libcbase.h"
33#include "pub_core_libcassert.h"
34#include "pub_core_libcprint.h"
njnf39e9a32005-06-12 02:43:17 +000035#include "pub_core_libcproc.h"
njn132bfcc2005-06-04 19:16:06 +000036#include "pub_core_main.h"
37#include "pub_core_stacktrace.h"
38#include "pub_core_tooliface.h"
njnf39e9a32005-06-12 02:43:17 +000039#include "vki_unistd.h"
njn132bfcc2005-06-04 19:16:06 +000040
41/* ---------------------------------------------------------------------
42 Assertery.
43 ------------------------------------------------------------------ */
44
45#if defined(VGP_x86_linux)
46# define GET_REAL_SP_AND_FP(sp, fp) \
47 asm("movl %%esp, %0;" \
48 "movl %%ebp, %1;" \
49 : "=r" (sp),\
50 "=r" (fp));
51#elif defined(VGP_amd64_linux)
52# define GET_REAL_SP_AND_FP(sp, fp) \
53 asm("movq %%rsp, %0;" \
54 "movq %%rbp, %1;" \
55 : "=r" (sp),\
56 "=r" (fp));
57#else
58# error Unknown platform
59#endif
60
njnf39e9a32005-06-12 02:43:17 +000061/* Pull down the entire world */
62void VG_(exit)( Int status )
63{
64 (void)VG_(do_syscall1)(__NR_exit_group, status );
65 (void)VG_(do_syscall1)(__NR_exit, status );
66 /* Why are we still alive here? */
67 /*NOTREACHED*/
68 *(volatile Int *)0 = 'x';
69 vg_assert(2+2 == 5);
70}
71
njn132bfcc2005-06-04 19:16:06 +000072__attribute__ ((noreturn))
73static void report_and_quit ( const Char* report, Addr ip, Addr sp, Addr fp )
74{
75 #define BACKTRACE_DEPTH 100 // nice and deep!
76 Addr stacktop, ips[BACKTRACE_DEPTH];
77 ThreadState *tst;
78
79 tst = VG_(get_ThreadState)( VG_(get_lwp_tid)(VG_(gettid)()) );
80
81 // If necessary, fake up an ExeContext which is of our actual real CPU
82 // state. Could cause problems if we got the panic/exception within the
83 // execontext/stack dump/symtab code. But it's better than nothing.
84 if (0 == ip && 0 == sp && 0 == fp) {
85 ip = (Addr)__builtin_return_address(0);
86 GET_REAL_SP_AND_FP(sp, fp);
87 }
88
89 stacktop = tst->os_state.valgrind_stack_base +
90 tst->os_state.valgrind_stack_szB;
91
92 VG_(get_StackTrace2)(ips, BACKTRACE_DEPTH, ip, sp, fp, sp, stacktop);
93 VG_(pp_StackTrace) (ips, BACKTRACE_DEPTH);
94
95 VG_(printf)("\nBasic block ctr is approximately %llu\n", VG_(bbs_done) );
96
97 VG_(pp_sched_status)();
98 VG_(printf)("\n");
99 VG_(printf)("Note: see also the FAQ.txt in the source distribution.\n");
100 VG_(printf)("It contains workarounds to several common problems.\n");
101 VG_(printf)("\n");
102 VG_(printf)("If that doesn't help, please report this bug to: %s\n\n",
103 report);
104 VG_(printf)("In the bug report, send all the above text, the valgrind\n");
105 VG_(printf)("version, and what Linux distro you are using. Thanks.\n\n");
106 VG_(exit)(1);
107
108 #undef BACKTRACE_DEPTH
109}
110
111void VG_(assert_fail) ( Bool isCore, const Char* expr, const Char* file,
112 Int line, const Char* fn, const HChar* format, ... )
113{
114 va_list vargs;
115 Char buf[256];
116 Char* bufptr = buf;
117 Char* component;
118 Char* bugs_to;
119
120 static Bool entered = False;
121 if (entered)
122 VG_(exit)(2);
123 entered = True;
124
125 va_start(vargs, format);
126 VG_(vsprintf) ( bufptr, format, vargs );
127 va_end(vargs);
128
129 if (isCore) {
130 component = "valgrind";
131 bugs_to = VG_BUGS_TO;
132 } else {
133 component = VG_(details).name;
134 bugs_to = VG_(details).bug_reports_to;
135 }
136
137 // Treat vg_assert2(0, "foo") specially, as a panicky abort
138 if (VG_STREQ(expr, "0")) {
139 VG_(printf)("\n%s: %s:%d (%s): the 'impossible' happened.\n",
140 component, file, line, fn, expr );
141 } else {
142 VG_(printf)("\n%s: %s:%d (%s): Assertion '%s' failed.\n",
143 component, file, line, fn, expr );
144 }
145 if (!VG_STREQ(buf, ""))
146 VG_(printf)("%s: %s\n", component, buf );
147
148 report_and_quit(bugs_to, 0,0,0);
149}
150
151__attribute__ ((noreturn))
152static void panic ( Char* name, Char* report, Char* str,
153 Addr ip, Addr sp, Addr fp )
154{
155 VG_(printf)("\n%s: the 'impossible' happened:\n %s\n", name, str);
156 report_and_quit(report, ip, sp, fp);
157}
158
159void VG_(core_panic_at) ( Char* str, Addr ip, Addr sp, Addr fp )
160{
161 panic("valgrind", VG_BUGS_TO, str, ip, sp, fp);
162}
163
164void VG_(core_panic) ( Char* str )
165{
166 VG_(core_panic_at)(str, 0,0,0);
167}
168
169void VG_(tool_panic) ( Char* str )
170{
171 panic(VG_(details).name, VG_(details).bug_reports_to, str, 0,0,0);
172}
173
174/* Print some helpful-ish text about unimplemented things, and give
175 up. */
176void VG_(unimplemented) ( Char* msg )
177{
178 VG_(message)(Vg_UserMsg, "");
179 VG_(message)(Vg_UserMsg,
180 "Valgrind detected that your program requires");
181 VG_(message)(Vg_UserMsg,
182 "the following unimplemented functionality:");
183 VG_(message)(Vg_UserMsg, " %s", msg);
184 VG_(message)(Vg_UserMsg,
185 "This may be because the functionality is hard to implement,");
186 VG_(message)(Vg_UserMsg,
187 "or because no reasonable program would behave this way,");
188 VG_(message)(Vg_UserMsg,
189 "or because nobody has yet needed it. In any case, let us know at");
190 VG_(message)(Vg_UserMsg,
191 "%s and/or try to work around the problem, if you can.", VG_BUGS_TO);
192 VG_(message)(Vg_UserMsg,
193 "");
194 VG_(message)(Vg_UserMsg,
195 "Valgrind has to exit now. Sorry. Bye!");
196 VG_(message)(Vg_UserMsg,
197 "");
198 VG_(pp_sched_status)();
199 VG_(exit)(1);
200}
201
202
203
204/*--------------------------------------------------------------------*/
205/*--- end ---*/
206/*--------------------------------------------------------------------*/
207