// Useful for making failing stubs, when certain things haven't yet been
// implemented.
-#define I_die_here \
- VG_(core_assert_fail) ("Unimplemented functionality", \
- __FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-#define vg_assert(expr) \
- ((void) ((expr) ? 0 : \
- (VG_(core_assert_fail) (VG_STRINGIFY(expr), \
- __FILE__, __LINE__, \
- __PRETTY_FUNCTION__), 0)))
-__attribute__ ((__noreturn__))
-extern void VG_(core_assert_fail) ( const Char* expr, const Char* file,
- Int line, const Char* fn );
+#define I_die_here \
+ VG_(assert_fail) ("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__))
else
VG_(pp_StackTrace)(ips, VG_(clo_backtrace_size));
+ 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_(exit)(1);
}
-__attribute__ ((noreturn))
-static void assert_fail ( const Char* expr, const Char* name, const Char* report,
- const Char* file, Int line, const Char* fn )
+void VG_(assert_fail) ( Bool isCore, const Char* expr, const Char* file,
+ Int line, const Char* fn, const Char* 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;
- VG_(printf)("\n%s: %s:%d (%s): Assertion `%s' failed.\n",
- name, file, line, fn, expr );
- report_and_quit(report, NULL);
-}
-void VG_(tool_assert_fail) ( const Char* expr, const Char* file, Int line, const Char* fn )
-{
- assert_fail(expr, VG_(details).name, VG_(details).bug_reports_to,
- file, line, fn);
-}
+ va_start(vargs,format);
+ VG_(vprintf) ( add_to_vg_sprintf_buf, format, vargs, &bufptr );
+ add_to_vg_sprintf_buf('\0', &bufptr);
+ va_end(vargs);
-void VG_(core_assert_fail) ( const Char* expr, const Char* file, Int line, const Char* fn )
-{
- assert_fail(expr, "valgrind", VG_BUGS_TO, file, line, fn);
+ 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, NULL);
}
__attribute__ ((noreturn))
static void panic ( Char* name, Char* report, Char* str, StackTrace ips )
{
VG_(printf)("\n%s: the `impossible' happened:\n %s\n", name, str);
- VG_(printf)("Basic block ctr is approximately %llu\n", VG_(bbs_done) );
report_and_quit(report, ips);
}
/* Not found; we need to request a translation. */
if (VG_(translate)( tid, ip, /*debug*/False, 0/*not verbose*/ )) {
found = VG_(search_transtab)( NULL, ip, True );
- if (!found)
- VG_(core_panic)("VG_TRC_INNER_FASTMISS: missing tt_fast entry");
+ vg_assert2(found, "VG_TRC_INNER_FASTMISS: missing tt_fast entry");
+
} else {
// If VG_(translate)() fails, it's because it had to throw a
// signal because the client jumped to a bad address. That
break;
default:
- VG_(printf)("\ntrc = %d\n", trc);
- VG_(core_panic)("VG_(scheduler), phase 3: "
- "unexpected thread return code");
+ vg_assert2(0, "VG_(scheduler), phase 3: "
+ "unexpected thread return code (%u)", trc);
/* NOTREACHED */
break;
void VG_(set_fault_catcher)(void (*catcher)(Int, Addr))
{
- if (catcher != NULL && fault_catcher != NULL)
- VG_(core_panic)("Fault catcher is already registered");
+ vg_assert2(NULL == catcher || NULL == fault_catcher,
+ "Fault catcher is already registered");
fault_catcher = catcher;
}
#define VG_STRINGIFY_WRK(x) #x
#define VG_STRINGIFY(x) VG_STRINGIFY_WRK(x)
-#define tl_assert(expr) \
- ((void) ((expr) ? 0 : \
- (VG_(tool_assert_fail) (VG_STRINGIFY(expr), \
- __FILE__, __LINE__, \
- __PRETTY_FUNCTION__), 0)))
+#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_(tool_assert_fail) ( const Char* expr, const Char* file,
- Int line, const Char* fn );
-
+extern void VG_(assert_fail) ( Bool isCore, const Char* expr, const Char* file,
+ Int line, const Char* fn,
+ const Char* format, ... );
/* ------------------------------------------------------------------ */
/* Get memory by anonymous mmap. */