m_libcassert.c revision 5f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3
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-2009 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_threadstate.h" 35#include "pub_core_libcbase.h" 36#include "pub_core_libcassert.h" 37#include "pub_core_libcprint.h" 38#include "pub_core_libcproc.h" // For VG_(gettid)() 39#include "pub_core_stacktrace.h" 40#include "pub_core_syscall.h" 41#include "pub_core_tooliface.h" // For VG_(details).{name,bug_reports_to} 42#include "pub_core_options.h" // For VG_(clo_xml) 43 44/* --------------------------------------------------------------------- 45 Assertery. 46 ------------------------------------------------------------------ */ 47 48#if defined(VGP_x86_linux) 49# define GET_REAL_PC_SP_AND_FP(pc, sp, fp) \ 50 asm("call 0f;" \ 51 "0: popl %0;" \ 52 "movl %%esp, %1;" \ 53 "movl %%ebp, %2;" \ 54 : "=r" (pc),\ 55 "=r" (sp),\ 56 "=r" (fp)); 57#elif defined(VGP_amd64_linux) 58# define GET_REAL_PC_SP_AND_FP(pc, sp, fp) \ 59 asm("leaq 0(%%rip), %0;" \ 60 "movq %%rsp, %1;" \ 61 "movq %%rbp, %2;" \ 62 : "=r" (pc),\ 63 "=r" (sp),\ 64 "=r" (fp)); 65#elif defined(VGP_ppc32_linux) || defined(VGP_ppc32_aix5) 66# define GET_REAL_PC_SP_AND_FP(pc, sp, fp) \ 67 asm("mflr 0;" /* r0 = lr */ \ 68 "bl m_libcassert_get_ip;" /* lr = pc */ \ 69 "m_libcassert_get_ip:\n" \ 70 "mflr %0;" \ 71 "mtlr 0;" /* restore lr */ \ 72 "mr %1,1;" \ 73 "mr %2,1;" \ 74 : "=r" (pc), \ 75 "=r" (sp), \ 76 "=r" (fp) \ 77 : /* reads none */ \ 78 : "r0" /* trashed */ ); 79#elif defined(VGP_ppc64_linux) || defined(VGP_ppc64_aix5) 80# define GET_REAL_PC_SP_AND_FP(pc, sp, fp) \ 81 asm("mflr 0;" /* r0 = lr */ \ 82 "bl .m_libcassert_get_ip;" /* lr = pc */ \ 83 ".m_libcassert_get_ip:\n" \ 84 "mflr %0;" \ 85 "mtlr 0;" /* restore lr */ \ 86 "mr %1,1;" \ 87 "mr %2,1;" \ 88 : "=r" (pc), \ 89 "=r" (sp), \ 90 "=r" (fp) \ 91 : /* reads none */ \ 92 : "r0" /* trashed */ ); 93#else 94# error Unknown platform 95#endif 96 97#define BACKTRACE_DEPTH 100 // nice and deep! 98 99/* Pull down the entire world */ 100void VG_(exit)( Int status ) 101{ 102# if defined(VGO_linux) 103 (void)VG_(do_syscall1)(__NR_exit_group, status ); 104# endif 105 (void)VG_(do_syscall1)(__NR_exit, status ); 106 /* Why are we still alive here? */ 107 /*NOTREACHED*/ 108 *(volatile Int *)0 = 'x'; 109 vg_assert(2+2 == 5); 110} 111 112// Print the scheduler status. 113void VG_(show_sched_status) ( void ) 114{ 115 Int i; 116 VG_(printf)("\nsched status:\n"); 117 VG_(printf)(" running_tid=%d\n", VG_(get_running_tid)()); 118 for (i = 1; i < VG_N_THREADS; i++) { 119 if (VG_(threads)[i].status == VgTs_Empty) continue; 120 VG_(printf)( "\nThread %d: status = %s\n", i, 121 VG_(name_of_ThreadStatus)(VG_(threads)[i].status) ); 122 VG_(get_and_pp_StackTrace)( i, BACKTRACE_DEPTH ); 123 } 124 VG_(printf)("\n"); 125} 126 127__attribute__ ((noreturn)) 128static void report_and_quit ( const Char* report, 129 Addr ip, Addr sp, Addr fp, Addr lr ) 130{ 131 Addr stacktop; 132 Addr ips[BACKTRACE_DEPTH]; 133 Int n_ips; 134 ThreadState *tst 135 = VG_(get_ThreadState)( VG_(lwpid_to_vgtid)( VG_(gettid)() ) ); 136 137 // If necessary, fake up an ExeContext which is of our actual real CPU 138 // state. Could cause problems if we got the panic/exception within the 139 // execontext/stack dump/symtab code. But it's better than nothing. 140 if (0 == ip && 0 == sp && 0 == fp) { 141 GET_REAL_PC_SP_AND_FP(ip, sp, fp); 142 } 143 144 stacktop = tst->os_state.valgrind_stack_init_SP; 145 146 n_ips = 147 VG_(get_StackTrace_wrk)( 148 0/*tid is unknown*/, 149 ips, BACKTRACE_DEPTH, 150 NULL/*array to dump SP values in*/, 151 NULL/*array to dump FP values in*/, 152 ip, sp, fp, lr, sp, stacktop 153 ); 154 VG_(pp_StackTrace) (ips, n_ips); 155 156 VG_(show_sched_status)(); 157 VG_(printf)( 158 "\n" 159 "Note: see also the FAQ in the source distribution.\n" 160 "It contains workarounds to several common problems.\n" 161 "In particular, if Valgrind aborted or crashed after\n" 162 "identifying problems in your program, there's a good chance\n" 163 "that fixing those problems will prevent Valgrind aborting or\n" 164 "crashing, especially if it happened in m_mallocfree.c.\n" 165 "\n" 166 "If that doesn't help, please report this bug to: %s\n\n" 167 "In the bug report, send all the above text, the valgrind\n" 168 "version, and what OS and version you are using. Thanks.\n\n", 169 report); 170 VG_(exit)(1); 171} 172 173void VG_(assert_fail) ( Bool isCore, const Char* expr, const Char* file, 174 Int line, const Char* fn, const HChar* format, ... ) 175{ 176 va_list vargs; 177 Char buf[256]; 178 Char* component; 179 Char* bugs_to; 180 181 static Bool entered = False; 182 if (entered) 183 VG_(exit)(2); 184 entered = True; 185 186 va_start(vargs, format); 187 VG_(vsprintf) ( buf, format, vargs ); 188 va_end(vargs); 189 190 if (isCore) { 191 component = "valgrind"; 192 bugs_to = VG_BUGS_TO; 193 } else { 194 component = VG_(details).name; 195 bugs_to = VG_(details).bug_reports_to; 196 } 197 198 if (VG_(clo_xml)) 199 VG_UMSG("</valgrindoutput>\n"); 200 201 // Treat vg_assert2(0, "foo") specially, as a panicky abort 202 if (VG_STREQ(expr, "0")) { 203 VG_(printf)("\n%s: %s:%d (%s): the 'impossible' happened.\n", 204 component, file, line, fn ); 205 } else { 206 VG_(printf)("\n%s: %s:%d (%s): Assertion '%s' failed.\n", 207 component, file, line, fn, expr ); 208 } 209 if (!VG_STREQ(buf, "")) 210 VG_(printf)("%s: %s\n", component, buf ); 211 212 report_and_quit(bugs_to, 0,0,0,0); 213} 214 215__attribute__ ((noreturn)) 216static void panic ( Char* name, Char* report, Char* str, 217 Addr ip, Addr sp, Addr fp, Addr lr ) 218{ 219 if (VG_(clo_xml)) 220 VG_UMSG("</valgrindoutput>\n"); 221 VG_(printf)("\n%s: the 'impossible' happened:\n %s\n", name, str); 222 report_and_quit(report, ip, sp, fp, lr); 223} 224 225void VG_(core_panic_at) ( Char* str, Addr ip, Addr sp, Addr fp, Addr lr ) 226{ 227 panic("valgrind", VG_BUGS_TO, str, ip, sp, fp, lr); 228} 229 230void VG_(core_panic) ( Char* str ) 231{ 232 VG_(core_panic_at)(str, 0,0,0,0); 233} 234 235void VG_(tool_panic) ( Char* str ) 236{ 237 panic(VG_(details).name, VG_(details).bug_reports_to, str, 0,0,0,0); 238} 239 240/* Print some helpful-ish text about unimplemented things, and give up. */ 241void VG_(unimplemented) ( Char* msg ) 242{ 243 if (VG_(clo_xml)) 244 VG_UMSG("</valgrindoutput>\n"); 245 VG_UMSG(""); 246 VG_UMSG("Valgrind detected that your program requires"); 247 VG_UMSG("the following unimplemented functionality:"); 248 VG_UMSG(" %s", msg); 249 VG_UMSG("This may be because the functionality is hard to implement,"); 250 VG_UMSG("or because no reasonable program would behave this way,"); 251 VG_UMSG("or because nobody has yet needed it. In any case, let us know at"); 252 VG_UMSG("%s and/or try to work around the problem, if you can.", VG_BUGS_TO); 253 VG_UMSG(""); 254 VG_UMSG("Valgrind has to exit now. Sorry. Bye!"); 255 VG_UMSG(""); 256 VG_(show_sched_status)(); 257 VG_(exit)(1); 258} 259 260/*--------------------------------------------------------------------*/ 261/*--- end ---*/ 262/*--------------------------------------------------------------------*/ 263 264