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