From: Jeremy Fitzhardinge Date: Fri, 31 Oct 2003 07:12:21 +0000 (+0000) Subject: Patch from Robert Walsh . Adds some new client X-Git-Tag: svn/VALGRIND_2_1_0~93 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=65649c9d47759294a433261f4ce98fcb47517038;p=thirdparty%2Fvalgrind.git Patch from Robert Walsh . Adds some new client requests to allow client code to print messages through Valgrind's logging mechanism. The new requests are: VALGRIND_PRINTF - do a normal printf (prefixed with **PID**) VALGRIND_PRINTF_BACKTRACE - do a printf with stack trace VALGRIND_INTERNAL_PRINTF - printf, but for internal use (prefixed with ==PID==) VALGRIND_INTERNAL_PRINTF_BACKTRACE - as above, with backtrace git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1974 --- diff --git a/corecheck/tests/Makefile.am b/corecheck/tests/Makefile.am index 67494e6e25..89a3659ede 100644 --- a/corecheck/tests/Makefile.am +++ b/corecheck/tests/Makefile.am @@ -17,12 +17,14 @@ EXTRA_DIST = $(noinst_SCRIPTS) \ 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) @@ -30,6 +32,7 @@ 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 diff --git a/coregrind/docs/coregrind_core.html b/coregrind/docs/coregrind_core.html index 0ef41d6137..f801ebc739 100644 --- a/coregrind/docs/coregrind_core.html +++ b/coregrind/docs/coregrind_core.html @@ -974,6 +974,15 @@ skin-specific documentation for explanations of the skin-specific macros). Warning: Only use these if you really know what you are doing.

+

  • VALGRIND_PRINTF(format, ...): 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. +

    +

  • VALGRIND_PRINTF_BACKTRACE(format, ...): 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. +

    Note that valgrind.h is included by all the skin-specific header files (such as memcheck.h), so you don't need to include it in diff --git a/coregrind/vg_include.h b/coregrind/vg_include.h index 52ed3022b2..9229880ea3 100644 --- a/coregrind/vg_include.h +++ b/coregrind/vg_include.h @@ -54,6 +54,7 @@ * 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 @@ -558,6 +559,10 @@ extern Bool VG_(is_inside_segment_mmapd_by_low_level_MM)( Addr aa ); #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: @@ -569,6 +574,32 @@ 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), diff --git a/coregrind/vg_messages.c b/coregrind/vg_messages.c index 631306fa8b..e6f4ff1e07 100644 --- a/coregrind/vg_messages.c +++ b/coregrind/vg_messages.c @@ -46,27 +46,38 @@ static void add_to_buf ( Char c ) /* 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; @@ -75,20 +86,24 @@ void VG_(start_msg) ( VgMsgKind kind ) 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; } diff --git a/coregrind/vg_scheduler.c b/coregrind/vg_scheduler.c index 9c029a7f89..e3c763bc7e 100644 --- a/coregrind/vg_scheduler.c +++ b/coregrind/vg_scheduler.c @@ -3114,6 +3114,34 @@ void do_client_request ( ThreadId tid ) 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: diff --git a/include/valgrind.h b/include/valgrind.h index a1711fd281..047d6fc60e 100644 --- a/include/valgrind.h +++ b/include/valgrind.h @@ -59,6 +59,8 @@ #ifndef __VALGRIND_H #define __VALGRIND_H +#include + /* This file is for inclusion into client (your!) code. @@ -162,6 +164,9 @@ typedef 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; @@ -187,6 +192,40 @@ typedef _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 */ diff --git a/include/vg_skin.h b/include/vg_skin.h index 2ee0171721..9e2c4be009 100644 --- a/include/vg_skin.h +++ b/include/vg_skin.h @@ -170,18 +170,20 @@ extern Char** VG_(client_envp); 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 ); /*====================================================================*/ diff --git a/tests/filter_stderr_basic b/tests/filter_stderr_basic index ac34fa9514..55b2f29964 100755 --- a/tests/filter_stderr_basic +++ b/tests/filter_stderr_basic @@ -3,8 +3,8 @@ # 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 ", a for x86-linux." line and the following # copyright notice line. Works for skin and core intro lines.