blob: b5ce2d9c9ff751f1008b71d8d3b59a724f1a3151 [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
sewardjb3a1e4b2015-08-21 11:32:26 +000010 Copyright (C) 2000-2015 Julian Seward
njn132bfcc2005-06-04 19:16:06 +000011 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
njnc7561b92005-06-19 01:24:32 +000031#include "pub_core_basics.h"
sewardj4cfea4f2006-10-14 19:26:10 +000032#include "pub_core_vki.h"
sewardj745fc452006-10-17 02:03:11 +000033#include "pub_core_vkiscnums.h"
njn49b45ba2005-07-20 02:41:31 +000034#include "pub_core_threadstate.h"
philippe180a7502014-04-20 13:41:10 +000035#include "pub_core_gdbserver.h"
philippe4f6f3362014-04-19 00:25:54 +000036#include "pub_core_aspacemgr.h"
njn132bfcc2005-06-04 19:16:06 +000037#include "pub_core_libcbase.h"
38#include "pub_core_libcassert.h"
39#include "pub_core_libcprint.h"
njn49b45ba2005-07-20 02:41:31 +000040#include "pub_core_libcproc.h" // For VG_(gettid)()
philippe38a74d22014-08-29 22:53:19 +000041#include "pub_core_machine.h"
42#include "pub_core_stacks.h"
njn49b45ba2005-07-20 02:41:31 +000043#include "pub_core_stacktrace.h"
njn9abd6082005-06-17 21:31:45 +000044#include "pub_core_syscall.h"
njne070c202005-06-20 23:58:15 +000045#include "pub_core_tooliface.h" // For VG_(details).{name,bug_reports_to}
sewardjf349d552005-11-14 17:01:01 +000046#include "pub_core_options.h" // For VG_(clo_xml)
njn132bfcc2005-06-04 19:16:06 +000047
48/* ---------------------------------------------------------------------
49 Assertery.
50 ------------------------------------------------------------------ */
51
sewardj8eb8bab2015-07-21 14:44:28 +000052#if defined(VGP_x86_linux) || defined(VGP_x86_darwin) \
53 || defined(VGP_x86_solaris)
sewardj59570ff2010-01-01 11:59:33 +000054# define GET_STARTREGS(srP) \
55 { UInt eip, esp, ebp; \
56 __asm__ __volatile__( \
57 "call 0f;" \
58 "0: popl %0;" \
59 "movl %%esp, %1;" \
60 "movl %%ebp, %2;" \
61 : "=r" (eip), "=r" (esp), "=r" (ebp) \
62 : /* reads none */ \
63 : "memory" \
64 ); \
65 (srP)->r_pc = (ULong)eip; \
66 (srP)->r_sp = (ULong)esp; \
67 (srP)->misc.X86.r_ebp = ebp; \
68 }
sewardj8eb8bab2015-07-21 14:44:28 +000069#elif defined(VGP_amd64_linux) || defined(VGP_amd64_darwin) \
70 || defined(VGP_amd64_solaris)
sewardj59570ff2010-01-01 11:59:33 +000071# define GET_STARTREGS(srP) \
72 { ULong rip, rsp, rbp; \
73 __asm__ __volatile__( \
74 "leaq 0(%%rip), %0;" \
75 "movq %%rsp, %1;" \
76 "movq %%rbp, %2;" \
77 : "=r" (rip), "=r" (rsp), "=r" (rbp) \
78 : /* reads none */ \
79 : "memory" \
80 ); \
81 (srP)->r_pc = rip; \
82 (srP)->r_sp = rsp; \
83 (srP)->misc.AMD64.r_rbp = rbp; \
84 }
sewardj6e9de462011-06-28 07:25:29 +000085#elif defined(VGP_ppc32_linux)
sewardj59570ff2010-01-01 11:59:33 +000086# define GET_STARTREGS(srP) \
87 { UInt cia, r1, lr; \
88 __asm__ __volatile__( \
89 "mflr 0;" /* r0 = lr */ \
florian7f3c1f22015-10-12 20:15:12 +000090 "bl 0f;" /* lr = pc */ \
91 "0:\n" \
sewardj59570ff2010-01-01 11:59:33 +000092 "mflr %0;" /* %0 = pc */ \
93 "mtlr 0;" /* restore lr */ \
94 "mr %1,1;" /* %1 = r1 */ \
95 "mr %2,0;" /* %2 = lr */ \
96 : "=r" (cia), "=r" (r1), "=r" (lr) \
97 : /* reads none */ \
98 : "r0" /* trashed */ \
99 ); \
sewardjf5f1e122010-01-02 13:24:58 +0000100 (srP)->r_pc = (ULong)cia; \
101 (srP)->r_sp = (ULong)r1; \
102 (srP)->misc.PPC32.r_lr = lr; \
sewardj59570ff2010-01-01 11:59:33 +0000103 }
carllcae0cc22014-08-07 23:17:29 +0000104#elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
sewardj59570ff2010-01-01 11:59:33 +0000105# define GET_STARTREGS(srP) \
106 { ULong cia, r1, lr; \
107 __asm__ __volatile__( \
108 "mflr 0;" /* r0 = lr */ \
florian7f3c1f22015-10-12 20:15:12 +0000109 "bl 0f;" /* lr = pc */ \
110 "0:\n" \
sewardj59570ff2010-01-01 11:59:33 +0000111 "mflr %0;" /* %0 = pc */ \
112 "mtlr 0;" /* restore lr */ \
113 "mr %1,1;" /* %1 = r1 */ \
114 "mr %2,0;" /* %2 = lr */ \
115 : "=r" (cia), "=r" (r1), "=r" (lr) \
116 : /* reads none */ \
117 : "r0" /* trashed */ \
118 ); \
sewardjf5f1e122010-01-02 13:24:58 +0000119 (srP)->r_pc = cia; \
120 (srP)->r_sp = r1; \
121 (srP)->misc.PPC64.r_lr = lr; \
sewardj59570ff2010-01-01 11:59:33 +0000122 }
123#elif defined(VGP_arm_linux)
124# define GET_STARTREGS(srP) \
sewardjfa5ce562010-09-23 22:05:59 +0000125 { UInt block[6]; \
sewardj59570ff2010-01-01 11:59:33 +0000126 __asm__ __volatile__( \
127 "str r15, [%0, #+0];" \
128 "str r14, [%0, #+4];" \
129 "str r13, [%0, #+8];" \
130 "str r12, [%0, #+12];" \
131 "str r11, [%0, #+16];" \
sewardjfa5ce562010-09-23 22:05:59 +0000132 "str r7, [%0, #+20];" \
sewardj59570ff2010-01-01 11:59:33 +0000133 : /* out */ \
134 : /* in */ "r"(&block[0]) \
135 : /* trash */ "memory" \
136 ); \
137 (srP)->r_pc = block[0] - 8; \
sewardjd474ab22015-02-11 00:49:45 +0000138 (srP)->misc.ARM.r14 = block[1]; \
139 (srP)->r_sp = block[2]; \
sewardj59570ff2010-01-01 11:59:33 +0000140 (srP)->misc.ARM.r12 = block[3]; \
141 (srP)->misc.ARM.r11 = block[4]; \
sewardjfa5ce562010-09-23 22:05:59 +0000142 (srP)->misc.ARM.r7 = block[5]; \
sewardj59570ff2010-01-01 11:59:33 +0000143 }
sewardjf0c12502014-01-12 12:54:00 +0000144#elif defined(VGP_arm64_linux)
145# define GET_STARTREGS(srP) \
146 { ULong block[4]; \
147 __asm__ __volatile__( \
148 "adr x19, 0;" \
149 "str x19, [%0, #+0];" /* pc */ \
150 "mov x19, sp;" \
151 "str x19, [%0, #+8];" /* sp */ \
152 "str x29, [%0, #+16];" /* fp */ \
153 "str x30, [%0, #+24];" /* lr */ \
154 : /* out */ \
155 : /* in */ "r"(&block[0]) \
156 : /* trash */ "memory","x19" \
157 ); \
158 (srP)->r_pc = block[0]; \
159 (srP)->r_sp = block[1]; \
160 (srP)->misc.ARM64.x29 = block[2]; \
161 (srP)->misc.ARM64.x30 = block[3]; \
162 }
sewardjb5b87402011-03-07 16:05:35 +0000163#elif defined(VGP_s390x_linux)
164# define GET_STARTREGS(srP) \
165 { ULong ia, sp, fp, lr; \
166 __asm__ __volatile__( \
167 "bras %0,0f;" \
168 "0: lgr %1,15;" \
169 "lgr %2,11;" \
170 "lgr %3,14;" \
171 : "=r" (ia), "=r" (sp),"=r" (fp),"=r" (lr) \
172 /* no read & clobber */ \
173 ); \
174 (srP)->r_pc = ia; \
175 (srP)->r_sp = sp; \
176 (srP)->misc.S390X.r_fp = fp; \
177 (srP)->misc.S390X.r_lr = lr; \
178 }
sewardj5db15402012-06-07 09:13:21 +0000179#elif defined(VGP_mips32_linux)
180# define GET_STARTREGS(srP) \
181 { UInt pc, sp, fp, ra, gp; \
182 asm("move $8, $31;" /* t0 = ra */ \
florian7f3c1f22015-10-12 20:15:12 +0000183 "bal 0f;" /* ra = pc */ \
184 "0:\n" \
sewardj5db15402012-06-07 09:13:21 +0000185 "move %0, $31;" \
186 "move $31, $8;" /* restore lr */ \
187 "move %1, $29;" \
188 "move %2, $30;" \
189 "move %3, $31;" \
190 "move %4, $28;" \
191 : "=r" (pc), \
192 "=r" (sp), \
193 "=r" (fp), \
194 "=r" (ra), \
195 "=r" (gp) \
196 : /* reads none */ \
197 : "$8" /* trashed */ ); \
198 (srP)->r_pc = (ULong)pc - 8; \
199 (srP)->r_sp = (ULong)sp; \
200 (srP)->misc.MIPS32.r30 = (ULong)fp; \
201 (srP)->misc.MIPS32.r31 = (ULong)ra; \
202 (srP)->misc.MIPS32.r28 = (ULong)gp; \
203 }
petarj4df0bfc2013-02-27 23:17:33 +0000204#elif defined(VGP_mips64_linux)
205# define GET_STARTREGS(srP) \
florian7f3c1f22015-10-12 20:15:12 +0000206 { ULong pc, sp, fp, ra, gp; \
petarj4df0bfc2013-02-27 23:17:33 +0000207 asm("move $8, $31;" /* t0 = ra */ \
florian7f3c1f22015-10-12 20:15:12 +0000208 "bal 0f;" /* ra = pc */ \
209 "0:\n" \
petarj4df0bfc2013-02-27 23:17:33 +0000210 "move %0, $31;" \
211 "move $31, $8;" /* restore lr */ \
212 "move %1, $29;" \
213 "move %2, $30;" \
214 "move %3, $31;" \
215 "move %4, $28;" \
216 : "=r" (pc), \
217 "=r" (sp), \
218 "=r" (fp), \
219 "=r" (ra), \
220 "=r" (gp) \
221 : /* reads none */ \
222 : "$8" /* trashed */ ); \
223 (srP)->r_pc = (ULong)pc - 8; \
224 (srP)->r_sp = (ULong)sp; \
225 (srP)->misc.MIPS64.r30 = (ULong)fp; \
226 (srP)->misc.MIPS64.r31 = (ULong)ra; \
227 (srP)->misc.MIPS64.r28 = (ULong)gp; \
228 }
sewardj112711a2015-04-10 12:30:09 +0000229#elif defined(VGP_tilegx_linux)
230# define GET_STARTREGS(srP) \
zliu62cee7a2015-04-15 02:33:09 +0000231 { ULong pc, sp, fp, ra; \
sewardj112711a2015-04-10 12:30:09 +0000232 __asm__ __volatile__( \
233 "move r8, lr \n" \
234 "jal 0f \n" \
235 "0:\n" \
236 "move %0, lr \n" \
237 "move lr, r8 \n" /* put old lr back*/ \
238 "move %1, sp \n" \
239 "move %2, r52 \n" \
240 "move %3, lr \n" \
241 : "=r" (pc), \
242 "=r" (sp), \
243 "=r" (fp), \
244 "=r" (ra) \
245 : /* reads none */ \
246 : "%r8" /* trashed */ ); \
247 (srP)->r_pc = (ULong)pc - 8; \
248 (srP)->r_sp = (ULong)sp; \
249 (srP)->misc.TILEGX.r52 = (ULong)fp; \
250 (srP)->misc.TILEGX.r55 = (ULong)ra; \
251 }
njn9450d242005-06-26 20:50:05 +0000252#else
253# error Unknown platform
254#endif
255
256#define BACKTRACE_DEPTH 100 // nice and deep!
njn3161e802005-06-20 03:38:27 +0000257
philippe180a7502014-04-20 13:41:10 +0000258__attribute__ ((__noreturn__))
259static void exit_wrk( Int status, Bool gdbserver_call_allowed)
njnf39e9a32005-06-12 02:43:17 +0000260{
philippe180a7502014-04-20 13:41:10 +0000261 static Bool exit_called = False;
262 // avoid recursive exit during gdbserver call.
263
264 if (gdbserver_call_allowed && !exit_called) {
265 const ThreadId atid = 1; // Arbitrary tid used to call/terminate gdbsrv.
266 exit_called = True;
267 if (status != 0 && VG_(gdbserver_stop_at) (VgdbStopAt_ValgrindAbExit)) {
268 if (VG_(gdbserver_init_done)()) {
269 VG_(umsg)("(action at valgrind abnormal exit) vgdb me ... \n");
270 VG_(gdbserver) (atid);
271 } else {
272 VG_(umsg)("(action at valgrind abnormal exit) "
273 "Early valgrind exit : vgdb not yet usable\n");
274 }
275 }
276 if (VG_(gdbserver_init_done)()) {
277 // Always terminate the gdbserver when Valgrind exits, so as
278 // to e.g. cleanup the FIFOs.
279 VG_(gdbserver_exit) (atid,
280 status == 0 ? VgSrc_ExitProcess : VgSrc_FatalSig);
281 }
282 }
283 exit_called = True;
284
florian421c26e2014-07-24 12:46:28 +0000285 VG_(exit_now) (status);
286}
287
288/* Call the appropriate system call and nothing else. This function should
289 be called in places where the dependencies of VG_(exit) need to be
290 avoided. */
291__attribute__ ((__noreturn__))
292void VG_(exit_now)( Int status )
293{
njn5b6b8fa2009-05-19 05:28:43 +0000294#if defined(VGO_linux)
njnf39e9a32005-06-12 02:43:17 +0000295 (void)VG_(do_syscall1)(__NR_exit_group, status );
sewardj8eb8bab2015-07-21 14:44:28 +0000296#elif defined(VGO_darwin) || defined(VGO_solaris)
njnf39e9a32005-06-12 02:43:17 +0000297 (void)VG_(do_syscall1)(__NR_exit, status );
njn5b6b8fa2009-05-19 05:28:43 +0000298#else
299# error Unknown OS
300#endif
njnf39e9a32005-06-12 02:43:17 +0000301 /*NOTREACHED*/
njn4eeb0e52009-06-09 22:46:32 +0000302 // We really shouldn't reach here. Just in case we do, use some very crude
303 // methods to force abort
304 __builtin_trap();
305 *(volatile Int*)0 = 'x';
njnf39e9a32005-06-12 02:43:17 +0000306}
307
philippe180a7502014-04-20 13:41:10 +0000308/* Pull down the entire world */
309void VG_(exit)( Int status )
310{
311 exit_wrk (status, True);
312}
313
314/* Pull down the entire world */
315void VG_(client_exit)( Int status )
316{
317 exit_wrk (status, False);
318}
319
320
njnc7561b92005-06-19 01:24:32 +0000321// Print the scheduler status.
philippe4f6f3362014-04-19 00:25:54 +0000322static void show_sched_status_wrk ( Bool host_stacktrace,
philippe38a74d22014-08-29 22:53:19 +0000323 Bool stack_usage,
philippe4f6f3362014-04-19 00:25:54 +0000324 Bool exited_threads,
florian518850b2014-10-22 22:25:30 +0000325 const UnwindStartRegs* startRegsIN)
njn49b45ba2005-07-20 02:41:31 +0000326{
327 Int i;
philippe4f6f3362014-04-19 00:25:54 +0000328 if (host_stacktrace) {
329 const Bool save_clo_xml = VG_(clo_xml);
330 Addr stacktop;
331 Addr ips[BACKTRACE_DEPTH];
332 Int n_ips;
333 ThreadState *tst
334 = VG_(get_ThreadState)( VG_(lwpid_to_vgtid)( VG_(gettid)() ) );
335
336 // If necessary, fake up an ExeContext which is of our actual real CPU
337 // state. Could cause problems if we got the panic/exception within the
338 // execontext/stack dump/symtab code. But it's better than nothing.
339 UnwindStartRegs startRegs;
340 VG_(memset)(&startRegs, 0, sizeof(startRegs));
341
342 if (startRegsIN == NULL) {
343 GET_STARTREGS(&startRegs);
344 } else {
345 startRegs = *startRegsIN;
346 }
347
348 stacktop = tst->os_state.valgrind_stack_init_SP;
349
350 n_ips =
351 VG_(get_StackTrace_wrk)(
352 0/*tid is unknown*/,
353 ips, BACKTRACE_DEPTH,
354 NULL/*array to dump SP values in*/,
355 NULL/*array to dump FP values in*/,
356 &startRegs, stacktop
357 );
358 VG_(printf)("\nhost stacktrace:\n");
359 VG_(clo_xml) = False;
360 VG_(pp_StackTrace) (ips, n_ips);
361 VG_(clo_xml) = save_clo_xml;
362 }
363
njn49b45ba2005-07-20 02:41:31 +0000364 VG_(printf)("\nsched status:\n");
Elliott Hughesa0664b92017-04-18 17:46:52 -0700365 if (VG_(threads) == NULL) {
366 VG_(printf)(" scheduler not yet initialised\n");
367 } else {
368 VG_(printf)(" running_tid=%u\n", VG_(get_running_tid)());
369 for (i = 1; i < VG_N_THREADS; i++) {
370 VgStack *stack
371 = (VgStack*)VG_(threads)[i].os_state.valgrind_stack_base;
372 /* If a thread slot was never used (yet), valgrind_stack_base is 0.
373 If a thread slot is used by a thread or was used by a thread which
374 has exited, then valgrind_stack_base points to the stack base. */
375 if (VG_(threads)[i].status == VgTs_Empty
376 && (!exited_threads || stack == 0)) continue;
377 VG_(printf)("\nThread %d: status = %s (lwpid %d)\n", i,
378 VG_(name_of_ThreadStatus)(VG_(threads)[i].status),
379 VG_(threads)[i].os_state.lwpid);
380 if (VG_(threads)[i].status != VgTs_Empty)
381 VG_(get_and_pp_StackTrace)( i, BACKTRACE_DEPTH );
382 if (stack_usage && VG_(threads)[i].client_stack_highest_byte != 0 ) {
383 Addr start, end;
384
385 start = end = 0;
386 VG_(stack_limits)(VG_(threads)[i].client_stack_highest_byte,
387 &start, &end);
388 if (start != end)
389 VG_(printf)("client stack range: [%p %p] client SP: %p\n",
390 (void*)start, (void*)end, (void*)VG_(get_SP)(i));
391 else
392 VG_(printf)("client stack range: ???????\n");
393 }
394 if (stack_usage && stack != 0)
395 VG_(printf)("valgrind stack top usage: %lu of %lu\n",
396 VG_(clo_valgrind_stacksize)
397 - VG_(am_get_VgStack_unused_szB)
398 (stack, VG_(clo_valgrind_stacksize)),
399 (SizeT) VG_(clo_valgrind_stacksize));
philippe38a74d22014-08-29 22:53:19 +0000400 }
njn49b45ba2005-07-20 02:41:31 +0000401 }
402 VG_(printf)("\n");
403}
njnc7561b92005-06-19 01:24:32 +0000404
philippe4f6f3362014-04-19 00:25:54 +0000405void VG_(show_sched_status) ( Bool host_stacktrace,
philippe38a74d22014-08-29 22:53:19 +0000406 Bool stack_usage,
philippe4f6f3362014-04-19 00:25:54 +0000407 Bool exited_threads)
408{
409 show_sched_status_wrk (host_stacktrace,
philippe38a74d22014-08-29 22:53:19 +0000410 stack_usage,
philippe4f6f3362014-04-19 00:25:54 +0000411 exited_threads,
412 NULL);
413}
414
njn132bfcc2005-06-04 19:16:06 +0000415__attribute__ ((noreturn))
florianbbd9a212012-10-14 00:16:28 +0000416static void report_and_quit ( const HChar* report,
florian518850b2014-10-22 22:25:30 +0000417 const UnwindStartRegs* startRegsIN )
njn132bfcc2005-06-04 19:16:06 +0000418{
philippe4f6f3362014-04-19 00:25:54 +0000419 show_sched_status_wrk (True, // host_stacktrace
philippe38a74d22014-08-29 22:53:19 +0000420 False, // stack_usage
philippe4f6f3362014-04-19 00:25:54 +0000421 False, // exited_threads
422 startRegsIN);
njnb8329f02009-04-16 00:33:20 +0000423 VG_(printf)(
424 "\n"
425 "Note: see also the FAQ in the source distribution.\n"
426 "It contains workarounds to several common problems.\n"
427 "In particular, if Valgrind aborted or crashed after\n"
428 "identifying problems in your program, there's a good chance\n"
429 "that fixing those problems will prevent Valgrind aborting or\n"
430 "crashing, especially if it happened in m_mallocfree.c.\n"
431 "\n"
432 "If that doesn't help, please report this bug to: %s\n\n"
433 "In the bug report, send all the above text, the valgrind\n"
434 "version, and what OS and version you are using. Thanks.\n\n",
435 report);
njn132bfcc2005-06-04 19:16:06 +0000436 VG_(exit)(1);
njn132bfcc2005-06-04 19:16:06 +0000437}
438
florianbbd9a212012-10-14 00:16:28 +0000439void VG_(assert_fail) ( Bool isCore, const HChar* expr, const HChar* file,
440 Int line, const HChar* fn, const HChar* format, ... )
njn132bfcc2005-06-04 19:16:06 +0000441{
florian74054f42014-09-28 21:35:07 +0000442 va_list vargs, vargs_copy;
florianbbd9a212012-10-14 00:16:28 +0000443 const HChar* component;
444 const HChar* bugs_to;
florian5869ded2013-01-29 04:25:45 +0000445 UInt written;
njn132bfcc2005-06-04 19:16:06 +0000446
447 static Bool entered = False;
448 if (entered)
sewardj745fc452006-10-17 02:03:11 +0000449 VG_(exit)(2);
njn132bfcc2005-06-04 19:16:06 +0000450 entered = True;
451
njn132bfcc2005-06-04 19:16:06 +0000452 if (isCore) {
453 component = "valgrind";
454 bugs_to = VG_BUGS_TO;
455 } else {
456 component = VG_(details).name;
457 bugs_to = VG_(details).bug_reports_to;
458 }
459
sewardjf349d552005-11-14 17:01:01 +0000460 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +0000461 VG_(printf_xml)("</valgrindoutput>\n");
sewardjf349d552005-11-14 17:01:01 +0000462
njn132bfcc2005-06-04 19:16:06 +0000463 // Treat vg_assert2(0, "foo") specially, as a panicky abort
464 if (VG_STREQ(expr, "0")) {
465 VG_(printf)("\n%s: %s:%d (%s): the 'impossible' happened.\n",
njn8a7b41b2007-09-23 00:51:24 +0000466 component, file, line, fn );
njn132bfcc2005-06-04 19:16:06 +0000467 } else {
468 VG_(printf)("\n%s: %s:%d (%s): Assertion '%s' failed.\n",
469 component, file, line, fn, expr );
470 }
florian74054f42014-09-28 21:35:07 +0000471
472 /* Check whether anything will be written */
473 HChar buf[5];
474 va_start(vargs, format);
475 va_copy(vargs_copy, vargs);
476 written = VG_(vsnprintf) ( buf, sizeof(buf), format, vargs );
477 va_end(vargs);
478
479 if (written > 0) {
480 VG_(printf)("%s: ", component);
481 VG_(vprintf)(format, vargs_copy);
482 VG_(printf)("\n");
483 }
njn132bfcc2005-06-04 19:16:06 +0000484
sewardj59570ff2010-01-01 11:59:33 +0000485 report_and_quit(bugs_to, NULL);
njn132bfcc2005-06-04 19:16:06 +0000486}
487
488__attribute__ ((noreturn))
florianbbd9a212012-10-14 00:16:28 +0000489static void panic ( const HChar* name, const HChar* report, const HChar* str,
florian518850b2014-10-22 22:25:30 +0000490 const UnwindStartRegs* startRegs )
njn132bfcc2005-06-04 19:16:06 +0000491{
sewardjf349d552005-11-14 17:01:01 +0000492 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +0000493 VG_(printf_xml)("</valgrindoutput>\n");
njn132bfcc2005-06-04 19:16:06 +0000494 VG_(printf)("\n%s: the 'impossible' happened:\n %s\n", name, str);
sewardj59570ff2010-01-01 11:59:33 +0000495 report_and_quit(report, startRegs);
njn132bfcc2005-06-04 19:16:06 +0000496}
497
florian518850b2014-10-22 22:25:30 +0000498void VG_(core_panic_at) ( const HChar* str, const UnwindStartRegs* startRegs )
njn132bfcc2005-06-04 19:16:06 +0000499{
sewardj59570ff2010-01-01 11:59:33 +0000500 panic("valgrind", VG_BUGS_TO, str, startRegs);
njn132bfcc2005-06-04 19:16:06 +0000501}
502
florianbbd9a212012-10-14 00:16:28 +0000503void VG_(core_panic) ( const HChar* str )
njn132bfcc2005-06-04 19:16:06 +0000504{
sewardj59570ff2010-01-01 11:59:33 +0000505 VG_(core_panic_at)(str, NULL);
njn132bfcc2005-06-04 19:16:06 +0000506}
507
florianbbd9a212012-10-14 00:16:28 +0000508void VG_(tool_panic) ( const HChar* str )
njn132bfcc2005-06-04 19:16:06 +0000509{
sewardj59570ff2010-01-01 11:59:33 +0000510 panic(VG_(details).name, VG_(details).bug_reports_to, str, NULL);
njn132bfcc2005-06-04 19:16:06 +0000511}
512
njn49b45ba2005-07-20 02:41:31 +0000513/* Print some helpful-ish text about unimplemented things, and give up. */
sewardj8eb8bab2015-07-21 14:44:28 +0000514void VG_(unimplemented) ( const HChar* format, ... )
njn132bfcc2005-06-04 19:16:06 +0000515{
sewardj8eb8bab2015-07-21 14:44:28 +0000516 va_list vargs;
517 HChar msg[256];
518
519 va_start(vargs, format);
520 VG_(vsnprintf)(msg, sizeof(msg), format, vargs);
521 va_end(vargs);
522
sewardjf349d552005-11-14 17:01:01 +0000523 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +0000524 VG_(printf_xml)("</valgrindoutput>\n");
525 VG_(umsg)("\n");
526 VG_(umsg)("Valgrind detected that your program requires\n");
527 VG_(umsg)("the following unimplemented functionality:\n");
528 VG_(umsg)(" %s\n", msg);
529 VG_(umsg)("This may be because the functionality is hard to implement,\n");
530 VG_(umsg)("or because no reasonable program would behave this way,\n");
531 VG_(umsg)("or because nobody has yet needed it. "
532 "In any case, let us know at\n");
533 VG_(umsg)("%s and/or try to work around the problem, if you can.\n",
534 VG_BUGS_TO);
535 VG_(umsg)("\n");
536 VG_(umsg)("Valgrind has to exit now. Sorry. Bye!\n");
537 VG_(umsg)("\n");
philippe4f6f3362014-04-19 00:25:54 +0000538 VG_(show_sched_status)(False, // host_stacktrace
philippe38a74d22014-08-29 22:53:19 +0000539 False, // stack_usage
philippe4f6f3362014-04-19 00:25:54 +0000540 False); // exited_threads
njn132bfcc2005-06-04 19:16:06 +0000541 VG_(exit)(1);
542}
543
njn132bfcc2005-06-04 19:16:06 +0000544/*--------------------------------------------------------------------*/
545/*--- end ---*/
546/*--------------------------------------------------------------------*/