blob: d5825bdd21920a0a0005a388dd16cec4bd27faa4 [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"
njn9abd6082005-06-17 21:31:45 +000038#include "pub_core_syscall.h"
njn132bfcc2005-06-04 19:16:06 +000039#include "pub_core_tooliface.h"
njnf39e9a32005-06-12 02:43:17 +000040#include "vki_unistd.h"
njn132bfcc2005-06-04 19:16:06 +000041
42/* ---------------------------------------------------------------------
43 Assertery.
44 ------------------------------------------------------------------ */
45
46#if defined(VGP_x86_linux)
47# define GET_REAL_SP_AND_FP(sp, fp) \
48 asm("movl %%esp, %0;" \
49 "movl %%ebp, %1;" \
50 : "=r" (sp),\
51 "=r" (fp));
52#elif defined(VGP_amd64_linux)
53# define GET_REAL_SP_AND_FP(sp, fp) \
54 asm("movq %%rsp, %0;" \
55 "movq %%rbp, %1;" \
56 : "=r" (sp),\
57 "=r" (fp));
58#else
59# error Unknown platform
60#endif
61
njnf39e9a32005-06-12 02:43:17 +000062/* Pull down the entire world */
63void VG_(exit)( Int status )
64{
65 (void)VG_(do_syscall1)(__NR_exit_group, status );
66 (void)VG_(do_syscall1)(__NR_exit, status );
67 /* Why are we still alive here? */
68 /*NOTREACHED*/
69 *(volatile Int *)0 = 'x';
70 vg_assert(2+2 == 5);
71}
72
njn132bfcc2005-06-04 19:16:06 +000073__attribute__ ((noreturn))
74static void report_and_quit ( const Char* report, Addr ip, Addr sp, Addr fp )
75{
76 #define BACKTRACE_DEPTH 100 // nice and deep!
77 Addr stacktop, ips[BACKTRACE_DEPTH];
78 ThreadState *tst;
79
80 tst = VG_(get_ThreadState)( VG_(get_lwp_tid)(VG_(gettid)()) );
81
82 // If necessary, fake up an ExeContext which is of our actual real CPU
83 // state. Could cause problems if we got the panic/exception within the
84 // execontext/stack dump/symtab code. But it's better than nothing.
85 if (0 == ip && 0 == sp && 0 == fp) {
86 ip = (Addr)__builtin_return_address(0);
87 GET_REAL_SP_AND_FP(sp, fp);
88 }
89
90 stacktop = tst->os_state.valgrind_stack_base +
91 tst->os_state.valgrind_stack_szB;
92
93 VG_(get_StackTrace2)(ips, BACKTRACE_DEPTH, ip, sp, fp, sp, stacktop);
94 VG_(pp_StackTrace) (ips, BACKTRACE_DEPTH);
95
96 VG_(printf)("\nBasic block ctr is approximately %llu\n", VG_(bbs_done) );
97
98 VG_(pp_sched_status)();
99 VG_(printf)("\n");
100 VG_(printf)("Note: see also the FAQ.txt in the source distribution.\n");
101 VG_(printf)("It contains workarounds to several common problems.\n");
102 VG_(printf)("\n");
103 VG_(printf)("If that doesn't help, please report this bug to: %s\n\n",
104 report);
105 VG_(printf)("In the bug report, send all the above text, the valgrind\n");
106 VG_(printf)("version, and what Linux distro you are using. Thanks.\n\n");
107 VG_(exit)(1);
108
109 #undef BACKTRACE_DEPTH
110}
111
112void VG_(assert_fail) ( Bool isCore, const Char* expr, const Char* file,
113 Int line, const Char* fn, const HChar* format, ... )
114{
115 va_list vargs;
116 Char buf[256];
117 Char* bufptr = buf;
118 Char* component;
119 Char* bugs_to;
120
121 static Bool entered = False;
122 if (entered)
123 VG_(exit)(2);
124 entered = True;
125
126 va_start(vargs, format);
127 VG_(vsprintf) ( bufptr, format, vargs );
128 va_end(vargs);
129
130 if (isCore) {
131 component = "valgrind";
132 bugs_to = VG_BUGS_TO;
133 } else {
134 component = VG_(details).name;
135 bugs_to = VG_(details).bug_reports_to;
136 }
137
138 // Treat vg_assert2(0, "foo") specially, as a panicky abort
139 if (VG_STREQ(expr, "0")) {
140 VG_(printf)("\n%s: %s:%d (%s): the 'impossible' happened.\n",
141 component, file, line, fn, expr );
142 } else {
143 VG_(printf)("\n%s: %s:%d (%s): Assertion '%s' failed.\n",
144 component, file, line, fn, expr );
145 }
146 if (!VG_STREQ(buf, ""))
147 VG_(printf)("%s: %s\n", component, buf );
148
149 report_and_quit(bugs_to, 0,0,0);
150}
151
152__attribute__ ((noreturn))
153static void panic ( Char* name, Char* report, Char* str,
154 Addr ip, Addr sp, Addr fp )
155{
156 VG_(printf)("\n%s: the 'impossible' happened:\n %s\n", name, str);
157 report_and_quit(report, ip, sp, fp);
158}
159
160void VG_(core_panic_at) ( Char* str, Addr ip, Addr sp, Addr fp )
161{
162 panic("valgrind", VG_BUGS_TO, str, ip, sp, fp);
163}
164
165void VG_(core_panic) ( Char* str )
166{
167 VG_(core_panic_at)(str, 0,0,0);
168}
169
170void VG_(tool_panic) ( Char* str )
171{
172 panic(VG_(details).name, VG_(details).bug_reports_to, str, 0,0,0);
173}
174
175/* Print some helpful-ish text about unimplemented things, and give
176 up. */
177void VG_(unimplemented) ( Char* msg )
178{
179 VG_(message)(Vg_UserMsg, "");
180 VG_(message)(Vg_UserMsg,
181 "Valgrind detected that your program requires");
182 VG_(message)(Vg_UserMsg,
183 "the following unimplemented functionality:");
184 VG_(message)(Vg_UserMsg, " %s", msg);
185 VG_(message)(Vg_UserMsg,
186 "This may be because the functionality is hard to implement,");
187 VG_(message)(Vg_UserMsg,
188 "or because no reasonable program would behave this way,");
189 VG_(message)(Vg_UserMsg,
190 "or because nobody has yet needed it. In any case, let us know at");
191 VG_(message)(Vg_UserMsg,
192 "%s and/or try to work around the problem, if you can.", VG_BUGS_TO);
193 VG_(message)(Vg_UserMsg,
194 "");
195 VG_(message)(Vg_UserMsg,
196 "Valgrind has to exit now. Sorry. Bye!");
197 VG_(message)(Vg_UserMsg,
198 "");
199 VG_(pp_sched_status)();
200 VG_(exit)(1);
201}
202
203
204
205/*--------------------------------------------------------------------*/
206/*--- end ---*/
207/*--------------------------------------------------------------------*/
208