From: Nicholas Nethercote Date: Sat, 4 Jun 2005 19:16:06 +0000 (+0000) Subject: Modularised assertions and panics in m_libcassert. X-Git-Tag: svn/VALGRIND_3_0_0~476 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=eb2d0a7d06d70e8fd129f035613ee68494ae7bd2;p=thirdparty%2Fvalgrind.git Modularised assertions and panics in m_libcassert. As part of this, killed the VG_STRINGIFY macro, which was used to expand out names like "VG_(foo)" and "vgPlain_foo" in assertion failure messages. This is good since we actually want the "VG_(foo)" form used in these messages. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3842 --- diff --git a/cachegrind/cg_main.c b/cachegrind/cg_main.c index 1c13db3b1b..a7bfd6b2d0 100644 --- a/cachegrind/cg_main.c +++ b/cachegrind/cg_main.c @@ -33,6 +33,7 @@ #include "pub_tool_debuginfo.h" #include "pub_tool_hashtable.h" #include "pub_tool_libcbase.h" +#include "pub_tool_libcassert.h" #include "pub_tool_libcprint.h" #include "pub_tool_mallocfree.h" #include "pub_tool_options.h" diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am index d5c2ef9010..1068b7dec6 100644 --- a/coregrind/Makefile.am +++ b/coregrind/Makefile.am @@ -47,6 +47,7 @@ noinst_HEADERS = \ pub_core_execontext.h \ pub_core_hashtable.h \ pub_core_libcbase.h \ + pub_core_libcassert.h \ pub_core_libcprint.h \ pub_core_main.h \ pub_core_mallocfree.h \ @@ -90,6 +91,7 @@ stage2_SOURCES = \ m_execontext.c \ m_hashtable.c \ m_libcbase.c \ + m_libcassert.c \ m_libcprint.c \ m_main.c \ m_mallocfree.c \ diff --git a/coregrind/amd64/state.c b/coregrind/amd64/state.c index f88ca584d0..b119873174 100644 --- a/coregrind/amd64/state.c +++ b/coregrind/amd64/state.c @@ -30,6 +30,7 @@ #include "core.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_tooliface.h" #include diff --git a/coregrind/core.h b/coregrind/core.h index 25c8ee41af..97ccf8bbb6 100644 --- a/coregrind/core.h +++ b/coregrind/core.h @@ -96,38 +96,6 @@ extern Int VG_(fd_hard_limit); Exports of vg_mylibc.c ------------------------------------------------------------------ */ -// Useful for making failing stubs, when certain things haven't yet been -// implemented. -#define I_die_here \ - VG_(assert_fail) (/*isCore*//*BOGUS*/True, \ - "Unimplemented functionality", \ - __FILE__, __LINE__, __PRETTY_FUNCTION__, \ - "valgrind", VG_BUGS_TO, "") - -#define vg_assert(expr) \ - ((void) ((expr) ? 0 : \ - (VG_(assert_fail) (/*isCore*/True, VG_STRINGIFY(expr), \ - __FILE__, __LINE__, __PRETTY_FUNCTION__, \ - ""), \ - 0))) - -#define vg_assert2(expr, format, args...) \ - ((void) ((expr) ? 0 : \ - (VG_(assert_fail) (/*isCore*/True, VG_STRINGIFY(expr), \ - __FILE__, __LINE__, __PRETTY_FUNCTION__, \ - format, ##args), \ - 0))) - -__attribute__ ((__noreturn__)) -extern void VG_(core_panic) ( Char* str ); -__attribute__ ((__noreturn__)) -extern void VG_(core_panic_at) ( Char* str, Addr ip, Addr sp, Addr fp ); - -/* Called when some unhandleable client behaviour is detected. - Prints a msg and aborts. */ -extern void VG_(unimplemented) ( Char* msg ) - __attribute__((__noreturn__)); - /* Tools use VG_(strdup)() which doesn't expose ArenaId */ extern Char* VG_(arena_strdup) ( ArenaId aid, const Char* s); diff --git a/coregrind/linux/core_os.c b/coregrind/linux/core_os.c index 77ed8618e8..dc1241033e 100644 --- a/coregrind/linux/core_os.c +++ b/coregrind/linux/core_os.c @@ -30,6 +30,7 @@ #include "core.h" #include "pub_core_debuglog.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_options.h" #include "pub_core_signals.h" diff --git a/coregrind/m_aspacemgr/aspacemgr.c b/coregrind/m_aspacemgr/aspacemgr.c index ded33e6e0d..ab18b87407 100644 --- a/coregrind/m_aspacemgr/aspacemgr.c +++ b/coregrind/m_aspacemgr/aspacemgr.c @@ -33,6 +33,7 @@ #include "core.h" #include "pub_core_aspacemgr.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_options.h" #include "pub_core_syscalls.h" diff --git a/coregrind/m_aspacemgr/read_procselfmaps.c b/coregrind/m_aspacemgr/read_procselfmaps.c index 7e20cc1624..1797171023 100644 --- a/coregrind/m_aspacemgr/read_procselfmaps.c +++ b/coregrind/m_aspacemgr/read_procselfmaps.c @@ -33,6 +33,7 @@ #include "core.h" #include "pub_core_aspacemgr.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" /* Size of a smallish table used to read /proc/self/map entries. */ diff --git a/coregrind/m_debuginfo/dwarf.c b/coregrind/m_debuginfo/dwarf.c index 2cde63765a..a6b4a05f1b 100644 --- a/coregrind/m_debuginfo/dwarf.c +++ b/coregrind/m_debuginfo/dwarf.c @@ -30,6 +30,7 @@ #include "core.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_options.h" #include "priv_symtab.h" diff --git a/coregrind/m_debuginfo/stabs.c b/coregrind/m_debuginfo/stabs.c index aa117a359e..3bc57b2fdf 100644 --- a/coregrind/m_debuginfo/stabs.c +++ b/coregrind/m_debuginfo/stabs.c @@ -30,6 +30,7 @@ #include "core.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "priv_symtab.h" diff --git a/coregrind/m_debuginfo/symtab.c b/coregrind/m_debuginfo/symtab.c index 94d2b323bf..43f0f4c5d2 100644 --- a/coregrind/m_debuginfo/symtab.c +++ b/coregrind/m_debuginfo/symtab.c @@ -33,6 +33,7 @@ #include "pub_core_aspacemgr.h" #include "pub_core_demangle.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_options.h" #include "pub_core_profile.h" diff --git a/coregrind/m_debuginfo/symtypes.c b/coregrind/m_debuginfo/symtypes.c index 4eae1ed5eb..ad6d193af6 100644 --- a/coregrind/m_debuginfo/symtypes.c +++ b/coregrind/m_debuginfo/symtypes.c @@ -32,6 +32,7 @@ #include "pub_core_debuginfo.h" #include "pub_core_debuglog.h" /* VG_(debugLog_vprintf) */ #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_tooliface.h" #include "priv_symtypes.h" diff --git a/coregrind/m_demangle/cp-demangle.c b/coregrind/m_demangle/cp-demangle.c index 174961fcc4..ac147f49d0 100644 --- a/coregrind/m_demangle/cp-demangle.c +++ b/coregrind/m_demangle/cp-demangle.c @@ -42,6 +42,7 @@ #include "core.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "ansidecl.h" #include "dyn-string.h" #include "demangle.h" diff --git a/coregrind/m_demangle/cplus-dem.c b/coregrind/m_demangle/cplus-dem.c index e854c04c8f..ec32a3a728 100644 --- a/coregrind/m_demangle/cplus-dem.c +++ b/coregrind/m_demangle/cplus-dem.c @@ -39,6 +39,7 @@ Boston, MA 02111-1307, USA. */ #include "safe-ctype.h" #include "core.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_tool_libcprint.h" /*#include diff --git a/coregrind/m_demangle/dyn-string.c b/coregrind/m_demangle/dyn-string.c index c5ef67252f..a51d455985 100644 --- a/coregrind/m_demangle/dyn-string.c +++ b/coregrind/m_demangle/dyn-string.c @@ -33,6 +33,7 @@ Boston, MA 02111-1307, USA. */ #include "core.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "ansidecl.h" #include "dyn-string.h" diff --git a/coregrind/m_errormgr.c b/coregrind/m_errormgr.c index fe36d2291e..71ae7ceb2b 100644 --- a/coregrind/m_errormgr.c +++ b/coregrind/m_errormgr.c @@ -33,6 +33,7 @@ #include "pub_core_errormgr.h" #include "pub_core_execontext.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_main.h" // for VG_(start_debugger)() #include "pub_core_options.h" diff --git a/coregrind/m_execontext.c b/coregrind/m_execontext.c index f53f151d7e..01270d0ad3 100644 --- a/coregrind/m_execontext.c +++ b/coregrind/m_execontext.c @@ -30,6 +30,7 @@ #include "core.h" #include "pub_core_execontext.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_options.h" #include "pub_core_profile.h" diff --git a/coregrind/m_hashtable.c b/coregrind/m_hashtable.c index d9748aab84..c3b6e3c4d1 100644 --- a/coregrind/m_hashtable.c +++ b/coregrind/m_hashtable.c @@ -30,6 +30,7 @@ #include "core.h" #include "pub_core_hashtable.h" +#include "pub_core_libcassert.h" /*--------------------------------------------------------------------*/ /*--- Declarations ---*/ diff --git a/coregrind/m_libcassert.c b/coregrind/m_libcassert.c new file mode 100644 index 0000000000..b5c5373575 --- /dev/null +++ b/coregrind/m_libcassert.c @@ -0,0 +1,194 @@ + +/*--------------------------------------------------------------------*/ +/*--- Assertions and panics. m_libcassert.c ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2000-2005 Julian Seward + jseward@acm.org + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#include "core.h" +#include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" +#include "pub_core_libcprint.h" +#include "pub_core_main.h" +#include "pub_core_stacktrace.h" +#include "pub_core_tooliface.h" + +/* --------------------------------------------------------------------- + Assertery. + ------------------------------------------------------------------ */ + +#if defined(VGP_x86_linux) +# define GET_REAL_SP_AND_FP(sp, fp) \ + asm("movl %%esp, %0;" \ + "movl %%ebp, %1;" \ + : "=r" (sp),\ + "=r" (fp)); +#elif defined(VGP_amd64_linux) +# define GET_REAL_SP_AND_FP(sp, fp) \ + asm("movq %%rsp, %0;" \ + "movq %%rbp, %1;" \ + : "=r" (sp),\ + "=r" (fp)); +#else +# error Unknown platform +#endif + +__attribute__ ((noreturn)) +static void report_and_quit ( const Char* report, Addr ip, Addr sp, Addr fp ) +{ + #define BACKTRACE_DEPTH 100 // nice and deep! + Addr stacktop, ips[BACKTRACE_DEPTH]; + ThreadState *tst; + + tst = VG_(get_ThreadState)( VG_(get_lwp_tid)(VG_(gettid)()) ); + + // If necessary, fake up an ExeContext which is of our actual real CPU + // state. Could cause problems if we got the panic/exception within the + // execontext/stack dump/symtab code. But it's better than nothing. + if (0 == ip && 0 == sp && 0 == fp) { + ip = (Addr)__builtin_return_address(0); + GET_REAL_SP_AND_FP(sp, fp); + } + + stacktop = tst->os_state.valgrind_stack_base + + tst->os_state.valgrind_stack_szB; + + VG_(get_StackTrace2)(ips, BACKTRACE_DEPTH, ip, sp, fp, sp, stacktop); + VG_(pp_StackTrace) (ips, BACKTRACE_DEPTH); + + VG_(printf)("\nBasic block ctr is approximately %llu\n", VG_(bbs_done) ); + + VG_(pp_sched_status)(); + VG_(printf)("\n"); + VG_(printf)("Note: see also the FAQ.txt in the source distribution.\n"); + VG_(printf)("It contains workarounds to several common problems.\n"); + VG_(printf)("\n"); + VG_(printf)("If that doesn't help, please report this bug to: %s\n\n", + report); + VG_(printf)("In the bug report, send all the above text, the valgrind\n"); + VG_(printf)("version, and what Linux distro you are using. Thanks.\n\n"); + VG_(exit)(1); + + #undef BACKTRACE_DEPTH +} + +void VG_(assert_fail) ( Bool isCore, const Char* expr, const Char* file, + Int line, const Char* fn, const HChar* format, ... ) +{ + va_list vargs; + Char buf[256]; + Char* bufptr = buf; + Char* component; + Char* bugs_to; + + static Bool entered = False; + if (entered) + VG_(exit)(2); + entered = True; + + va_start(vargs, format); + VG_(vsprintf) ( bufptr, format, vargs ); + va_end(vargs); + + if (isCore) { + component = "valgrind"; + bugs_to = VG_BUGS_TO; + } else { + component = VG_(details).name; + bugs_to = VG_(details).bug_reports_to; + } + + // Treat vg_assert2(0, "foo") specially, as a panicky abort + if (VG_STREQ(expr, "0")) { + VG_(printf)("\n%s: %s:%d (%s): the 'impossible' happened.\n", + component, file, line, fn, expr ); + } else { + VG_(printf)("\n%s: %s:%d (%s): Assertion '%s' failed.\n", + component, file, line, fn, expr ); + } + if (!VG_STREQ(buf, "")) + VG_(printf)("%s: %s\n", component, buf ); + + report_and_quit(bugs_to, 0,0,0); +} + +__attribute__ ((noreturn)) +static void panic ( Char* name, Char* report, Char* str, + Addr ip, Addr sp, Addr fp ) +{ + VG_(printf)("\n%s: the 'impossible' happened:\n %s\n", name, str); + report_and_quit(report, ip, sp, fp); +} + +void VG_(core_panic_at) ( Char* str, Addr ip, Addr sp, Addr fp ) +{ + panic("valgrind", VG_BUGS_TO, str, ip, sp, fp); +} + +void VG_(core_panic) ( Char* str ) +{ + VG_(core_panic_at)(str, 0,0,0); +} + +void VG_(tool_panic) ( Char* str ) +{ + panic(VG_(details).name, VG_(details).bug_reports_to, str, 0,0,0); +} + +/* Print some helpful-ish text about unimplemented things, and give + up. */ +void VG_(unimplemented) ( Char* msg ) +{ + VG_(message)(Vg_UserMsg, ""); + VG_(message)(Vg_UserMsg, + "Valgrind detected that your program requires"); + VG_(message)(Vg_UserMsg, + "the following unimplemented functionality:"); + VG_(message)(Vg_UserMsg, " %s", msg); + VG_(message)(Vg_UserMsg, + "This may be because the functionality is hard to implement,"); + VG_(message)(Vg_UserMsg, + "or because no reasonable program would behave this way,"); + VG_(message)(Vg_UserMsg, + "or because nobody has yet needed it. In any case, let us know at"); + VG_(message)(Vg_UserMsg, + "%s and/or try to work around the problem, if you can.", VG_BUGS_TO); + VG_(message)(Vg_UserMsg, + ""); + VG_(message)(Vg_UserMsg, + "Valgrind has to exit now. Sorry. Bye!"); + VG_(message)(Vg_UserMsg, + ""); + VG_(pp_sched_status)(); + VG_(exit)(1); +} + + + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ + diff --git a/coregrind/m_libcprint.c b/coregrind/m_libcprint.c index be5701cc6c..f782c48841 100644 --- a/coregrind/m_libcprint.c +++ b/coregrind/m_libcprint.c @@ -31,6 +31,7 @@ #include "core.h" #include "pub_core_debuglog.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_options.h" #include "valgrind.h" // for RUNNING_ON_VALGRIND diff --git a/coregrind/m_main.c b/coregrind/m_main.c index d64272bc0d..7a2e424ff1 100644 --- a/coregrind/m_main.c +++ b/coregrind/m_main.c @@ -37,6 +37,7 @@ #include "pub_core_errormgr.h" #include "pub_core_execontext.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_main.h" #include "pub_core_options.h" diff --git a/coregrind/m_mallocfree.c b/coregrind/m_mallocfree.c index 3c09ef92e8..235c923bb1 100644 --- a/coregrind/m_mallocfree.c +++ b/coregrind/m_mallocfree.c @@ -33,6 +33,7 @@ #include "core.h" #include "pub_core_aspacemgr.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_options.h" #include "pub_core_profile.h" diff --git a/coregrind/m_profile.c b/coregrind/m_profile.c index 2f72aa308d..965503abbb 100644 --- a/coregrind/m_profile.c +++ b/coregrind/m_profile.c @@ -29,6 +29,7 @@ */ #include "core.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_profile.h" diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c index 81afc96c61..bfcb1b26f1 100644 --- a/coregrind/m_redir.c +++ b/coregrind/m_redir.c @@ -33,6 +33,7 @@ #include "pub_core_aspacemgr.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_skiplist.h" #include "pub_core_options.h" diff --git a/coregrind/m_scheduler/scheduler.c b/coregrind/m_scheduler/scheduler.c index 5455ce7e7b..43a537818a 100644 --- a/coregrind/m_scheduler/scheduler.c +++ b/coregrind/m_scheduler/scheduler.c @@ -64,6 +64,7 @@ #include "pub_core_dispatch.h" #include "pub_core_errormgr.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_main.h" #include "pub_core_options.h" diff --git a/coregrind/m_scheduler/sema.c b/coregrind/m_scheduler/sema.c index 8d06651fb3..5db9e58791 100644 --- a/coregrind/m_scheduler/sema.c +++ b/coregrind/m_scheduler/sema.c @@ -29,6 +29,7 @@ */ #include "core.h" +#include "pub_core_libcassert.h" #include "priv_sema.h" /* diff --git a/coregrind/m_sigframe/sigframe-amd64-linux.c b/coregrind/m_sigframe/sigframe-amd64-linux.c index 33593bc96f..19c859e1b9 100644 --- a/coregrind/m_sigframe/sigframe-amd64-linux.c +++ b/coregrind/m_sigframe/sigframe-amd64-linux.c @@ -32,6 +32,7 @@ #include "core.h" #include "pub_core_aspacemgr.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_options.h" #include "pub_core_sigframe.h" diff --git a/coregrind/m_sigframe/sigframe-x86-linux.c b/coregrind/m_sigframe/sigframe-x86-linux.c index f760586935..e94f888d0f 100644 --- a/coregrind/m_sigframe/sigframe-x86-linux.c +++ b/coregrind/m_sigframe/sigframe-x86-linux.c @@ -32,6 +32,7 @@ #include "core.h" #include "pub_core_aspacemgr.h" /* find_segment */ #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_options.h" #include "pub_core_sigframe.h" diff --git a/coregrind/m_signals.c b/coregrind/m_signals.c index 36d57361f6..cfe0f23c97 100644 --- a/coregrind/m_signals.c +++ b/coregrind/m_signals.c @@ -84,6 +84,7 @@ #include "pub_core_aspacemgr.h" #include "pub_core_errormgr.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_main.h" #include "pub_core_options.h" diff --git a/coregrind/m_skiplist.c b/coregrind/m_skiplist.c index 17ee897c9c..4bbc33aace 100644 --- a/coregrind/m_skiplist.c +++ b/coregrind/m_skiplist.c @@ -88,6 +88,7 @@ #include "core.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_skiplist.h" diff --git a/coregrind/m_stacktrace.c b/coregrind/m_stacktrace.c index d9845cd2bf..8af639eec5 100644 --- a/coregrind/m_stacktrace.c +++ b/coregrind/m_stacktrace.c @@ -31,6 +31,7 @@ #include "core.h" #include "pub_core_aspacemgr.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_options.h" #include "pub_core_profile.h" diff --git a/coregrind/m_syscalls/syscalls-amd64-linux.c b/coregrind/m_syscalls/syscalls-amd64-linux.c index e96bb2ea50..355034b5f6 100644 --- a/coregrind/m_syscalls/syscalls-amd64-linux.c +++ b/coregrind/m_syscalls/syscalls-amd64-linux.c @@ -32,6 +32,7 @@ #include "ume.h" /* for jmp_with_stack */ #include "pub_core_debuglog.h" #include "pub_core_aspacemgr.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_sigframe.h" #include "pub_core_syscalls.h" diff --git a/coregrind/m_syscalls/syscalls-linux.c b/coregrind/m_syscalls/syscalls-linux.c index 165a97f5aa..00f5238e88 100644 --- a/coregrind/m_syscalls/syscalls-linux.c +++ b/coregrind/m_syscalls/syscalls-linux.c @@ -30,6 +30,7 @@ #include "core.h" #include "pub_core_aspacemgr.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_tooliface.h" #include "priv_syscalls.h" diff --git a/coregrind/m_syscalls/syscalls-x86-linux.c b/coregrind/m_syscalls/syscalls-x86-linux.c index e4cd2675c8..691be02780 100644 --- a/coregrind/m_syscalls/syscalls-x86-linux.c +++ b/coregrind/m_syscalls/syscalls-x86-linux.c @@ -37,6 +37,7 @@ #include "ume.h" /* for jmp_with_stack */ #include "pub_core_debuglog.h" #include "pub_core_aspacemgr.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_sigframe.h" #include "pub_core_syscalls.h" diff --git a/coregrind/m_syscalls/syscalls.c b/coregrind/m_syscalls/syscalls.c index dfc9ff6010..0a7cbee744 100644 --- a/coregrind/m_syscalls/syscalls.c +++ b/coregrind/m_syscalls/syscalls.c @@ -32,6 +32,7 @@ #include "pub_core_debuglog.h" #include "pub_core_aspacemgr.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_main.h" #include "pub_core_profile.h" diff --git a/coregrind/m_tooliface.c b/coregrind/m_tooliface.c index b9916af471..dc06c8518d 100644 --- a/coregrind/m_tooliface.c +++ b/coregrind/m_tooliface.c @@ -31,6 +31,7 @@ #include "core.h" #include "pub_core_tooliface.h" +#include "pub_core_libcbase.h" #include "pub_core_libcprint.h" // The core/tool dictionary of functions (initially zeroed, as we want it) @@ -100,11 +101,10 @@ VgNeeds VG_(needs) = { /* static */ void VG_(sanity_check_needs) ( void) { -#define CHECK_NOT(var, value) \ - if ((var)==(value)) { \ - VG_(printf)("\nTool error: '%s' not initialised\n", \ - VG_STRINGIFY(var)); \ - VG_(tool_panic)("Uninitialised details field\n"); \ +#define CHECK_NOT(var, value) \ + if ((var)==(value)) { \ + VG_(printf)("\nTool error: '%s' not initialised\n", #var);\ + VG_(tool_panic)("Uninitialised details field\n"); \ } /* Ones that must be set */ diff --git a/coregrind/m_translate.c b/coregrind/m_translate.c index 9da8aaeb21..86b127280a 100644 --- a/coregrind/m_translate.c +++ b/coregrind/m_translate.c @@ -32,6 +32,7 @@ #include "core.h" #include "pub_core_aspacemgr.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_main.h" // for VG_(bbs_done) #include "pub_core_options.h" diff --git a/coregrind/m_transtab.c b/coregrind/m_transtab.c index 8cc16997d6..a3f4dc000a 100644 --- a/coregrind/m_transtab.c +++ b/coregrind/m_transtab.c @@ -32,6 +32,7 @@ #include "core.h" #include "pub_core_debuginfo.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_options.h" #include "pub_core_tooliface.h" diff --git a/coregrind/pub_core_libcassert.h b/coregrind/pub_core_libcassert.h new file mode 100644 index 0000000000..1453669690 --- /dev/null +++ b/coregrind/pub_core_libcassert.h @@ -0,0 +1,77 @@ + +/*--------------------------------------------------------------------*/ +/*--- Assertions, etc. pub_core_libcassert.h ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2000-2005 Julian Seward + jseward@acm.org + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#ifndef __PUB_CORE_LIBCASSERT_H +#define __PUB_CORE_LIBCASSERT_H + +//-------------------------------------------------------------------- +// PURPOSE: This module contains all the libc code related to assertions, +// panics and aborting. +//-------------------------------------------------------------------- + +#include "pub_tool_libcassert.h" + +// Useful for making failing stubs, when certain things haven't yet been +// implemented. +#define I_die_here \ + VG_(assert_fail) (/*isCore*//*BOGUS*/True, \ + "Unimplemented functionality", \ + __FILE__, __LINE__, __PRETTY_FUNCTION__, \ + "valgrind", VG_BUGS_TO, "") + +#define vg_assert(expr) \ + ((void) ((expr) ? 0 : \ + (VG_(assert_fail) (/*isCore*/True, #expr, \ + __FILE__, __LINE__, __PRETTY_FUNCTION__, \ + ""), \ + 0))) + +#define vg_assert2(expr, format, args...) \ + ((void) ((expr) ? 0 : \ + (VG_(assert_fail) (/*isCore*/True, #expr, \ + __FILE__, __LINE__, __PRETTY_FUNCTION__, \ + format, ##args), \ + 0))) + +__attribute__ ((__noreturn__)) +extern void VG_(core_panic) ( Char* str ); +__attribute__ ((__noreturn__)) +extern void VG_(core_panic_at) ( Char* str, Addr ip, Addr sp, Addr fp ); + +/* Called when some unhandleable client behaviour is detected. + Prints a msg and aborts. */ +extern void VG_(unimplemented) ( Char* msg ) + __attribute__((__noreturn__)); + +#endif // __PUB_CORE_LIBCASSERT_H + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ diff --git a/coregrind/vg_mylibc.c b/coregrind/vg_mylibc.c index 9486dac0e0..bc00797ad0 100644 --- a/coregrind/vg_mylibc.c +++ b/coregrind/vg_mylibc.c @@ -34,6 +34,7 @@ #include "pub_core_aspacemgr.h" #include "pub_core_debuglog.h" /* VG_(debugLog_vprintf) */ #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_main.h" #include "pub_core_options.h" @@ -437,157 +438,6 @@ Char* VG_(strdup) ( const Char* s ) return VG_(arena_strdup) ( VG_AR_TOOL, s ); } -/* --------------------------------------------------------------------- - Assertery. - ------------------------------------------------------------------ */ - -#if defined(VGP_x86_linux) -# define GET_REAL_SP_AND_FP(sp, fp) \ - asm("movl %%esp, %0;" \ - "movl %%ebp, %1;" \ - : "=r" (sp),\ - "=r" (fp)); -#elif defined(VGP_amd64_linux) -# define GET_REAL_SP_AND_FP(sp, fp) \ - asm("movq %%rsp, %0;" \ - "movq %%rbp, %1;" \ - : "=r" (sp),\ - "=r" (fp)); -#else -# error Unknown platform -#endif - -__attribute__ ((noreturn)) -static void report_and_quit ( const Char* report, Addr ip, Addr sp, Addr fp ) -{ - #define BACKTRACE_DEPTH 100 // nice and deep! - Addr stacktop, ips[BACKTRACE_DEPTH]; - ThreadState *tst; - - tst = VG_(get_ThreadState)( VG_(get_lwp_tid)(VG_(gettid)()) ); - - // If necessary, fake up an ExeContext which is of our actual real CPU - // state. Could cause problems if we got the panic/exception within the - // execontext/stack dump/symtab code. But it's better than nothing. - if (0 == ip && 0 == sp && 0 == fp) { - ip = (Addr)__builtin_return_address(0); - GET_REAL_SP_AND_FP(sp, fp); - } - - stacktop = tst->os_state.valgrind_stack_base + - tst->os_state.valgrind_stack_szB; - - VG_(get_StackTrace2)(ips, BACKTRACE_DEPTH, ip, sp, fp, sp, stacktop); - VG_(pp_StackTrace) (ips, BACKTRACE_DEPTH); - - VG_(printf)("\nBasic block ctr is approximately %llu\n", VG_(bbs_done) ); - - VG_(pp_sched_status)(); - VG_(printf)("\n"); - VG_(printf)("Note: see also the FAQ.txt in the source distribution.\n"); - VG_(printf)("It contains workarounds to several common problems.\n"); - VG_(printf)("\n"); - VG_(printf)("If that doesn't help, please report this bug to: %s\n\n", - report); - VG_(printf)("In the bug report, send all the above text, the valgrind\n"); - VG_(printf)("version, and what Linux distro you are using. Thanks.\n\n"); - VG_(exit)(1); - - #undef BACKTRACE_DEPTH -} - -void VG_(assert_fail) ( Bool isCore, const Char* expr, const Char* file, - Int line, const Char* fn, const HChar* format, ... ) -{ - va_list vargs; - Char buf[256]; - Char* bufptr = buf; - Char* component; - Char* bugs_to; - - static Bool entered = False; - if (entered) - VG_(exit)(2); - entered = True; - - va_start(vargs, format); - VG_(vsprintf) ( bufptr, format, vargs ); - va_end(vargs); - - if (isCore) { - component = "valgrind"; - bugs_to = VG_BUGS_TO; - } else { - component = VG_(details).name; - bugs_to = VG_(details).bug_reports_to; - } - - // Treat vg_assert2(0, "foo") specially, as a panicky abort - if (VG_STREQ(expr, "0")) { - VG_(printf)("\n%s: %s:%d (%s): the 'impossible' happened.\n", - component, file, line, fn, expr ); - } else { - VG_(printf)("\n%s: %s:%d (%s): Assertion '%s' failed.\n", - component, file, line, fn, expr ); - } - if (!VG_STREQ(buf, "")) - VG_(printf)("%s: %s\n", component, buf ); - - report_and_quit(bugs_to, 0,0,0); -} - -__attribute__ ((noreturn)) -static void panic ( Char* name, Char* report, Char* str, - Addr ip, Addr sp, Addr fp ) -{ - VG_(printf)("\n%s: the 'impossible' happened:\n %s\n", name, str); - report_and_quit(report, ip, sp, fp); -} - -void VG_(core_panic_at) ( Char* str, Addr ip, Addr sp, Addr fp ) -{ - panic("valgrind", VG_BUGS_TO, str, ip, sp, fp); -} - -void VG_(core_panic) ( Char* str ) -{ - VG_(core_panic_at)(str, 0,0,0); -} - -void VG_(tool_panic) ( Char* str ) -{ - panic(VG_(details).name, VG_(details).bug_reports_to, str, 0,0,0); -} - -/* Print some helpful-ish text about unimplemented things, and give - up. */ -void VG_(unimplemented) ( Char* msg ) -{ - VG_(message)(Vg_UserMsg, ""); - VG_(message)(Vg_UserMsg, - "Valgrind detected that your program requires"); - VG_(message)(Vg_UserMsg, - "the following unimplemented functionality:"); - VG_(message)(Vg_UserMsg, " %s", msg); - VG_(message)(Vg_UserMsg, - "This may be because the functionality is hard to implement,"); - VG_(message)(Vg_UserMsg, - "or because no reasonable program would behave this way,"); - VG_(message)(Vg_UserMsg, - "or because nobody has yet needed it. In any case, let us know at"); - VG_(message)(Vg_UserMsg, - "%s and/or try to work around the problem, if you can.", VG_BUGS_TO); - VG_(message)(Vg_UserMsg, - ""); - VG_(message)(Vg_UserMsg, - "Valgrind has to exit now. Sorry. Bye!"); - VG_(message)(Vg_UserMsg, - ""); - VG_(pp_sched_status)(); - VG_(exit)(1); -} - - /* --------------------------------------------------------------------- Primitive support for reading files. ------------------------------------------------------------------ */ diff --git a/coregrind/x86/state.c b/coregrind/x86/state.c index 0c98d480a7..476459c9d1 100644 --- a/coregrind/x86/state.c +++ b/coregrind/x86/state.c @@ -30,6 +30,7 @@ #include "core.h" #include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" #include "pub_core_tooliface.h" #include "vki_unistd.h" #include diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c index d23fe7a574..f69311eab6 100644 --- a/helgrind/hg_main.c +++ b/helgrind/hg_main.c @@ -33,6 +33,7 @@ #include "pub_tool_debuginfo.h" #include "pub_tool_hashtable.h" #include "pub_tool_libcbase.h" +#include "pub_tool_libcassert.h" #include "pub_tool_libcprint.h" #include "pub_tool_mallocfree.h" #include "pub_tool_options.h" diff --git a/include/Makefile.am b/include/Makefile.am index aac22923e1..b087a30c36 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -9,6 +9,7 @@ incinc_HEADERS = \ pub_tool_execontext.h \ pub_tool_hashtable.h \ pub_tool_libcbase.h \ + pub_tool_libcassert.h \ pub_tool_libcprint.h \ pub_tool_mallocfree.h \ pub_tool_options.h \ diff --git a/include/pub_tool_libcassert.h b/include/pub_tool_libcassert.h new file mode 100644 index 0000000000..22a46e08a2 --- /dev/null +++ b/include/pub_tool_libcassert.h @@ -0,0 +1,57 @@ + +/*--------------------------------------------------------------------*/ +/*--- Assertions, etc. pub_tool_libcassert.h ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2000-2005 Julian Seward + jseward@acm.org + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#ifndef __PUB_TOOL_LIBCBASSERT_H +#define __PUB_TOOL_LIBCBASSERT_H + +#define tl_assert(expr) \ + ((void) ((expr) ? 0 : \ + (VG_(assert_fail) (/*isCore?*/False, #expr, \ + __FILE__, __LINE__, __PRETTY_FUNCTION__, \ + ""), \ + 0))) + +#define tl_assert2(expr, format, args...) \ + ((void) ((expr) ? 0 : \ + (VG_(assert_fail) (/*isCore?*/False, #expr, \ + __FILE__, __LINE__, __PRETTY_FUNCTION__, \ + format, ##args), \ + 0))) + +__attribute__ ((__noreturn__)) +extern void VG_(assert_fail) ( Bool isCore, const Char* expr, const Char* file, + Int line, const Char* fn, + const HChar* format, ... ); + +#endif // __PUB_TOOL_LIBCBASSERT_H + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ diff --git a/include/tool.h b/include/tool.h index a781459d59..795a129d85 100644 --- a/include/tool.h +++ b/include/tool.h @@ -171,35 +171,6 @@ extern Char* VG_(getcwd) ( Char* buf, SizeT size ); Returns False if it fails. Will fail if the pathname is > 65535 bytes. */ extern Bool VG_(getcwd_alloc) ( Char** cwd ); -/* ------------------------------------------------------------------ */ -/* assert.h */ -/* Asserts permanently enabled -- no turning off with NDEBUG. Hurrah! */ - -/* This odd definition lets us stringify VG_(x) function names to - "vgPlain_x". We need to do two macroexpansions to get the VG_ macro - expanded before stringifying. */ -#define VG_STRINGIFY_WRK(x) #x -#define VG_STRINGIFY(x) VG_STRINGIFY_WRK(x) - -#define tl_assert(expr) \ - ((void) ((expr) ? 0 : \ - (VG_(assert_fail) (/*isCore?*/False, VG_STRINGIFY(expr), \ - __FILE__, __LINE__, __PRETTY_FUNCTION__, \ - ""), \ - 0))) - -#define tl_assert2(expr, format, args...) \ - ((void) ((expr) ? 0 : \ - (VG_(assert_fail) (/*isCore?*/False, VG_STRINGIFY(expr), \ - __FILE__, __LINE__, __PRETTY_FUNCTION__, \ - format, ##args), \ - 0))) - -__attribute__ ((__noreturn__)) -extern void VG_(assert_fail) ( Bool isCore, const Char* expr, const Char* file, - Int line, const Char* fn, - const HChar* format, ... ); - /* ------------------------------------------------------------------ */ /* Get memory by anonymous mmap. */ extern void* VG_(get_memory_from_mmap) ( SizeT nBytes, Char* who ); diff --git a/massif/ms_main.c b/massif/ms_main.c index c25147352e..aebc27d962 100644 --- a/massif/ms_main.c +++ b/massif/ms_main.c @@ -38,6 +38,7 @@ #include "pub_tool_debuginfo.h" #include "pub_tool_hashtable.h" #include "pub_tool_libcbase.h" +#include "pub_tool_libcassert.h" #include "pub_tool_libcprint.h" #include "pub_tool_mallocfree.h" #include "pub_tool_options.h" diff --git a/memcheck/mac_leakcheck.c b/memcheck/mac_leakcheck.c index 5341c0d143..82c18049f2 100644 --- a/memcheck/mac_leakcheck.c +++ b/memcheck/mac_leakcheck.c @@ -33,6 +33,7 @@ #include #include "mac_shared.h" #include "pub_tool_libcbase.h" +#include "pub_tool_libcassert.h" #include "pub_tool_libcprint.h" /* Define to debug the memory-leak-detector. */ diff --git a/memcheck/mac_malloc_wrappers.c b/memcheck/mac_malloc_wrappers.c index a888536ec7..92489beb0b 100644 --- a/memcheck/mac_malloc_wrappers.c +++ b/memcheck/mac_malloc_wrappers.c @@ -32,6 +32,7 @@ #include "mac_shared.h" #include "pub_tool_libcbase.h" +#include "pub_tool_libcassert.h" #include "pub_tool_libcprint.h" /*------------------------------------------------------------*/ diff --git a/memcheck/mac_shared.c b/memcheck/mac_shared.c index 83a8084a8f..8ac8fe9e1e 100644 --- a/memcheck/mac_shared.c +++ b/memcheck/mac_shared.c @@ -31,6 +31,7 @@ */ #include "mac_shared.h" +#include "pub_tool_libcassert.h" #include "pub_tool_libcbase.h" #include "pub_tool_libcprint.h" #include "memcheck.h" /* for VG_USERREQ__* */ diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c index a2e24db51c..da32ae2103 100644 --- a/memcheck/mc_main.c +++ b/memcheck/mc_main.c @@ -39,6 +39,7 @@ #include "mc_include.h" #include "memcheck.h" /* for client requests */ #include "pub_tool_libcbase.h" +#include "pub_tool_libcassert.h" #include "pub_tool_libcprint.h" diff --git a/memcheck/mc_translate.c b/memcheck/mc_translate.c index d4a1327c78..0900c7572f 100644 --- a/memcheck/mc_translate.c +++ b/memcheck/mc_translate.c @@ -30,6 +30,7 @@ */ #include "mc_include.h" +#include "pub_tool_libcassert.h" #include "pub_tool_libcprint.h"