1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Assertions and panics.                        m_libcassert.c ---*/
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This file is part of Valgrind, a dynamic binary instrumentation
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   framework.
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Copyright (C) 2000-2011 Julian Seward
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      jseward@acm.org
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This program is free software; you can redistribute it and/or
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   modify it under the terms of the GNU General Public License as
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   published by the Free Software Foundation; either version 2 of the
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   License, or (at your option) any later version.
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This program is distributed in the hope that it will be useful, but
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   WITHOUT ANY WARRANTY; without even the implied warranty of
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   General Public License for more details.
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   You should have received a copy of the GNU General Public License
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   along with this program; if not, write to the Free Software
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   02111-1307, USA.
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The GNU General Public License is contained in the file COPYING.
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_basics.h"
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_vki.h"
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_vkiscnums.h"
34b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_libcsetjmp.h"    // to keep threadstate.h happy
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_threadstate.h"
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcbase.h"
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcassert.h"
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcprint.h"
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcproc.h"      // For VG_(gettid)()
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_stacktrace.h"
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_syscall.h"
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_tooliface.h"     // For VG_(details).{name,bug_reports_to}
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_options.h"       // For VG_(clo_xml)
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Assertery.
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGP_x86_linux) || defined(VGP_x86_darwin)
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define GET_STARTREGS(srP)                              \
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { UInt eip, esp, ebp;                               \
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        __asm__ __volatile__(                             \
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "call 0f;"                                     \
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "0: popl %0;"                                  \
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "movl %%esp, %1;"                              \
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "movl %%ebp, %2;"                              \
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : "=r" (eip), "=r" (esp), "=r" (ebp)           \
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : /* reads none */                             \
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : "memory"                                     \
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        );                                                \
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->r_pc = (ULong)eip;                         \
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->r_sp = (ULong)esp;                         \
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->misc.X86.r_ebp = ebp;                      \
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_amd64_linux) || defined(VGP_amd64_darwin)
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define GET_STARTREGS(srP)                              \
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ULong rip, rsp, rbp;                              \
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        __asm__ __volatile__(                             \
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "leaq 0(%%rip), %0;"                           \
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "movq %%rsp, %1;"                              \
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "movq %%rbp, %2;"                              \
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : "=r" (rip), "=r" (rsp), "=r" (rbp)           \
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : /* reads none */                             \
74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : "memory"                                     \
75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        );                                                \
76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->r_pc = rip;                                \
77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->r_sp = rsp;                                \
78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->misc.AMD64.r_rbp = rbp;                    \
79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
80b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGP_ppc32_linux)
81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define GET_STARTREGS(srP)                              \
82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { UInt cia, r1, lr;                                 \
83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        __asm__ __volatile__(                             \
84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "mflr 0;"                   /* r0 = lr */      \
85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "bl m_libcassert_get_ip;"   /* lr = pc */      \
86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "m_libcassert_get_ip:\n"                       \
87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "mflr %0;"                  /* %0 = pc */      \
88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "mtlr 0;"                   /* restore lr */   \
89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "mr %1,1;"                  /* %1 = r1 */      \
90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "mr %2,0;"                  /* %2 = lr */      \
91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : "=r" (cia), "=r" (r1), "=r" (lr)             \
92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : /* reads none */                             \
93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : "r0" /* trashed */                           \
94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        );                                                \
95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->r_pc = (ULong)cia;                         \
96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->r_sp = (ULong)r1;                          \
97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->misc.PPC32.r_lr = lr;                      \
98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGP_ppc64_linux)
100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define GET_STARTREGS(srP)                              \
101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ULong cia, r1, lr;                                \
102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        __asm__ __volatile__(                             \
103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "mflr 0;"                   /* r0 = lr */      \
104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "bl .m_libcassert_get_ip;"  /* lr = pc */      \
105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           ".m_libcassert_get_ip:\n"                      \
106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "mflr %0;"                  /* %0 = pc */      \
107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "mtlr 0;"                   /* restore lr */   \
108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "mr %1,1;"                  /* %1 = r1 */      \
109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "mr %2,0;"                  /* %2 = lr */      \
110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : "=r" (cia), "=r" (r1), "=r" (lr)             \
111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : /* reads none */                             \
112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : "r0" /* trashed */                           \
113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        );                                                \
114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->r_pc = cia;                                \
115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->r_sp = r1;                                 \
116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->misc.PPC64.r_lr = lr;                      \
117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_arm_linux)
119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define GET_STARTREGS(srP)                              \
120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { UInt block[6];                                    \
121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        __asm__ __volatile__(                             \
122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "str r15, [%0, #+0];"                          \
123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "str r14, [%0, #+4];"                          \
124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "str r13, [%0, #+8];"                          \
125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "str r12, [%0, #+12];"                         \
126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "str r11, [%0, #+16];"                         \
127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "str r7,  [%0, #+20];"                         \
128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : /* out */                                    \
129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : /* in */ "r"(&block[0])                      \
130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : /* trash */ "memory"                         \
131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        );                                                \
132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->r_pc = block[0] - 8;                       \
133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->r_sp = block[1];                           \
134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->misc.ARM.r14 = block[2];                   \
135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->misc.ARM.r12 = block[3];                   \
136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->misc.ARM.r11 = block[4];                   \
137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->misc.ARM.r7  = block[5];                   \
138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGP_s390x_linux)
140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  define GET_STARTREGS(srP)                              \
141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      { ULong ia, sp, fp, lr;                             \
142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        __asm__ __volatile__(                             \
143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           "bras %0,0f;"                                  \
144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           "0: lgr %1,15;"                                \
145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           "lgr %2,11;"                                   \
146b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           "lgr %3,14;"                                   \
147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           : "=r" (ia), "=r" (sp),"=r" (fp),"=r" (lr)     \
148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           /* no read & clobber */                        \
149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        );                                                \
150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        (srP)->r_pc = ia;                                 \
151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        (srP)->r_sp = sp;                                 \
152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        (srP)->misc.S390X.r_fp = fp;                      \
153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        (srP)->misc.S390X.r_lr = lr;                      \
154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  error Unknown platform
157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define BACKTRACE_DEPTH    100         // nice and deep!
160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Pull down the entire world */
162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(exit)( Int status )
163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux)
165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (void)VG_(do_syscall1)(__NR_exit_group, status );
166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin)
167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (void)VG_(do_syscall1)(__NR_exit, status );
168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  error Unknown OS
170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*NOTREACHED*/
172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // We really shouldn't reach here.  Just in case we do, use some very crude
173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // methods to force abort
174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   __builtin_trap();
175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *(volatile Int*)0 = 'x';
176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Print the scheduler status.
179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(show_sched_status) ( void )
180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int i;
182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("\nsched status:\n");
183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("  running_tid=%d\n", VG_(get_running_tid)());
184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 1; i < VG_N_THREADS; i++) {
185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (VG_(threads)[i].status == VgTs_Empty) continue;
186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)( "\nThread %d: status = %s\n", i,
187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   VG_(name_of_ThreadStatus)(VG_(threads)[i].status) );
188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(get_and_pp_StackTrace)( i, BACKTRACE_DEPTH );
189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("\n");
191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__ ((noreturn))
194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void report_and_quit ( const Char* report,
195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              UnwindStartRegs* startRegsIN )
196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr stacktop;
198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr ips[BACKTRACE_DEPTH];
199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int  n_ips;
200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadState *tst
201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      = VG_(get_ThreadState)( VG_(lwpid_to_vgtid)( VG_(gettid)() ) );
202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // If necessary, fake up an ExeContext which is of our actual real CPU
204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // state.  Could cause problems if we got the panic/exception within the
205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // execontext/stack dump/symtab code.  But it's better than nothing.
206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UnwindStartRegs startRegs;
207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(memset)(&startRegs, 0, sizeof(startRegs));
208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (startRegsIN == NULL) {
210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      GET_STARTREGS(&startRegs);
211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      startRegs = *startRegsIN;
213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   stacktop = tst->os_state.valgrind_stack_init_SP;
216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n_ips =
218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(get_StackTrace_wrk)(
219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         0/*tid is unknown*/,
220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ips, BACKTRACE_DEPTH,
221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         NULL/*array to dump SP values in*/,
222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         NULL/*array to dump FP values in*/,
223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         &startRegs, stacktop
224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );
225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(clo_xml) = False;
226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(pp_StackTrace) (ips, n_ips);
227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(show_sched_status)();
229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)(
230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "\n"
231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "Note: see also the FAQ in the source distribution.\n"
232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "It contains workarounds to several common problems.\n"
233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "In particular, if Valgrind aborted or crashed after\n"
234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "identifying problems in your program, there's a good chance\n"
235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "that fixing those problems will prevent Valgrind aborting or\n"
236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "crashing, especially if it happened in m_mallocfree.c.\n"
237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "\n"
238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "If that doesn't help, please report this bug to: %s\n\n"
239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "In the bug report, send all the above text, the valgrind\n"
240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "version, and what OS and version you are using.  Thanks.\n\n",
241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      report);
242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(exit)(1);
243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(assert_fail) ( Bool isCore, const Char* expr, const Char* file,
246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        Int line, const Char* fn, const HChar* format, ... )
247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   va_list vargs;
249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Char buf[256];
250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Char* component;
251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Char* bugs_to;
252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   static Bool entered = False;
254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (entered)
255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(exit)(2);
256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   entered = True;
257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   va_start(vargs, format);
259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(vsprintf) ( buf, format, vargs );
260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   va_end(vargs);
261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (isCore) {
263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      component = "valgrind";
264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      bugs_to   = VG_BUGS_TO;
265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      component = VG_(details).name;
267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      bugs_to   = VG_(details).bug_reports_to;
268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_(clo_xml))
271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf_xml)("</valgrindoutput>\n");
272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Treat vg_assert2(0, "foo") specially, as a panicky abort
274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_STREQ(expr, "0")) {
275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("\n%s: %s:%d (%s): the 'impossible' happened.\n",
276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  component, file, line, fn );
277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("\n%s: %s:%d (%s): Assertion '%s' failed.\n",
279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  component, file, line, fn, expr );
280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!VG_STREQ(buf, ""))
282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("%s: %s\n", component, buf );
283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   report_and_quit(bugs_to, NULL);
285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__ ((noreturn))
288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void panic ( Char* name, Char* report, Char* str,
289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    UnwindStartRegs* startRegs )
290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_(clo_xml))
292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf_xml)("</valgrindoutput>\n");
293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("\n%s: the 'impossible' happened:\n   %s\n", name, str);
294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   report_and_quit(report, startRegs);
295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(core_panic_at) ( Char* str, UnwindStartRegs* startRegs )
298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   panic("valgrind", VG_BUGS_TO, str, startRegs);
300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(core_panic) ( Char* str )
303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(core_panic_at)(str, NULL);
305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(tool_panic) ( Char* str )
308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   panic(VG_(details).name, VG_(details).bug_reports_to, str, NULL);
310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Print some helpful-ish text about unimplemented things, and give up. */
313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(unimplemented) ( Char* msg )
314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_(clo_xml))
316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf_xml)("</valgrindoutput>\n");
317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("\n");
318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("Valgrind detected that your program requires\n");
319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("the following unimplemented functionality:\n");
320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("   %s\n", msg);
321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("This may be because the functionality is hard to implement,\n");
322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("or because no reasonable program would behave this way,\n");
323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("or because nobody has yet needed it.  "
324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             "In any case, let us know at\n");
325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("%s and/or try to work around the problem, if you can.\n",
326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             VG_BUGS_TO);
327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("\n");
328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("Valgrind has to exit now.  Sorry.  Bye!\n");
329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("\n");
330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(show_sched_status)();
331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(exit)(1);
332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end                                                          ---*/
336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
338