|
From: <sv...@va...> - 2009-08-15 22:42:02
|
Author: sewardj
Date: 2009-08-15 23:41:51 +0100 (Sat, 15 Aug 2009)
New Revision: 10822
Log:
When generating XML output for suppressions, print the suppression
both wrapped up in XML tags (as before) but also in plain text in a
sequence of CDATA blocks. Normally only one, but in the worst case
the raw data will have ]]> in it, in which case it needs to be split
across two CDATA blocks.
This apparently simple change involved a lot of refactoring of the
suppression printing machinery:
* in the core-tool iface, change "print_extra_suppression_info" (which
prints any auxiliary info) to "get_extra_suppression_info", which
parks the text in a caller-supplied buffer. Adjust tools to match.
* VG_(apply_StackTrace): accept a void* argument, which is passed to
each invokation of the functional parameter (a poor man's closure
implementation).
* move PRINTF_CHECK into put_tool_basics.h, where it should have been
all along
* move private printf-into-an-XArray-of-character functions from
m_debuginfo into m_xarray, and make them public
* gen_suppression itself: use all the above changes. Basically we
always generate the plaintext version into an XArray. In text mode
that's just printed. In XML mode, we print the XMLery as before,
but the plaintext version is dumped into a CDATA block too.
* update the Protocol 4 specification to match all this.
This still isn't 100% right in the sense that the CDATA block data
needs to be split across multiple blocks if it should ever contain the
CDATA end mark "]]>". The Protocol 4 spec has this right even though
the implementation currently doesn't.
Fixes #191189.
Modified:
trunk/coregrind/m_debuginfo/debuginfo.c
trunk/coregrind/m_errormgr.c
trunk/coregrind/m_stacktrace.c
trunk/coregrind/m_tooliface.c
trunk/coregrind/m_xarray.c
trunk/coregrind/pub_core_tooliface.h
trunk/docs/internals/xml-output-protocol4.txt
trunk/drd/drd_error.c
trunk/exp-ptrcheck/pc_common.c
trunk/exp-ptrcheck/pc_common.h
trunk/exp-ptrcheck/pc_main.c
trunk/helgrind/hg_errors.c
trunk/helgrind/hg_errors.h
trunk/helgrind/hg_main.c
trunk/include/pub_tool_basics.h
trunk/include/pub_tool_libcprint.h
trunk/include/pub_tool_stacktrace.h
trunk/include/pub_tool_tooliface.h
trunk/include/pub_tool_xarray.h
trunk/memcheck/mc_errors.c
trunk/memcheck/mc_include.h
trunk/memcheck/mc_main.c
Modified: trunk/coregrind/m_debuginfo/debuginfo.c
===================================================================
--- trunk/coregrind/m_debuginfo/debuginfo.c 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/coregrind/m_debuginfo/debuginfo.c 2009-08-15 22:41:51 UTC (rev 10822)
@@ -2269,28 +2269,18 @@
/*--- ---*/
/*--------------------------------------------------------------*/
-/* Implement a "p2XA" function ("printf-to-XA"), which printfs into an
- XArray of HChar, adding stuff at the end. This is very convenient
- for concocting result strings in format_message(). Note that the
- resulting string is NOT zero-terminated.
+/* Try to make p2XA(dst, fmt, args..) turn into
+ VG_(xaprintf_no_f_c)(dst, fmt, args) without having to resort to
+ vararg macros. As usual with everything to do with varargs, it's
+ an ugly hack.
- Unfortunately no format check on p2XA, since we need to use %t
- for XML escaped-string output, and gcc complains about that.
+ //#define p2XA(dstxa, format, args...)
+ // VG_(xaprintf_no_f_c)(dstxa, format, ##args)
*/
-static void add_char_to_XA ( HChar c, void* opaque )
-{
- XArray* dst = (XArray*)opaque;
- (void) VG_(addBytesToXA)( dst, &c, 1 );
-}
-static void p2XA ( XArray* dst, const HChar* format, ... )
-{
- va_list vargs;
- va_start(vargs, format);
- VG_(vcbprintf)( add_char_to_XA, (void*)dst, format, vargs );
- va_end(vargs);
-}
+#define p2XA VG_(xaprintf_no_f_c)
-/* Add a zero-terminating byte to DST. */
+/* Add a zero-terminating byte to DST, which must be an XArray* of
+ HChar. */
static void zterm_XA ( XArray* dst )
{
HChar zero = 0;
Modified: trunk/coregrind/m_errormgr.c
===================================================================
--- trunk/coregrind/m_errormgr.c 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/coregrind/m_errormgr.c 2009-08-15 22:41:51 UTC (rev 10822)
@@ -46,6 +46,7 @@
#include "pub_core_stacktrace.h"
#include "pub_core_tooliface.h"
#include "pub_core_translate.h" // for VG_(translate)()
+#include "pub_core_xarray.h" // VG_(xaprintf) et al
/*------------------------------------------------------------*/
/*--- Globals ---*/
@@ -295,78 +296,133 @@
}
-/* Helper function for suppression generation: print a single line of
- a suppression pseudo-stack-trace, either in XML or text mode.
+/* Helper functions for suppression generation: print a single line of
+ a suppression pseudo-stack-trace, either in XML or text mode. It's
+ important that the behaviour of these two functions exactly
+ corresponds.
*/
#define ERRTXT_LEN 4096
-static void printSuppForIp(UInt n, Addr ip)
+static void printSuppForIp_XML(UInt n, Addr ip, void* uu_opaque)
{
static UChar buf[ERRTXT_LEN];
+ if ( VG_(get_fnname_no_cxx_demangle) (ip, buf, ERRTXT_LEN) ) {
+ VG_(printf_xml_no_f_c)(" <sframe> <fun>%t</fun> </sframe>\n", buf);
+ } else
+ if ( VG_(get_objname)(ip, buf, ERRTXT_LEN) ) {
+ VG_(printf_xml_no_f_c)(" <sframe> <obj>%t</obj> </sframe>\n", buf);
+ } else {
+ VG_(printf_xml_no_f_c)(" <sframe> <obj>*</obj> </sframe>\n");
+ }
+}
+static void printSuppForIp_nonXML(UInt n, Addr ip, void* textV)
+{
+ static UChar buf[ERRTXT_LEN];
+ XArray* /* of HChar */ text = (XArray*)textV;
if ( VG_(get_fnname_no_cxx_demangle) (ip, buf, ERRTXT_LEN) ) {
- if (VG_(clo_xml))
- VG_(printf_xml_no_f_c)(" <sframe> <fun>%t</fun> </sframe>\n", buf);
- else
- VG_(printf)(" fun:%s\n", buf);
-
- } else if ( VG_(get_objname)(ip, buf, ERRTXT_LEN) ) {
- if (VG_(clo_xml))
- VG_(printf_xml_no_f_c)(" <sframe> <obj>%t</obj> </sframe>\n", buf);
- else
- VG_(printf)(" obj:%s\n", buf);
-
+ VG_(xaprintf)(text, " fun:%s\n", buf);
+ } else
+ if ( VG_(get_objname)(ip, buf, ERRTXT_LEN) ) {
+ VG_(xaprintf)(text, " obj:%s\n", buf);
} else {
- if (VG_(clo_xml))
- VG_(printf_xml_no_f_c)(" <sframe> <obj>*</obj> </sframe>\n");
- else
- VG_(printf)(" obj:*\n");
+ VG_(xaprintf)(text, " obj:*\n");
}
}
-
/* Generate a suppression for an error, either in text or XML mode.
*/
static void gen_suppression(Error* err)
{
- ExeContext* ec = VG_(get_error_where)(err);
+ Char xtra[256]; /* assumed big enough (is overrun-safe) */
+ Bool anyXtra;
+ Char* name;
+ ExeContext* ec;
+ XArray* /* HChar */ text;
- //(example code, see comment on CoreSuppKind above)
- if (0) {
- //if (0) ThreadErr == err->ekind) {
- // VG_(printf)("{\n");
- // VG_(printf)(" <insert a suppression name here>\n");
- // VG_(printf)(" core:Thread\n");
+ const HChar* dummy_name = "insert_a_suppression_name_here";
- } else {
- Char* name = VG_TDICT_CALL(tool_get_error_name, err);
- if (NULL == name) {
- VG_(umsg)("(%s does not allow error to be suppressed)\n",
- VG_(details).name);
- return;
- }
- if (VG_(clo_xml)) {
- VG_(printf_xml)(" <suppression>\n");
- VG_(printf_xml)(" <sname>insert_a_suppression_name_here</sname>\n");
- VG_(printf_xml)(" <skind>%s:%s</skind>\n", VG_(details).name, name);
- } else {
- VG_(printf)("{\n");
- VG_(printf)(" <insert a suppression name here>\n");
- VG_(printf)(" %s:%s\n", VG_(details).name, name);
- }
- VG_TDICT_CALL(tool_print_extra_suppression_info, err);
+ vg_assert(err);
+
+ /* In XML mode, we also need to print the plain text version of the
+ suppresion in a CDATA section. What that really means is, we
+ need to generate the plaintext version both in XML and text
+ mode. So generate it into TEXT. */
+ text = VG_(newXA)( VG_(malloc), "errormgr.gen_suppression.1",
+ VG_(free), sizeof(HChar) );
+ vg_assert(text);
+
+ ec = VG_(get_error_where)(err);
+ vg_assert(ec);
+
+ name = VG_TDICT_CALL(tool_get_error_name, err);
+ if (NULL == name) {
+ VG_(umsg)("(%s does not allow error to be suppressed)\n",
+ VG_(details).name);
+ return;
}
+ /* Ok. Generate the plain text version into TEXT. */
+ VG_(xaprintf)(text, "{\n");
+ VG_(xaprintf)(text, " <%s>\n", dummy_name);
+ VG_(xaprintf)(text, " %s:%s\n", VG_(details).name, name);
+
+ VG_(memset)(xtra, 0, sizeof(xtra));
+ anyXtra = VG_TDICT_CALL(tool_get_extra_suppression_info,
+ err, xtra, sizeof(xtra));
+ vg_assert(xtra[sizeof(xtra)-1] == 0);
+
+ if (anyXtra)
+ VG_(xaprintf)(text, " %s\n", xtra);
+
// Print stack trace elements
- VG_(apply_StackTrace)(printSuppForIp,
+ VG_(apply_StackTrace)(printSuppForIp_nonXML,
+ text,
VG_(get_ExeContext_StackTrace)(ec),
VG_(get_ExeContext_n_ips)(ec));
- if (VG_(clo_xml)) {
+ VG_(xaprintf)(text, "}\n");
+ // zero terminate
+ VG_(xaprintf)(text, "%c", (HChar)0 );
+ // VG_(printf) of text
+
+ /* And now display it. */
+ if (! VG_(clo_xml) ) {
+
+ // the simple case
+ VG_(printf)("%s", (HChar*) VG_(indexXA)(text, 0) );
+
+ } else {
+
+ /* Now we have to print the XML directly. No need to go to the
+ effort of stuffing it in an XArray, since we won't need it
+ again. */
+ VG_(printf_xml)(" <suppression>\n");
+ VG_(printf_xml)(" <sname>%s</sname>\n", dummy_name);
+ VG_(printf_xml_no_f_c)(
+ " <skind>%t:%t</skind>\n", VG_(details).name, name);
+ if (anyXtra)
+ VG_(printf_xml_no_f_c)(" <skaux>%t</skaux>\n", xtra);
+
+ // Print stack trace elements
+ VG_(apply_StackTrace)(printSuppForIp_XML,
+ NULL,
+ VG_(get_ExeContext_StackTrace)(ec),
+ VG_(get_ExeContext_n_ips)(ec));
+
+ // And now the cdata bit
+ // XXX FIXME! properly handle the case where the raw text
+ // itself contains "]]>", as specified in Protocol 4.
+ VG_(printf_xml)(" <rawtext>\n");
+ VG_(printf_xml)("<![CDATA[\n");
+ VG_(printf)("%s", (HChar*) VG_(indexXA)(text, 0) );
+ VG_(printf_xml)("]]>\n");
+ VG_(printf_xml)(" </rawtext>\n");
VG_(printf_xml)(" </suppression>\n");
- } else {
- VG_(printf)("}\n");
+
}
+
+ VG_(deleteXA)(text);
}
Modified: trunk/coregrind/m_stacktrace.c
===================================================================
--- trunk/coregrind/m_stacktrace.c 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/coregrind/m_stacktrace.c 2009-08-15 22:41:51 UTC (rev 10822)
@@ -514,7 +514,7 @@
stack_highest_word);
}
-static void printIpDesc(UInt n, Addr ip)
+static void printIpDesc(UInt n, Addr ip, void* uu_opaque)
{
#define BUF_LEN 4096
@@ -537,7 +537,7 @@
if (VG_(clo_xml))
VG_(printf_xml)(" <stack>\n");
- VG_(apply_StackTrace)( printIpDesc, ips, n_ips );
+ VG_(apply_StackTrace)( printIpDesc, NULL, ips, n_ips );
if (VG_(clo_xml))
VG_(printf_xml)(" </stack>\n");
@@ -555,8 +555,11 @@
VG_(pp_StackTrace)(ips, n_ips);
}
-void VG_(apply_StackTrace)( void(*action)(UInt n, Addr ip),
- StackTrace ips, UInt n_ips )
+void VG_(apply_StackTrace)(
+ void(*action)(UInt n, Addr ip, void* opaque),
+ void* opaque,
+ StackTrace ips, UInt n_ips
+ )
{
Bool main_done = False;
Int i = 0;
@@ -576,7 +579,7 @@
}
// Act on the ip
- action(i, ip);
+ action(i, ip, opaque);
i++;
} while (i < n_ips && !main_done);
Modified: trunk/coregrind/m_tooliface.c
===================================================================
--- trunk/coregrind/m_tooliface.c 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/coregrind/m_tooliface.c 2009-08-15 22:41:51 UTC (rev 10822)
@@ -233,7 +233,7 @@
Bool (*read_extra) (Int, Char**, SizeT*, Supp*),
Bool (*matches) (Error*, Supp*),
Char* (*name) (Error*),
- void (*print_extra)(Error*)
+ Bool (*get_xtra_si)(Error*,/*OUT*/Char*,Int)
)
{
VG_(needs).tool_errors = True;
@@ -246,7 +246,7 @@
VG_(tdict).tool_read_extra_suppression_info = read_extra;
VG_(tdict).tool_error_matches_suppression = matches;
VG_(tdict).tool_get_error_name = name;
- VG_(tdict).tool_print_extra_suppression_info = print_extra;
+ VG_(tdict).tool_get_extra_suppression_info = get_xtra_si;
}
void VG_(needs_command_line_options)(
Modified: trunk/coregrind/m_xarray.c
===================================================================
--- trunk/coregrind/m_xarray.c 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/coregrind/m_xarray.c 2009-08-15 22:41:51 UTC (rev 10822)
@@ -306,7 +306,32 @@
xa->usedsizeE -= n;
}
+/* --------- Printeffery --------- */
+static void add_char_to_XA ( HChar c, void* opaque )
+{
+ XArray* dst = (XArray*)opaque;
+ (void) VG_(addBytesToXA)( dst, &c, 1 );
+}
+
+void VG_(xaprintf)( XArray* dst, const HChar* format, ... )
+{
+ va_list vargs;
+ va_start(vargs, format);
+ VG_(vcbprintf)( add_char_to_XA, (void*)dst, format, vargs );
+ va_end(vargs);
+}
+
+/* and again .. */
+void VG_(xaprintf_no_f_c)( XArray* dst, const HChar* format, ... )
+{
+ va_list vargs;
+ va_start(vargs, format);
+ VG_(vcbprintf)( add_char_to_XA, (void*)dst, format, vargs );
+ va_end(vargs);
+}
+
+
/*--------------------------------------------------------------------*/
/*--- end m_xarray.c ---*/
/*--------------------------------------------------------------------*/
Modified: trunk/coregrind/pub_core_tooliface.h
===================================================================
--- trunk/coregrind/pub_core_tooliface.h 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/coregrind/pub_core_tooliface.h 2009-08-15 22:41:51 UTC (rev 10822)
@@ -125,7 +125,7 @@
Bool (*tool_read_extra_suppression_info) (Int, Char**, SizeT*, Supp*);
Bool (*tool_error_matches_suppression) (Error*, Supp*);
Char* (*tool_get_error_name) (Error*);
- void (*tool_print_extra_suppression_info)(Error*);
+ Bool (*tool_get_extra_suppression_info) (Error*,/*OUT*/Char*,Int);
// VG_(needs).superblock_discards
void (*tool_discard_superblock_info)(Addr64, VexGuestExtents);
Modified: trunk/docs/internals/xml-output-protocol4.txt
===================================================================
--- trunk/docs/internals/xml-output-protocol4.txt 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/docs/internals/xml-output-protocol4.txt 2009-08-15 22:41:51 UTC (rev 10822)
@@ -298,15 +298,27 @@
-----------
These are optionally emitted as part of ERRORs, and specify the
suppression that would be needed to suppress the containing error.
+For convenience, the suppression is presented twice, once in
+a structured nicely wrapped up in tags, and once as raw text
+suitable for direct copying and pasting into a suppressions file.
<suppression>
<sname>TEXT</sname> name of the suppression
<skind>TEXT</skind> kind, eg "Memcheck:Param"
<skaux>TEXT</skaux> (optional) aux kind, eg "write(buf)"
SFRAME (one or more) frames
+ <rawtext> CDATAS </rawtext>
</suppression>
+where CDATAS is a sequence of one or more <![CDATA[ .. ]]> blocks
+holding the raw text. Unfortunately, CDATA provides no way to escape
+the ending marker "]]>", which means that if the raw data contains
+such a sequence, it has to be split between two CDATA blocks, one
+ending with data "]]" and the other beginning with data "<". This is
+why the spec calls for one or more CDATA blocks rather than exactly
+one.
+
SFRAME
------
Either
Modified: trunk/drd/drd_error.c
===================================================================
--- trunk/drd/drd_error.c 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/drd/drd_error.c 2009-08-15 22:41:51 UTC (rev 10822)
@@ -528,14 +528,18 @@
}
/**
- * Print extra suppression information.
+ * Return extra suppression information.
*
* Invoked while printing a suppression pattern because the user
* specified --gen-suppressions=yes or all on the command line. DRD does not
* define any 'extra' suppression information.
*/
-static void drd_print_extra_suppression_info(Error* e)
-{ }
+static
+Bool drd_get_extra_suppression_info(Error* e,
+ /*OUT*/Char* buf, Int nBuf)
+{
+ return False;
+}
/** Tell the Valgrind core about DRD's error handlers. */
void DRD_(register_error_handlers)(void)
@@ -549,5 +553,5 @@
drd_read_extra_suppression_info,
drd_error_matches_suppression,
drd_get_error_name,
- drd_print_extra_suppression_info);
+ drd_get_extra_suppression_info);
}
Modified: trunk/exp-ptrcheck/pc_common.c
===================================================================
--- trunk/exp-ptrcheck/pc_common.c 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/exp-ptrcheck/pc_common.c 2009-08-15 22:41:51 UTC (rev 10822)
@@ -775,16 +775,23 @@
}
}
-void pc_print_extra_suppression_info ( Error* err )
+Bool pc_get_extra_suppression_info ( Error* err,
+ /*OUT*/Char* buf, Int nBuf )
{
- if (XE_SysParam == VG_(get_error_kind)(err)) {
- VG_(printf)(" %s\n", VG_(get_error_string)(err));
+ ErrorKind ekind = VG_(get_error_kind )(err);
+ tl_assert(buf);
+ tl_assert(nBuf >= 16); // stay sane
+ if (XE_SysParam == ekind) {
+ Char* errstr = VG_(get_error_string)(err);
+ tl_assert(errstr);
+ VG_(snprintf)(buf, nBuf-1, "%s", errstr);
+ return True;
+ } else {
+ return False;
}
}
-
-
/*--------------------------------------------------------------------*/
/*--- end pc_common.c ---*/
/*--------------------------------------------------------------------*/
Modified: trunk/exp-ptrcheck/pc_common.h
===================================================================
--- trunk/exp-ptrcheck/pc_common.h 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/exp-ptrcheck/pc_common.h 2009-08-15 22:41:51 UTC (rev 10822)
@@ -56,7 +56,8 @@
SizeT* nBufp, Supp* su );
Bool pc_error_matches_suppression (Error* err, Supp* su);
Char* pc_get_error_name ( Error* err );
-void pc_print_extra_suppression_info ( Error* err );
+Bool pc_get_extra_suppression_info ( Error* err,
+ /*OUT*/Char* buf, Int nBuf );
extern Bool h_clo_partial_loads_ok;
/* extern Bool h_clo_lossage_check; */
Modified: trunk/exp-ptrcheck/pc_main.c
===================================================================
--- trunk/exp-ptrcheck/pc_main.c 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/exp-ptrcheck/pc_main.c 2009-08-15 22:41:51 UTC (rev 10822)
@@ -190,7 +190,7 @@
pc_read_extra_suppression_info,
pc_error_matches_suppression,
pc_get_error_name,
- pc_print_extra_suppression_info);
+ pc_get_extra_suppression_info);
VG_(needs_xml_output) ();
Modified: trunk/helgrind/hg_errors.c
===================================================================
--- trunk/helgrind/hg_errors.c 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/helgrind/hg_errors.c 2009-08-15 22:41:51 UTC (rev 10822)
@@ -1068,9 +1068,11 @@
}
}
-void HG_(print_extra_suppression_info) ( Error* err )
+Bool HG_(get_extra_suppression_info) ( Error* err,
+ /*OUT*/Char* buf, Int nBuf )
{
/* Do nothing */
+ return False;
}
Modified: trunk/helgrind/hg_errors.h
===================================================================
--- trunk/helgrind/hg_errors.h 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/helgrind/hg_errors.h 2009-08-15 22:41:51 UTC (rev 10822)
@@ -44,7 +44,8 @@
Supp* su );
Bool HG_(error_matches_suppression) ( Error* err, Supp* su );
Char* HG_(get_error_name) ( Error* err );
-void HG_(print_extra_suppression_info) ( Error* err );
+Bool HG_(get_extra_suppression_info) ( Error* err,
+ /*OUT*/Char* buf, Int nBuf );
/* Functions for recording various kinds of errors. */
void HG_(record_error_Race) ( Thread* thr,
Modified: trunk/helgrind/hg_main.c
===================================================================
--- trunk/helgrind/hg_main.c 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/helgrind/hg_main.c 2009-08-15 22:41:51 UTC (rev 10822)
@@ -4601,7 +4601,7 @@
HG_(read_extra_suppression_info),
HG_(error_matches_suppression),
HG_(get_error_name),
- HG_(print_extra_suppression_info));
+ HG_(get_extra_suppression_info));
VG_(needs_xml_output) ();
Modified: trunk/include/pub_tool_basics.h
===================================================================
--- trunk/include/pub_tool_basics.h 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/include/pub_tool_basics.h 2009-08-15 22:41:51 UTC (rev 10822)
@@ -323,7 +323,17 @@
# define UNLIKELY(x) (x)
#endif
+// printf format string checking for gcc.
+// This feature has been supported since at least gcc version 2.95.
+// For more information about the format attribute, see
+// http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Function-Attributes.html.
+#if defined(__GNUC__)
+#define PRINTF_CHECK(x, y) __attribute__((format(__printf__, x, y)))
+#else
+#define PRINTF_CHECK(x, y)
+#endif
+
#endif /* __PUB_TOOL_BASICS_H */
/*--------------------------------------------------------------------*/
Modified: trunk/include/pub_tool_libcprint.h
===================================================================
--- trunk/include/pub_tool_libcprint.h 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/include/pub_tool_libcprint.h 2009-08-15 22:41:51 UTC (rev 10822)
@@ -31,20 +31,6 @@
#ifndef __PUB_TOOL_LIBCPRINT_H
#define __PUB_TOOL_LIBCPRINT_H
-
-/* Enable compile-time format string checking by gcc.
- This feature is supported since at least gcc version 2.95.
- For more information about the format attribute, see also
- http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Function-Attributes.html.
- */
-
-#if defined(__GNUC__)
-#define PRINTF_CHECK(x, y) __attribute__((format(__printf__, x, y)))
-#else
-#define PRINTF_CHECK(x, y)
-#endif
-
-
/* ---------------------------------------------------------------------
Basic printing
------------------------------------------------------------------ */
Modified: trunk/include/pub_tool_stacktrace.h
===================================================================
--- trunk/include/pub_tool_stacktrace.h 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/include/pub_tool_stacktrace.h 2009-08-15 22:41:51 UTC (rev 10822)
@@ -62,11 +62,16 @@
/*OUT*/StackTrace fps,
Word first_ip_delta );
-// Apply a function to every element in the StackTrace. The parameter 'n'
-// gives the index of the passed ip. Doesn't go below main() unless
-// --show-below-main=yes is set.
-extern void VG_(apply_StackTrace)( void(*action)(UInt n, Addr ip),
- StackTrace ips, UInt n_ips );
+// Apply a function to every element in the StackTrace. The parameter
+// 'n' gives the index of the passed ip. 'opaque' is an arbitrary
+// pointer provided to each invokation of 'action' (a poor man's
+// closure). Doesn't go below main() unless --show-below-main=yes is
+// set.
+extern void VG_(apply_StackTrace)(
+ void(*action)(UInt n, Addr ip, void* opaque),
+ void* opaque,
+ StackTrace ips, UInt n_ips
+ );
// Print a StackTrace.
extern void VG_(pp_StackTrace) ( StackTrace ips, UInt n_ips );
Modified: trunk/include/pub_tool_tooliface.h
===================================================================
--- trunk/include/pub_tool_tooliface.h 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/include/pub_tool_tooliface.h 2009-08-15 22:41:51 UTC (rev 10822)
@@ -332,10 +332,17 @@
// VG_(tdict).tool_recognised_suppression().
Char* (*get_error_name)(Error* err),
- // This should print any extra info for the error, for --gen-suppressions,
- // including the newline. This is the inverse of
+ // This should print into buf[0..nBuf-1] any extra info for the
+ // error, for --gen-suppressions, but not including any leading
+ // spaces nor a trailing newline. When called, buf[0 .. nBuf-1]
+ // will be zero filled, and it is expected and checked that the
+ // last element is still zero after the call. In other words the
+ // tool may not overrun the buffer, and this is checked for. If
+ // there is any info printed in the buffer, return True, otherwise
+ // do nothing, and return False. This function is the inverse of
// VG_(tdict).tool_read_extra_suppression_info().
- void (*print_extra_suppression_info)(Error* err)
+ Bool (*print_extra_suppression_info)(Error* err,
+ /*OUT*/Char* buf, Int nBuf)
);
/* Is information kept by the tool about specific instructions or
Modified: trunk/include/pub_tool_xarray.h
===================================================================
--- trunk/include/pub_tool_xarray.h 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/include/pub_tool_xarray.h 2009-08-15 22:41:51 UTC (rev 10822)
@@ -125,6 +125,18 @@
is NULL, in which case the parent's cost-center is used. */
extern XArray* VG_(cloneXA)( HChar* cc, XArray* xa );
+/* Convenience function: printf into an XArray of HChar, adding stuff
+ at the end. This is very convenient for concocting arbitrary
+ length printf output in an XArray. Note that the resulting string
+ is NOT zero-terminated. Versions are provided with and without a
+ format check, the latter so the unknown (to gcc) "%t" can be used
+ without gcc complaining. */
+extern void VG_(xaprintf)( XArray* dst, const HChar* format, ... )
+ PRINTF_CHECK(2, 3);
+
+extern void VG_(xaprintf_no_f_c)
+ ( XArray* dst, const HChar* format, ... );
+
#endif // __PUB_TOOL_XARRAY_H
/*--------------------------------------------------------------------*/
Modified: trunk/memcheck/mc_errors.c
===================================================================
--- trunk/memcheck/mc_errors.c 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/memcheck/mc_errors.c 2009-08-15 22:41:51 UTC (rev 10822)
@@ -1499,11 +1499,19 @@
}
}
-void MC_(print_extra_suppression_info) ( Error* err )
+Bool MC_(get_extra_suppression_info) ( Error* err,
+ /*OUT*/Char* buf, Int nBuf )
{
ErrorKind ekind = VG_(get_error_kind )(err);
+ tl_assert(buf);
+ tl_assert(nBuf >= 16); // stay sane
if (Err_RegParam == ekind || Err_MemParam == ekind) {
- VG_(printf)(" %s\n", VG_(get_error_string)(err));
+ Char* errstr = VG_(get_error_string)(err);
+ tl_assert(errstr);
+ VG_(snprintf)(buf, nBuf-1, "%s", errstr);
+ return True;
+ } else {
+ return False;
}
}
Modified: trunk/memcheck/mc_include.h
===================================================================
--- trunk/memcheck/mc_include.h 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/memcheck/mc_include.h 2009-08-15 22:41:51 UTC (rev 10822)
@@ -320,7 +320,8 @@
Bool MC_(error_matches_suppression) ( Error* err, Supp* su );
-void MC_(print_extra_suppression_info) ( Error* err );
+Bool MC_(get_extra_suppression_info) ( Error* err,
+ /*OUT*/Char* buf, Int nBuf );
Char* MC_(get_error_name) ( Error* err );
Modified: trunk/memcheck/mc_main.c
===================================================================
--- trunk/memcheck/mc_main.c 2009-08-15 21:50:44 UTC (rev 10821)
+++ trunk/memcheck/mc_main.c 2009-08-15 22:41:51 UTC (rev 10822)
@@ -5715,7 +5715,7 @@
MC_(read_extra_suppression_info),
MC_(error_matches_suppression),
MC_(get_error_name),
- MC_(print_extra_suppression_info));
+ MC_(get_extra_suppression_info));
VG_(needs_libc_freeres) ();
VG_(needs_command_line_options)(mc_process_cmd_line_options,
mc_print_usage,
|