From: Florian Krohm Date: Tue, 27 Aug 2013 15:17:53 +0000 (+0000) Subject: When XML mode is selected messages from VALGRIND_PRINTF and friends X-Git-Tag: svn/VALGRIND_3_9_0~175 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=089f1ef8034e2d0392736e0e766c1d8c39a9d4e7;p=thirdparty%2Fvalgrind.git When XML mode is selected messages from VALGRIND_PRINTF and friends should go to the XML stream not stderr. Fixes BZ 322807. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13516 --- diff --git a/NEWS b/NEWS index 76939f8141..d5770a564d 100644 --- a/NEWS +++ b/NEWS @@ -443,6 +443,9 @@ FIXED r?? 321960 pthread_create() then alloca() causing invalid stack write errors FIXED 13467 +322807 VALGRIND_PRINTF_BACKTRACE writes callstack to xml and text to stderr + FIXED 13516 + 322851 0bXXX binary literal syntax is not standard FIXED 2736 diff --git a/coregrind/m_scheduler/scheduler.c b/coregrind/m_scheduler/scheduler.c index eb3351e11b..b20ab919ae 100644 --- a/coregrind/m_scheduler/scheduler.c +++ b/coregrind/m_scheduler/scheduler.c @@ -1654,6 +1654,76 @@ static Bool os_client_request(ThreadId tid, UWord *args) } +/* Write out a client message, possibly including a back trace. Return + the number of characters written. In case of XML output, the format + string as well as any arguments it requires will be XML'ified. + I.e. special characters such as the angle brackets will be translated + into proper escape sequences. */ +static +Int print_client_message( ThreadId tid, const HChar *format, + va_list *vargsp, Bool include_backtrace) +{ + Int count; + + if (VG_(clo_xml)) { + /* Translate the format string as follows: + < --> < + > --> > + & --> & + %s --> %pS + Yes, yes, it's simplified but in synch with + myvprintf_str_XML_simplistic and VG_(debugLog_vprintf). + */ + + /* Allocate a buffer that is for sure large enough. */ + HChar xml_format[VG_(strlen)(format) * 5 + 1]; + + const HChar *p; + HChar *q = xml_format; + + for (p = format; *p; ++p) { + switch (*p) { + case '<': VG_(strcpy)(q, "<"); q += 4; break; + case '>': VG_(strcpy)(q, ">"); q += 4; break; + case '&': VG_(strcpy)(q, "&"); q += 5; break; + case '%': + /* Careful: make sure %%s stays %%s */ + *q++ = *p++; + if (*p == 's') { + *q++ = 'p'; + *q++ = 'S'; + } else { + *q++ = *p; + } + break; + + default: + *q++ = *p; + break; + } + } + *q = '\0'; + + VG_(printf_xml)( "\n" ); + VG_(printf_xml)( " %d\n", tid ); + VG_(printf_xml)( " " ); + count = VG_(vprintf_xml)( xml_format, *vargsp ); + VG_(printf_xml)( " \n" ); + } else { + count = VG_(vmessage)( Vg_ClientMsg, format, *vargsp ); + VG_(message_flush)(); + } + + if (include_backtrace) + VG_(get_and_pp_StackTrace)( tid, VG_(clo_backtrace_size) ); + + if (VG_(clo_xml)) + VG_(printf_xml)( "\n" ); + + return count; +} + + /* Do a client request for the thread tid. After the request, tid may or may not still be runnable; if not, the scheduler will have to choose a new thread to run. @@ -1708,6 +1778,7 @@ void do_client_request ( ThreadId tid ) break; case VG_USERREQ__PRINTF: { + const HChar* format = (HChar *)arg[1]; /* JRS 2010-Jan-28: this is DEPRECATED; use the _VALIST_BY_REF version instead */ if (sizeof(va_list) != sizeof(UWord)) @@ -1718,13 +1789,14 @@ void do_client_request ( ThreadId tid ) } u; u.uw = (unsigned long)arg[2]; Int count = - VG_(vmessage)( Vg_ClientMsg, (HChar *)arg[1], u.vargs ); - VG_(message_flush)(); + print_client_message( tid, format, &u.vargs, + /* include_backtrace */ False ); SET_CLREQ_RETVAL( tid, count ); break; } case VG_USERREQ__PRINTF_BACKTRACE: { + const HChar* format = (HChar *)arg[1]; /* JRS 2010-Jan-28: this is DEPRECATED; use the _VALIST_BY_REF version instead */ if (sizeof(va_list) != sizeof(UWord)) @@ -1735,28 +1807,29 @@ void do_client_request ( ThreadId tid ) } u; u.uw = (unsigned long)arg[2]; Int count = - VG_(vmessage)( Vg_ClientMsg, (HChar *)arg[1], u.vargs ); - VG_(message_flush)(); - VG_(get_and_pp_StackTrace)( tid, VG_(clo_backtrace_size) ); + print_client_message( tid, format, &u.vargs, + /* include_backtrace */ True ); SET_CLREQ_RETVAL( tid, count ); break; } case VG_USERREQ__PRINTF_VALIST_BY_REF: { + const HChar* format = (HChar *)arg[1]; va_list* vargsp = (va_list*)arg[2]; - Int count = - VG_(vmessage)( Vg_ClientMsg, (HChar *)arg[1], *vargsp ); - VG_(message_flush)(); + Int count = + print_client_message( tid, format, vargsp, + /* include_backtrace */ False ); + SET_CLREQ_RETVAL( tid, count ); break; } case VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF: { + const HChar* format = (HChar *)arg[1]; va_list* vargsp = (va_list*)arg[2]; Int count = - VG_(vmessage)( Vg_ClientMsg, (HChar *)arg[1], *vargsp ); - VG_(message_flush)(); - VG_(get_and_pp_StackTrace)( tid, VG_(clo_backtrace_size) ); + print_client_message( tid, format, vargsp, + /* include_backtrace */ True ); SET_CLREQ_RETVAL( tid, count ); break; } diff --git a/docs/internals/xml-output-protocol4.txt b/docs/internals/xml-output-protocol4.txt index 0dec54fae0..861d8ca21b 100644 --- a/docs/internals/xml-output-protocol4.txt +++ b/docs/internals/xml-output-protocol4.txt @@ -190,7 +190,7 @@ the following in sequence: human-understandable. In current Valgrind versions it is the elapsed wallclock time since process start. -* Zero or more of (either ERRORCOUNTS or TOOLSPECIFIC). +* Zero or more of (either ERRORCOUNTS, TOOLSPECIFIC, or CLIENTMSG). * The following, indicating that the program has now finished, and that the any final wrapup (eg, for Memcheck, leak checking) is happening. @@ -699,3 +699,36 @@ The possible values are: One of various miscellaneous noteworthy conditions was observed (eg, thread exited whilst holding locks, "impossible" behaviour from the underlying threading library, etc) + +==================================================================== + +CLIENTMSG + +CLIENTMSG defines a message that was caused by one of the following +client requests: + +- VALGRIND_PRINTF +- VALGRIND_PRINTF_BACKTRACE + +Definition: + + + INT + ... + + +OR + + + INT + ... + STACK + + +* The tag indicates the Valgrind thread number. + +* The tag indicates the message as specified in the client request + (properly translated to XML). + +* STACK is only present in case of VALGRIND_PRINTF_BACKTRACE. See above + for a definition of STACK. diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am index e363df48e6..293813323e 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -74,6 +74,8 @@ EXTRA_DIST = \ buflen_check.stderr.exp-kfail \ bug287260.stderr.exp bug287260.vgtest \ calloc-overflow.stderr.exp calloc-overflow.vgtest\ + client-msg.stderr.exp client-msg.vgtest \ + client-msg-as-xml.stderr.exp client-msg-as-xml.vgtest \ clientperm.stderr.exp \ clientperm.stdout.exp clientperm.vgtest \ clireq_nofill.stderr.exp \ @@ -273,6 +275,7 @@ check_PROGRAMS = \ buflen_check \ bug287260 \ calloc-overflow \ + client-msg \ clientperm \ clireq_nofill \ clo_redzone \ diff --git a/memcheck/tests/client-msg-as-xml.stderr.exp b/memcheck/tests/client-msg-as-xml.stderr.exp new file mode 100644 index 0000000000..af97c61ab4 --- /dev/null +++ b/memcheck/tests/client-msg-as-xml.stderr.exp @@ -0,0 +1,90 @@ + + + + +4 +memcheck + + + ... + ... + ... + ... + + +... +... +memcheck + + + ... + + ./client-msg + + + + + RUNNING + + + + + ... + hello <> <&>%s world + + + + 0x........ + ... + VALGRIND_PRINTF_BACKTRACE + ... + valgrind.h + ... + + + 0x........ + ... + baz + ... + client-msg.c + ... + + + 0x........ + ... + bar + ... + client-msg.c + ... + + + 0x........ + ... + foo + ... + client-msg.c + ... + + + 0x........ + ... + main + ... + client-msg.c + ... + + + + + + FINISHED + + + + + + +... + + + diff --git a/memcheck/tests/client-msg-as-xml.vgtest b/memcheck/tests/client-msg-as-xml.vgtest new file mode 100644 index 0000000000..b3e8121708 --- /dev/null +++ b/memcheck/tests/client-msg-as-xml.vgtest @@ -0,0 +1,3 @@ +prog: client-msg +vgopts: --xml=yes --xml-fd=2 --log-file=/dev/null +stderr_filter: filter_xml diff --git a/memcheck/tests/client-msg.c b/memcheck/tests/client-msg.c new file mode 100644 index 0000000000..cdcf43d107 --- /dev/null +++ b/memcheck/tests/client-msg.c @@ -0,0 +1,24 @@ +#include "valgrind.h" + +void baz() +{ + VALGRIND_PRINTF_BACKTRACE("hello <> %s%%s world\n","<&>"); +} + +void bar() +{ + baz(); +} + +void foo() +{ + bar(); +} + +int main() +{ + foo(); + + return 0; +} + diff --git a/memcheck/tests/client-msg.stderr.exp b/memcheck/tests/client-msg.stderr.exp new file mode 100644 index 0000000000..075d321613 --- /dev/null +++ b/memcheck/tests/client-msg.stderr.exp @@ -0,0 +1,6 @@ +hello <> <&>%s world + ... + by 0x........: baz (client-msg.c:5) + by 0x........: bar (client-msg.c:10) + by 0x........: foo (client-msg.c:15) + by 0x........: main (client-msg.c:20) diff --git a/memcheck/tests/client-msg.vgtest b/memcheck/tests/client-msg.vgtest new file mode 100644 index 0000000000..ace036469b --- /dev/null +++ b/memcheck/tests/client-msg.vgtest @@ -0,0 +1,2 @@ +prog: client-msg +vgopts: -q