pth_mutexspeed.stdout.exp pth_mutexspeed.vgtest \
pth_once.stderr.exp pth_once.stdout.exp pth_once.vgtest \
sigkill.stderr.exp sigkill.vgtest \
- res_search.stderr.exp res_search.stdout.exp res_search.vgtest
+ res_search.stderr.exp res_search.stdout.exp res_search.vgtest \
+ vgprintf.stderr.exp vgprintf.stdout.exp vgprintf.vgtest
check_PROGRAMS = \
erringfds sigkill res_search \
pth_atfork1 pth_cancel2 pth_cvsimple pth_empty \
- pth_exit pth_mutexspeed pth_once
+ pth_exit pth_mutexspeed pth_once \
+ vgprintf
AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -g -O0
AM_CXXFLAGS = $(AM_CFLAGS)
# C ones
erringfds_SOURCES = erringfds.c
sigkill_SOURCES = sigkill.c
+vgprintf_SOURCES = vgprintf.c
# Pthread ones
pth_atfork1_SOURCES = pth_atfork1.c
<b>Warning:</b> Only use these if you <i>really</i> know what you are
doing.
<p>
+<li><code>VALGRIND_PRINTF(format, ...)</code>: printf a message to the
+ log file when running under Valgrind. Nothing is output if not
+ running under Valgrind. Returns the number of characters output.
+<p>
+<li><code>VALGRIND_PRINTF_BACKTRACE(format, ...)</code>: printf a message
+ to the log file along with a stack backtrace when running under
+ Valgrind. Nothing is output if not running under Valgrind.
+ Returns the number of characters output.
+<p>
</ul>
Note that <code>valgrind.h</code> is included by all the skin-specific header
files (such as <code>memcheck.h</code>), so you don't need to include it in
* visible to core but not visible to any skins should go in this
* file, vg_include.h. */
#include "vg_skin.h"
+#include "valgrind.h"
/* Total number of spill slots available for allocation, if a TempReg
doesn't make it into a RealReg. Just bomb the entire system if
#define VG_USERREQ__GET_PTHREAD_TRACE_LEVEL 0x3101
/* Log a pthread error from client-space. Cosmetic. */
#define VG_USERREQ__PTHREAD_ERROR 0x3102
+/* Internal equivalent of VALGRIND_PRINTF . */
+#define VG_USERREQ__INTERNAL_PRINTF 0x3103
+/* Internal equivalent of VALGRIND_PRINTF_BACKTRACE . */
+#define VG_USERREQ__INTERNAL_PRINTF_BACKTRACE 0x3104
/*
In vg_constants.h:
called at program exit. */
extern void VG_(__libc_freeres_wrapper)( void );
+__attribute__((weak))
+int
+VALGRIND_INTERNAL_PRINTF(char *format, ...)
+{
+ unsigned int _qzz_res = 0;
+ va_list vargs;
+ va_start(vargs, format);
+ VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, VG_USERREQ__INTERNAL_PRINTF,
+ (unsigned int)format, (unsigned int)vargs, 0, 0);
+ va_end(vargs);
+ return _qzz_res;
+}
+
+__attribute__((weak))
+int
+VALGRIND_INTERNAL_PRINTF_BACKTRACE(char *format, ...)
+{
+ unsigned int _qzz_res = 0;
+ va_list vargs;
+ va_start(vargs, format);
+ VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, VG_USERREQ__INTERNAL_PRINTF_BACKTRACE,
+ (unsigned int)format, (unsigned int)vargs, 0, 0);
+ va_end(vargs);
+ return _qzz_res;
+}
+
/* ---------------------------------------------------------------------
Constants pertaining to the simulated CPU state, VG_(baseBlock),
/* Publically visible from here onwards. */
-void
+int
VG_(add_to_msg) ( Char *format, ... )
{
+ int count;
va_list vargs;
va_start(vargs,format);
- VG_(vprintf) ( add_to_buf, format, vargs );
+ count = VG_(vprintf) ( add_to_buf, format, vargs );
va_end(vargs);
+ return count;
+}
+
+int VG_(vmessage) ( VgMsgKind kind, Char* format, va_list vargs )
+{
+ int count;
+ count = VG_(start_msg) ( kind );
+ count += VG_(vprintf) ( add_to_buf, format, vargs );
+ count += VG_(end_msg)();
+ return count;
}
/* Send a simple single-part message. */
-void VG_(message) ( VgMsgKind kind, Char* format, ... )
+int VG_(message) ( VgMsgKind kind, Char* format, ... )
{
+ int count;
va_list vargs;
va_start(vargs,format);
- VG_(start_msg) ( kind );
- VG_(vprintf) ( add_to_buf, format, vargs );
+ count = VG_(vmessage) ( kind, format, vargs );
va_end(vargs);
- VG_(end_msg)();
+ return count;
}
-void VG_(start_msg) ( VgMsgKind kind )
+int VG_(start_msg) ( VgMsgKind kind )
{
Char c;
vg_n_mbuf = 0;
case Vg_UserMsg: c = '='; break;
case Vg_DebugMsg: c = '-'; break;
case Vg_DebugExtraMsg: c = '+'; break;
+ case Vg_ClientMsg: c = '*'; break;
default: c = '?'; break;
}
- VG_(add_to_msg)( "%c%c%d%c%c ",
- c,c, VG_(getpid)(), c,c );
+ return VG_(add_to_msg)( "%c%c%d%c%c ",
+ c,c, VG_(getpid)(), c,c );
}
-void VG_(end_msg) ( void )
+int VG_(end_msg) ( void )
{
+ int count = 0;
if (VG_(clo_logfile_fd) >= 0) {
add_to_buf('\n');
VG_(send_bytes_to_logging_sink) (
vg_mbuf, VG_(strlen)(vg_mbuf) );
+ count = 1;
}
+ return count;
}
handle_signal_return(tid);
break;
+ case VG_USERREQ__PRINTF: {
+ int count =
+ VG_(vmessage)( Vg_ClientMsg, (char *)arg[1], (va_list)arg[2] );
+ SET_CLREQ_RETVAL( tid, count );
+ break; }
+
+ case VG_USERREQ__INTERNAL_PRINTF: {
+ int count =
+ VG_(vmessage)( Vg_UserMsg, (char *)arg[1], (va_list)arg[2] );
+ SET_CLREQ_RETVAL( tid, count );
+ break; }
+
+ case VG_USERREQ__PRINTF_BACKTRACE: {
+ ExeContext *e = VG_(get_ExeContext)( tid );
+ int count =
+ VG_(vmessage)( Vg_ClientMsg, (char *)arg[1], (va_list)arg[2] );
+ VG_(mini_stack_dump)(e->eips, VG_(clo_backtrace_size));
+ SET_CLREQ_RETVAL( tid, count );
+ break; }
+
+ case VG_USERREQ__INTERNAL_PRINTF_BACKTRACE: {
+ ExeContext *e = VG_(get_ExeContext)( tid );
+ int count =
+ VG_(vmessage)( Vg_UserMsg, (char *)arg[1], (va_list)arg[2] );
+ VG_(mini_stack_dump)(e->eips, VG_(clo_backtrace_size));
+ SET_CLREQ_RETVAL( tid, count );
+ break; }
+
/* Requests from the client program */
case VG_USERREQ__DISCARD_TRANSLATIONS:
#ifndef __VALGRIND_H
#define __VALGRIND_H
+#include <stdarg.h>
+
/* This file is for inclusion into client (your!) code.
VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
VG_USERREQ__FREELIKE_BLOCK = 0x1302,
+ /* Allow printfs to valgrind log. */
+ VG_USERREQ__PRINTF = 0x1401,
+ VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
} Vg_ClientRequest;
_qzz_addr, _qzz_len, 0, 0); \
}
+#ifndef NVALGRIND
+
+__attribute__((weak))
+int
+VALGRIND_PRINTF(char *format, ...)
+{
+ unsigned int _qzz_res;
+ va_list vargs;
+ va_start(vargs, format);
+ VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, VG_USERREQ__PRINTF,
+ (unsigned int)format, (unsigned int)vargs, 0, 0);
+ va_end(vargs);
+ return _qzz_res;
+}
+
+__attribute__((weak))
+int
+VALGRIND_PRINTF_BACKTRACE(char *format, ...)
+{
+ unsigned int _qzz_res;
+ va_list vargs;
+ va_start(vargs, format);
+ VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, VG_USERREQ__PRINTF_BACKTRACE,
+ (unsigned int)format, (unsigned int)vargs, 0, 0);
+ va_end(vargs);
+ return _qzz_res;
+}
+
+#else /* NVALGRIND */
+
+#define VALGRIND_PRINTF(...)
+#define VALGRIND_PRINTF_BACKTRACE(...)
+
+#endif /* NVALGRIND */
/* These requests allow control to move from the simulated CPU to the
real CPU, calling an arbitary function */
typedef
enum { Vg_UserMsg, /* '?' == '=' */
Vg_DebugMsg, /* '?' == '-' */
- Vg_DebugExtraMsg /* '?' == '+' */
+ Vg_DebugExtraMsg, /* '?' == '+' */
+ Vg_ClientMsg, /* '?' == '*' */
}
VgMsgKind;
/* Functions for building a message from multiple parts. */
-extern void VG_(start_msg) ( VgMsgKind kind );
-extern void VG_(add_to_msg) ( Char* format, ... );
+extern int VG_(start_msg) ( VgMsgKind kind );
+extern int VG_(add_to_msg) ( Char* format, ... );
/* Ends and prints the message. Appends a newline. */
-extern void VG_(end_msg) ( void );
+extern int VG_(end_msg) ( void );
/* Send a single-part message. Appends a newline. */
-extern void VG_(message) ( VgMsgKind kind, Char* format, ... );
+extern int VG_(message) ( VgMsgKind kind, Char* format, ... );
+extern int VG_(vmessage) ( VgMsgKind kind, Char* format, va_list vargs );
/*====================================================================*/
# This filter should be applied to *every* stderr results. It removes Valgrind
# startup stuff and pid numbers.
-# Remove ==pid== and --pid-- and ++pid++ strings
-sed "s/\(==\|--\|++\)[0-9]\{1,5\}\1 //" |
+# Remove ==pid== and --pid-- and ++pid++ and **pid** strings
+sed "s/\(==\|--\|\+\+\|\*\*\)[0-9]\{1,5\}\1 //" |
# Remove "<name>, a <description> for x86-linux." line and the following
# copyright notice line. Works for skin and core intro lines.