blob: a6f306968135c5bef16d54f174ec766b2a307cd5 [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
Elliott Hughesed398002017-06-21 14:41:24 -070010 Copyright (C) 2000-2017 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 }
njn9450d242005-06-26 20:50:05 +0000229#else
230# error Unknown platform
231#endif
232
233#define BACKTRACE_DEPTH 100 // nice and deep!
njn3161e802005-06-20 03:38:27 +0000234
philippe180a7502014-04-20 13:41:10 +0000235__attribute__ ((__noreturn__))
236static void exit_wrk( Int status, Bool gdbserver_call_allowed)
njnf39e9a32005-06-12 02:43:17 +0000237{
philippe180a7502014-04-20 13:41:10 +0000238 static Bool exit_called = False;
239 // avoid recursive exit during gdbserver call.
240
241 if (gdbserver_call_allowed && !exit_called) {
242 const ThreadId atid = 1; // Arbitrary tid used to call/terminate gdbsrv.
243 exit_called = True;
Elliott Hughesed398002017-06-21 14:41:24 -0700244 if (status != 0
245 && VgdbStopAtiS(VgdbStopAt_ValgrindAbExit, VG_(clo_vgdb_stop_at))) {
philippe180a7502014-04-20 13:41:10 +0000246 if (VG_(gdbserver_init_done)()) {
247 VG_(umsg)("(action at valgrind abnormal exit) vgdb me ... \n");
248 VG_(gdbserver) (atid);
249 } else {
Elliott Hughesed398002017-06-21 14:41:24 -0700250 VG_(umsg)("(action at valgrind abnormal exit)\n"
251 "valgrind exit is too early => vgdb not yet usable\n");
philippe180a7502014-04-20 13:41:10 +0000252 }
253 }
254 if (VG_(gdbserver_init_done)()) {
255 // Always terminate the gdbserver when Valgrind exits, so as
256 // to e.g. cleanup the FIFOs.
257 VG_(gdbserver_exit) (atid,
258 status == 0 ? VgSrc_ExitProcess : VgSrc_FatalSig);
259 }
260 }
261 exit_called = True;
262
florian421c26e2014-07-24 12:46:28 +0000263 VG_(exit_now) (status);
264}
265
266/* Call the appropriate system call and nothing else. This function should
267 be called in places where the dependencies of VG_(exit) need to be
268 avoided. */
269__attribute__ ((__noreturn__))
270void VG_(exit_now)( Int status )
271{
njn5b6b8fa2009-05-19 05:28:43 +0000272#if defined(VGO_linux)
njnf39e9a32005-06-12 02:43:17 +0000273 (void)VG_(do_syscall1)(__NR_exit_group, status );
sewardj8eb8bab2015-07-21 14:44:28 +0000274#elif defined(VGO_darwin) || defined(VGO_solaris)
njnf39e9a32005-06-12 02:43:17 +0000275 (void)VG_(do_syscall1)(__NR_exit, status );
njn5b6b8fa2009-05-19 05:28:43 +0000276#else
277# error Unknown OS
278#endif
njnf39e9a32005-06-12 02:43:17 +0000279 /*NOTREACHED*/
njn4eeb0e52009-06-09 22:46:32 +0000280 // We really shouldn't reach here. Just in case we do, use some very crude
281 // methods to force abort
282 __builtin_trap();
283 *(volatile Int*)0 = 'x';
njnf39e9a32005-06-12 02:43:17 +0000284}
285
philippe180a7502014-04-20 13:41:10 +0000286/* Pull down the entire world */
287void VG_(exit)( Int status )
288{
289 exit_wrk (status, True);
290}
291
292/* Pull down the entire world */
293void VG_(client_exit)( Int status )
294{
295 exit_wrk (status, False);
296}
297
Elliott Hughesed398002017-06-21 14:41:24 -0700298static void print_thread_state (Bool stack_usage,
299 const HChar* prefix, ThreadId i)
300{
301 VgStack *stack
302 = (VgStack*)VG_(threads)[i].os_state.valgrind_stack_base;
303
304 VG_(printf)("\n%sThread %d: status = %s (lwpid %d)\n", prefix, i,
305 VG_(name_of_ThreadStatus)(VG_(threads)[i].status),
306 VG_(threads)[i].os_state.lwpid);
307 if (VG_(threads)[i].status != VgTs_Empty)
308 VG_(get_and_pp_StackTrace)( i, BACKTRACE_DEPTH );
309 if (stack_usage && VG_(threads)[i].client_stack_highest_byte != 0 ) {
310 Addr start, end;
311
312 start = end = 0;
313 VG_(stack_limits)(VG_(get_SP)(i), &start, &end);
314 if (start != end)
315 VG_(printf)("%sclient stack range: [%p %p] client SP: %p\n",
316 prefix,
317 (void*)start, (void*)end, (void*)VG_(get_SP)(i));
318 else
319 VG_(printf)("%sclient stack range: ??????? client SP: %p\n",
320 prefix,
321 (void*)VG_(get_SP)(i));
322 }
323 if (stack_usage && stack != 0)
324 VG_(printf)
325 ("%svalgrind stack top usage: %lu of %lu\n",
326 prefix,
327 VG_(clo_valgrind_stacksize)
328 - VG_(am_get_VgStack_unused_szB) (stack,
329 VG_(clo_valgrind_stacksize)),
330 (SizeT) VG_(clo_valgrind_stacksize));
331}
philippe180a7502014-04-20 13:41:10 +0000332
njnc7561b92005-06-19 01:24:32 +0000333// Print the scheduler status.
philippe4f6f3362014-04-19 00:25:54 +0000334static void show_sched_status_wrk ( Bool host_stacktrace,
philippe38a74d22014-08-29 22:53:19 +0000335 Bool stack_usage,
philippe4f6f3362014-04-19 00:25:54 +0000336 Bool exited_threads,
florian518850b2014-10-22 22:25:30 +0000337 const UnwindStartRegs* startRegsIN)
njn49b45ba2005-07-20 02:41:31 +0000338{
339 Int i;
philippe4f6f3362014-04-19 00:25:54 +0000340 if (host_stacktrace) {
341 const Bool save_clo_xml = VG_(clo_xml);
342 Addr stacktop;
343 Addr ips[BACKTRACE_DEPTH];
344 Int n_ips;
345 ThreadState *tst
346 = VG_(get_ThreadState)( VG_(lwpid_to_vgtid)( VG_(gettid)() ) );
347
348 // If necessary, fake up an ExeContext which is of our actual real CPU
349 // state. Could cause problems if we got the panic/exception within the
350 // execontext/stack dump/symtab code. But it's better than nothing.
351 UnwindStartRegs startRegs;
352 VG_(memset)(&startRegs, 0, sizeof(startRegs));
353
354 if (startRegsIN == NULL) {
355 GET_STARTREGS(&startRegs);
356 } else {
357 startRegs = *startRegsIN;
358 }
359
360 stacktop = tst->os_state.valgrind_stack_init_SP;
361
362 n_ips =
363 VG_(get_StackTrace_wrk)(
364 0/*tid is unknown*/,
365 ips, BACKTRACE_DEPTH,
366 NULL/*array to dump SP values in*/,
367 NULL/*array to dump FP values in*/,
368 &startRegs, stacktop
369 );
370 VG_(printf)("\nhost stacktrace:\n");
371 VG_(clo_xml) = False;
372 VG_(pp_StackTrace) (ips, n_ips);
373 VG_(clo_xml) = save_clo_xml;
374 }
375
njn49b45ba2005-07-20 02:41:31 +0000376 VG_(printf)("\nsched status:\n");
Elliott Hughesa0664b92017-04-18 17:46:52 -0700377 if (VG_(threads) == NULL) {
378 VG_(printf)(" scheduler not yet initialised\n");
379 } else {
380 VG_(printf)(" running_tid=%u\n", VG_(get_running_tid)());
381 for (i = 1; i < VG_N_THREADS; i++) {
382 VgStack *stack
383 = (VgStack*)VG_(threads)[i].os_state.valgrind_stack_base;
384 /* If a thread slot was never used (yet), valgrind_stack_base is 0.
385 If a thread slot is used by a thread or was used by a thread which
386 has exited, then valgrind_stack_base points to the stack base. */
387 if (VG_(threads)[i].status == VgTs_Empty
388 && (!exited_threads || stack == 0)) continue;
Elliott Hughesed398002017-06-21 14:41:24 -0700389 print_thread_state(stack_usage, "", i);
390 if (VG_(inner_threads) != NULL) {
391 /* An inner V has informed us (the outer) of its thread array.
392 Report the inner guest stack trace. */
393 UInt inner_tid;
Elliott Hughesa0664b92017-04-18 17:46:52 -0700394
Elliott Hughesed398002017-06-21 14:41:24 -0700395 for (inner_tid = 1; inner_tid < VG_N_THREADS; inner_tid++) {
396 if (VG_(threads)[i].os_state.lwpid
397 == VG_(inner_threads)[inner_tid].os_state.lwpid) {
398 ThreadState* save_outer_vg_threads = VG_(threads);
399
400 VG_(threads) = VG_(inner_threads);
401 print_thread_state(stack_usage, "INNER ", inner_tid);
402 VG_(threads) = save_outer_vg_threads;
403 break;
404 }
405 }
Elliott Hughesa0664b92017-04-18 17:46:52 -0700406 }
philippe38a74d22014-08-29 22:53:19 +0000407 }
njn49b45ba2005-07-20 02:41:31 +0000408 }
409 VG_(printf)("\n");
410}
njnc7561b92005-06-19 01:24:32 +0000411
philippe4f6f3362014-04-19 00:25:54 +0000412void VG_(show_sched_status) ( Bool host_stacktrace,
philippe38a74d22014-08-29 22:53:19 +0000413 Bool stack_usage,
philippe4f6f3362014-04-19 00:25:54 +0000414 Bool exited_threads)
415{
416 show_sched_status_wrk (host_stacktrace,
philippe38a74d22014-08-29 22:53:19 +0000417 stack_usage,
philippe4f6f3362014-04-19 00:25:54 +0000418 exited_threads,
419 NULL);
420}
421
njn132bfcc2005-06-04 19:16:06 +0000422__attribute__ ((noreturn))
florianbbd9a212012-10-14 00:16:28 +0000423static void report_and_quit ( const HChar* report,
florian518850b2014-10-22 22:25:30 +0000424 const UnwindStartRegs* startRegsIN )
njn132bfcc2005-06-04 19:16:06 +0000425{
philippe4f6f3362014-04-19 00:25:54 +0000426 show_sched_status_wrk (True, // host_stacktrace
philippe38a74d22014-08-29 22:53:19 +0000427 False, // stack_usage
philippe4f6f3362014-04-19 00:25:54 +0000428 False, // exited_threads
429 startRegsIN);
njnb8329f02009-04-16 00:33:20 +0000430 VG_(printf)(
431 "\n"
432 "Note: see also the FAQ in the source distribution.\n"
433 "It contains workarounds to several common problems.\n"
434 "In particular, if Valgrind aborted or crashed after\n"
435 "identifying problems in your program, there's a good chance\n"
436 "that fixing those problems will prevent Valgrind aborting or\n"
437 "crashing, especially if it happened in m_mallocfree.c.\n"
438 "\n"
439 "If that doesn't help, please report this bug to: %s\n\n"
440 "In the bug report, send all the above text, the valgrind\n"
441 "version, and what OS and version you are using. Thanks.\n\n",
442 report);
njn132bfcc2005-06-04 19:16:06 +0000443 VG_(exit)(1);
njn132bfcc2005-06-04 19:16:06 +0000444}
445
florianbbd9a212012-10-14 00:16:28 +0000446void VG_(assert_fail) ( Bool isCore, const HChar* expr, const HChar* file,
447 Int line, const HChar* fn, const HChar* format, ... )
njn132bfcc2005-06-04 19:16:06 +0000448{
florian74054f42014-09-28 21:35:07 +0000449 va_list vargs, vargs_copy;
florianbbd9a212012-10-14 00:16:28 +0000450 const HChar* component;
451 const HChar* bugs_to;
florian5869ded2013-01-29 04:25:45 +0000452 UInt written;
njn132bfcc2005-06-04 19:16:06 +0000453
454 static Bool entered = False;
455 if (entered)
sewardj745fc452006-10-17 02:03:11 +0000456 VG_(exit)(2);
njn132bfcc2005-06-04 19:16:06 +0000457 entered = True;
458
njn132bfcc2005-06-04 19:16:06 +0000459 if (isCore) {
460 component = "valgrind";
461 bugs_to = VG_BUGS_TO;
462 } else {
463 component = VG_(details).name;
464 bugs_to = VG_(details).bug_reports_to;
465 }
466
sewardjf349d552005-11-14 17:01:01 +0000467 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +0000468 VG_(printf_xml)("</valgrindoutput>\n");
sewardjf349d552005-11-14 17:01:01 +0000469
njn132bfcc2005-06-04 19:16:06 +0000470 // Treat vg_assert2(0, "foo") specially, as a panicky abort
471 if (VG_STREQ(expr, "0")) {
472 VG_(printf)("\n%s: %s:%d (%s): the 'impossible' happened.\n",
njn8a7b41b2007-09-23 00:51:24 +0000473 component, file, line, fn );
njn132bfcc2005-06-04 19:16:06 +0000474 } else {
475 VG_(printf)("\n%s: %s:%d (%s): Assertion '%s' failed.\n",
476 component, file, line, fn, expr );
477 }
florian74054f42014-09-28 21:35:07 +0000478
479 /* Check whether anything will be written */
480 HChar buf[5];
481 va_start(vargs, format);
482 va_copy(vargs_copy, vargs);
483 written = VG_(vsnprintf) ( buf, sizeof(buf), format, vargs );
484 va_end(vargs);
485
486 if (written > 0) {
487 VG_(printf)("%s: ", component);
488 VG_(vprintf)(format, vargs_copy);
489 VG_(printf)("\n");
490 }
njn132bfcc2005-06-04 19:16:06 +0000491
sewardj59570ff2010-01-01 11:59:33 +0000492 report_and_quit(bugs_to, NULL);
njn132bfcc2005-06-04 19:16:06 +0000493}
494
495__attribute__ ((noreturn))
florianbbd9a212012-10-14 00:16:28 +0000496static void panic ( const HChar* name, const HChar* report, const HChar* str,
florian518850b2014-10-22 22:25:30 +0000497 const UnwindStartRegs* startRegs )
njn132bfcc2005-06-04 19:16:06 +0000498{
sewardjf349d552005-11-14 17:01:01 +0000499 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +0000500 VG_(printf_xml)("</valgrindoutput>\n");
njn132bfcc2005-06-04 19:16:06 +0000501 VG_(printf)("\n%s: the 'impossible' happened:\n %s\n", name, str);
sewardj59570ff2010-01-01 11:59:33 +0000502 report_and_quit(report, startRegs);
njn132bfcc2005-06-04 19:16:06 +0000503}
504
florian518850b2014-10-22 22:25:30 +0000505void VG_(core_panic_at) ( const HChar* str, const UnwindStartRegs* startRegs )
njn132bfcc2005-06-04 19:16:06 +0000506{
sewardj59570ff2010-01-01 11:59:33 +0000507 panic("valgrind", VG_BUGS_TO, str, startRegs);
njn132bfcc2005-06-04 19:16:06 +0000508}
509
florianbbd9a212012-10-14 00:16:28 +0000510void VG_(core_panic) ( const HChar* str )
njn132bfcc2005-06-04 19:16:06 +0000511{
sewardj59570ff2010-01-01 11:59:33 +0000512 VG_(core_panic_at)(str, NULL);
njn132bfcc2005-06-04 19:16:06 +0000513}
514
florianbbd9a212012-10-14 00:16:28 +0000515void VG_(tool_panic) ( const HChar* str )
njn132bfcc2005-06-04 19:16:06 +0000516{
sewardj59570ff2010-01-01 11:59:33 +0000517 panic(VG_(details).name, VG_(details).bug_reports_to, str, NULL);
njn132bfcc2005-06-04 19:16:06 +0000518}
519
njn49b45ba2005-07-20 02:41:31 +0000520/* Print some helpful-ish text about unimplemented things, and give up. */
sewardj8eb8bab2015-07-21 14:44:28 +0000521void VG_(unimplemented) ( const HChar* format, ... )
njn132bfcc2005-06-04 19:16:06 +0000522{
sewardj8eb8bab2015-07-21 14:44:28 +0000523 va_list vargs;
524 HChar msg[256];
525
526 va_start(vargs, format);
527 VG_(vsnprintf)(msg, sizeof(msg), format, vargs);
528 va_end(vargs);
529
sewardjf349d552005-11-14 17:01:01 +0000530 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +0000531 VG_(printf_xml)("</valgrindoutput>\n");
532 VG_(umsg)("\n");
533 VG_(umsg)("Valgrind detected that your program requires\n");
534 VG_(umsg)("the following unimplemented functionality:\n");
535 VG_(umsg)(" %s\n", msg);
536 VG_(umsg)("This may be because the functionality is hard to implement,\n");
537 VG_(umsg)("or because no reasonable program would behave this way,\n");
538 VG_(umsg)("or because nobody has yet needed it. "
539 "In any case, let us know at\n");
540 VG_(umsg)("%s and/or try to work around the problem, if you can.\n",
541 VG_BUGS_TO);
542 VG_(umsg)("\n");
543 VG_(umsg)("Valgrind has to exit now. Sorry. Bye!\n");
544 VG_(umsg)("\n");
philippe4f6f3362014-04-19 00:25:54 +0000545 VG_(show_sched_status)(False, // host_stacktrace
philippe38a74d22014-08-29 22:53:19 +0000546 False, // stack_usage
philippe4f6f3362014-04-19 00:25:54 +0000547 False); // exited_threads
njn132bfcc2005-06-04 19:16:06 +0000548 VG_(exit)(1);
549}
550
njn132bfcc2005-06-04 19:16:06 +0000551/*--------------------------------------------------------------------*/
552/*--- end ---*/
553/*--------------------------------------------------------------------*/