__attribute__ ((noreturn))
void ML_(am_exit)( Int status )
{
-# if defined(VGO_linux)
- (void)VG_(do_syscall1)(__NR_exit_group, status);
-# endif
- (void)VG_(do_syscall1)(__NR_exit, status);
- /* Why are we still alive here? */
- /*NOTREACHED*/
- *(volatile Int *)0 = 'x';
- aspacem_assert(2+2 == 5);
+ VG_(exit_now) (status);
}
void ML_(am_barf) ( const HChar* what )
// VG_IS_PAGE_ALIGNED
// VG_PGROUNDDN, VG_PGROUNDUP
+#include "pub_core_libcassert.h" // VG_(exit_now)
+
#include "pub_core_syscall.h" // VG_(do_syscallN)
// VG_(mk_SysRes_Error)
// VG_(mk_SysRes_Success)
}
exit_called = True;
+ VG_(exit_now) (status);
+}
+
+/* Call the appropriate system call and nothing else. This function should
+ be called in places where the dependencies of VG_(exit) need to be
+ avoided. */
+__attribute__ ((__noreturn__))
+void VG_(exit_now)( Int status )
+{
#if defined(VGO_linux)
(void)VG_(do_syscall1)(__NR_exit_group, status );
#elif defined(VGO_darwin)
*/
#include "pub_core_basics.h"
+#include "pub_core_libcassert.h" // VG_(exit_now)
+#include "pub_core_debuglog.h" // VG_(debugLog)
#include "pub_core_libcbase.h"
+
+/* ---------------------------------------------------------------------
+ Assert machinery for use in this file. VG_(assert) cannot be called
+ here due to cyclic dependencies.
+ ------------------------------------------------------------------ */
+#define libcbase_assert(expr) \
+ ((void) ((expr) ? 0 : \
+ (ML_(libcbase_assert_fail)(#expr, \
+ __FILE__, __LINE__, \
+ __PRETTY_FUNCTION__))))
+
+static void ML_(libcbase_assert_fail)( const HChar *expr,
+ const HChar *file,
+ Int line,
+ const HChar *fn )
+{
+ VG_(debugLog)(0, "libcbase",
+ "Valgrind: FATAL: assertion failed:\n");
+ VG_(debugLog)(0, "libcbase", " %s\n", expr);
+ VG_(debugLog)(0, "libcbase", " at %s:%d (%s)\n", file, line, fn);
+ VG_(debugLog)(0, "libcbase", "Exiting now.\n");
+ VG_(exit_now)(1);
+}
+
/* ---------------------------------------------------------------------
HChar functions.
------------------------------------------------------------------ */
zero termination. */
void VG_(strncpy_safely) ( HChar* dest, const HChar* src, SizeT ndest )
{
+ libcbase_assert(ndest > 0);
+
SizeT i = 0;
while (True) {
dest[i] = 0;
/* Exits with status as client exit code. */
extern void VG_(client_exit)( Int status );
+/* Lightweight exit without any dependencies. */
+__attribute__ ((__noreturn__))
+extern void VG_(exit_now)( Int status );
+
/* Called when some unhandleable client behaviour is detected.
Prints a msg and aborts. */
extern void VG_(unimplemented) ( const HChar* msg )
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stddef.h>
#include "pub_tool_basics.h" /* UInt et al, needed for pub_tool_vki.h */
#include "pub_tool_vki.h"
#include "m_libcbase.c"
+/* Provide a stub to not have to pull in m_debuglog.c */
+void VG_(debugLog) ( Int level, const HChar* modulename,
+ const HChar* format, ... )
+{
+ va_list args;
+ va_start(args, format);
+ fprintf(stderr, "debuglog: %s: ", modulename);
+ vfprintf(stderr, format, args);
+ va_end(args);
+}
+
+/* Provide a stub to not have to pull in m_libcassert.c */
+void VG_(exit_now)( Int status )
+{
+ exit(status);
+}
+
+
#define CHECK(x) \
if (!x) { fprintf(stderr, "failure: %s:%d\n", __FILE__, __LINE__); }