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 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am
index d5c2ef9..1068b7d 100644
--- a/coregrind/Makefile.am
+++ b/coregrind/Makefile.am
@@ -47,6 +47,7 @@
 	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 @@
 	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 f88ca58..b119873 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 <sys/ptrace.h>
 
diff --git a/coregrind/core.h b/coregrind/core.h
index 25c8ee4..97ccf8b 100644
--- a/coregrind/core.h
+++ b/coregrind/core.h
@@ -96,38 +96,6 @@
    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 77ed861..dc12410 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 ded33e6..ab18b87 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 7e20cc1..1797171 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 2cde637..a6b4a05 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 aa117a3..3bc57b2 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 94d2b32..43f0f4c 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 4eae1ed..ad6d193 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 174961f..ac147f4 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 e854c04..ec32a3a 100644
--- a/coregrind/m_demangle/cplus-dem.c
+++ b/coregrind/m_demangle/cplus-dem.c
@@ -39,6 +39,7 @@
 #include "safe-ctype.h"
 #include "core.h"
 #include "pub_core_libcbase.h"
+#include "pub_core_libcassert.h"
 #include "pub_tool_libcprint.h"
 
 /*#include <sys/types.h>
diff --git a/coregrind/m_demangle/dyn-string.c b/coregrind/m_demangle/dyn-string.c
index c5ef672..a51d455 100644
--- a/coregrind/m_demangle/dyn-string.c
+++ b/coregrind/m_demangle/dyn-string.c
@@ -33,6 +33,7 @@
 
 #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 fe36d22..71ae7ce 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 f53f151..01270d0 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 d9748aa..c3b6e3c 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 0000000..b5c5373
--- /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 be5701c..f782c48 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 d64272b..7a2e424 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 3c09ef9..235c923 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 2f72aa3..965503a 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 81afc96..bfcb1b2 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 5455ce7..43a5378 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 8d06651..5db9e58 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 33593bc..19c859e 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 f760586..e94f888 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 36d5736..cfe0f23 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 17ee897..4bbc33a 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 d9845cd..8af639e 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 e96bb2e..355034b 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 165a97f..00f5238 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 e4cd267..691be02 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 dfc9ff6..0a7cbee 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 b9916af..dc06c85 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 @@
 /* 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 9da8aae..86b1272 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 8cc1699..a3f4dc0 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 0000000..1453669
--- /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 9486dac..bc00797 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"
@@ -438,157 +439,6 @@
 }
 
 /* ---------------------------------------------------------------------
-   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 0c98d48..476459c 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 <sys/ptrace.h>