Merge coregrind/ changes from branches/MESSAGING_TIDYUP r10464.
This commit tidies up and rationalises what could be called the
"messaging" system -- that part of V to do with presenting output to
the user. In particular it brings significant improvements to XML
output.
Changes are:
* XML and normal text output now have separate file descriptors,
which solves longstanding problems for XML consumers caused by
the XML output getting polluted by unexpected non-XML output.
* This also means that we no longer have to hardwire all manner
of output settings (verbosity, etc) when XML is requested.
* The XML output format has been revised, cleaned up, and made
more suitable for use by error detecting tools in general
(various Memcheck-specific features have been removed). XML
output is enabled for Ptrcheck and Helgrind, and Memcheck is
updated to the new format.
* One side effect is that the behaviour of VG_(message) has been
made to be consistent with printf: it no longer automatically
adds a newline at the end of the output. This means multiple
calls to it can be used to build up a single line message; or a
single call can write a multi-line message. The ==pid==
preamble is automatically inserted at each newline.
* VG_(message)(Vg_UserMsg, ..args..) now has the abbreviated form
VG_(UMSG)(..args..); ditto VG_(DMSG) for Vg_DebugMsg and
VG_(EMSG) for Vg_DebugExtraMsg. A couple of other useful
printf derivatives have been added to pub_tool_libcprint.h,
most particularly VG_(vcbprintf).
* There's a small change in the core-tool interface to do with
error handling: VG_(needs_tool_errors) has a new method
void (*before_pp_Error)(Error* err) which, if non-NULL, is
called just before void (*pp_Error)(Error* err). This is to
give tools the chance to look at errors before any part of them
is printed, so they can print any XML preamble they like.
* coregrind/m_errormgr.c has been overhauled and cleaned up, and
is a bit simpler and more commented. In particular pp_Error
and VG_(maybe_record_error) are significantly changed.
The diff is huge, but mostly very boring. Most of the changes
are of the form
- VG_(message)(Vg_UserMsg, "this is a message %d", n);
+ VG_(message)(Vg_UserMsg, "this is a message %d\n", n);
Unfortunately as a result of this, it touches a large number
of source files.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10465 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_commandline.c b/coregrind/m_commandline.c
index e4ab751..327560a 100644
--- a/coregrind/m_commandline.c
+++ b/coregrind/m_commandline.c
@@ -81,7 +81,7 @@
else
VG_(message)(Vg_UserMsg,
"%s was not read as it is world writeable or not owned by the "
- "current user", filename);
+ "current user\n", filename);
VG_(close)(sr_Res(fd));
}
diff --git a/coregrind/m_coredump/coredump-elf.c b/coregrind/m_coredump/coredump-elf.c
index 0d409aa..e29700a 100644
--- a/coregrind/m_coredump/coredump-elf.c
+++ b/coregrind/m_coredump/coredump-elf.c
@@ -444,11 +444,11 @@
Addr *seg_starts;
Int n_seg_starts;
- if (VG_(clo_log_name) != NULL) {
+ if (VG_(clo_log_fname_expanded) != NULL) {
coreext = ".core";
basename = VG_(expand_file_name)(
"--log-file (while creating core filename)",
- VG_(clo_log_name));
+ VG_(clo_log_fname_expanded));
}
vg_assert(coreext);
diff --git a/coregrind/m_debugger.c b/coregrind/m_debugger.c
index 1bc9fe5..aaa6c6b 100644
--- a/coregrind/m_debugger.c
+++ b/coregrind/m_debugger.c
@@ -296,22 +296,22 @@
*bufptr++ = '\0';
- VG_(message)(Vg_UserMsg, "starting debugger with cmd: %s", buf);
+ VG_(message)(Vg_UserMsg, "starting debugger with cmd: %s\n", buf);
res = VG_(system)(buf);
if (res == 0) {
- VG_(message)(Vg_UserMsg, "");
+ VG_(message)(Vg_UserMsg, "\n");
VG_(message)(Vg_UserMsg,
"Debugger has detached. Valgrind regains control."
- " We continue.");
+ " We continue.\n");
} else {
VG_(message)(Vg_UserMsg,
- "Warning: Debugger attach failed! (sys_system)");
- VG_(message)(Vg_UserMsg, "");
+ "Warning: Debugger attach failed! (sys_system)\n");
+ VG_(message)(Vg_UserMsg, "\n");
}
} else {
VG_(message)(Vg_UserMsg,
- "Warning: Debugger attach failed! (ptrace problem?)");
- VG_(message)(Vg_UserMsg, "");
+ "Warning: Debugger attach failed! (ptrace problem?)\n");
+ VG_(message)(Vg_UserMsg, "\n");
}
VG_(kill)(pid, VKI_SIGKILL);
diff --git a/coregrind/m_debuginfo/d3basics.c b/coregrind/m_debuginfo/d3basics.c
index 055f814..a61ed05 100644
--- a/coregrind/m_debuginfo/d3basics.c
+++ b/coregrind/m_debuginfo/d3basics.c
@@ -641,7 +641,7 @@
if (!VG_(clo_xml))
VG_(message)(Vg_DebugMsg,
"warning: evaluate_Dwarf3_Expr: unhandled "
- "DW_OP_ 0x%x", (Int)opcode);
+ "DW_OP_ 0x%x\n", (Int)opcode);
FAIL("evaluate_Dwarf3_Expr: unhandled DW_OP_");
/*NOTREACHED*/
}
diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c
index 34442f6..dfc9f31 100644
--- a/coregrind/m_debuginfo/debuginfo.c
+++ b/coregrind/m_debuginfo/debuginfo.c
@@ -306,7 +306,7 @@
if (curr->have_dinfo
&& (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir)))
VG_(message)(Vg_DebugMsg,
- "Discarding syms at %#lx-%#lx in %s due to %s()",
+ "Discarding syms at %#lx-%#lx in %s due to %s()\n",
di->text_avma,
di->text_avma + di->text_size,
curr->filename ? curr->filename : (UChar*)"???",
@@ -904,10 +904,10 @@
struct vg_stat stat_buf;
if (VG_(clo_verbosity) > 0) {
- VG_(message)(Vg_UserMsg, "");
+ VG_(message)(Vg_UserMsg, "\n");
VG_(message)(Vg_UserMsg,
"LOAD_PDB_DEBUGINFO(fd=%d, avma=%#lx, total_size=%lu, "
- "uu_reloc=%#lx)",
+ "uu_reloc=%#lx)\n",
fd_obj, avma_obj, total_size, unknown_purpose__reloc
);
}
@@ -933,7 +933,7 @@
vg_assert(exename[sizeof(exename)-1] == 0);
if (VG_(clo_verbosity) > 0) {
- VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: objname: %s", exename);
+ VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: objname: %s\n", exename);
}
/* Try to find a matching PDB file from which to read debuginfo.
@@ -961,24 +961,25 @@
/* See if we can find it, and check it's in-dateness. */
sres = VG_(stat)(pdbname, &stat_buf);
if (sr_isError(sres)) {
- VG_(message)(Vg_UserMsg, "Warning: Missing or un-stat-able %s",
+ VG_(message)(Vg_UserMsg, "Warning: Missing or un-stat-able %s\n",
pdbname);
if (VG_(clo_verbosity) > 0)
- VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: missing: %s", pdbname);
+ VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: missing: %s\n", pdbname);
goto out;
}
pdb_mtime = stat_buf.mtime;
if (pdb_mtime < obj_mtime ) {
/* PDB file is older than PE file - ignore it or we will either
(a) print wrong stack traces or more likely (b) crash. */
- VG_(message)(Vg_UserMsg, "Warning: Ignoring %s since it is older than %s",
- pdbname, exename);
+ VG_(message)(Vg_UserMsg,
+ "Warning: Ignoring %s since it is older than %s\n",
+ pdbname, exename);
goto out;
}
sres = VG_(open)(pdbname, VKI_O_RDONLY, 0);
if (sr_isError(sres)) {
- VG_(message)(Vg_UserMsg, "Warning: Can't open %s", pdbname);
+ VG_(message)(Vg_UserMsg, "Warning: Can't open %s\n", pdbname);
goto out;
}
@@ -993,7 +994,7 @@
}
if (VG_(clo_verbosity) > 0)
- VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: pdbname: %s", pdbname);
+ VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: pdbname: %s\n", pdbname);
/* play safe; always invalidate the CFI cache. I don't know if
this is necessary, but anyway .. */
@@ -2250,7 +2251,8 @@
spHere = *spP;
*ipP = *(Addr *)(spHere + 4*(fpo->cbRegs + fpo->cdwLocals));
- *spP = spHere + 4*(fpo->cbRegs + fpo->cdwLocals + 1 + fpo->cdwParams);
+ *spP = spHere + 4*(fpo->cbRegs + fpo->cdwLocals + 1
+ + fpo->cdwParams);
*fpP = *(Addr *)(spHere + 4*2);
return True;
}
@@ -2263,6 +2265,35 @@
/*--- ---*/
/*--------------------------------------------------------------*/
+/* 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.
+
+ Unfortunately no format check on p2XA, since we need to use %t
+ for XML escaped-string output, and gcc complains about that.
+*/
+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);
+}
+
+/* Add a zero-terminating byte to DST. */
+static void zterm_XA ( XArray* dst )
+{
+ HChar zero = 0;
+ (void) VG_(addBytesToXA)( dst, &zero, 1 );
+}
+
+
/* Evaluate the location expression/list for var, to see whether or
not data_addr falls within the variable. If so also return the
offset of data_addr from the start of the variable. Note that
@@ -2329,13 +2360,14 @@
}
-/* Format the acquired information into dname1[0 .. n_dname-1] and
- dname2[0 .. n_dname-1] in an understandable way. Not so easy.
- If frameNo is -1, this is assumed to be a global variable; else
- a local variable. */
-static void format_message ( /*OUT*/Char* dname1,
- /*OUT*/Char* dname2,
- Int n_dname,
+/* Format the acquired information into DN(AME)1 and DN(AME)2, which
+ are XArray*s of HChar, that have been initialised by the caller.
+ Resulting strings will be zero terminated. Information is
+ formatted in an understandable way. Not so easy. If frameNo is
+ -1, this is assumed to be a global variable; else a local
+ variable. */
+static void format_message ( /*MOD*/XArray* /* of HChar */ dn1,
+ /*MOD*/XArray* /* of HChar */ dn2,
Addr data_addr,
DiVariable* var,
PtrdiffT var_offset,
@@ -2344,19 +2376,35 @@
Int frameNo,
ThreadId tid )
{
- Bool have_descr, have_srcloc;
+ Bool have_descr, have_srcloc;
+ Bool xml = VG_(clo_xml);
UChar* vo_plural = var_offset == 1 ? "" : "s";
UChar* ro_plural = residual_offset == 1 ? "" : "s";
+ UChar* basetag = "auxwhat"; /* a constant */
+ UChar tagL[32], tagR[32], xagL[32], xagR[32];
vg_assert(frameNo >= -1);
- vg_assert(dname1 && dname2 && n_dname > 1);
+ vg_assert(dn1 && dn2);
vg_assert(described);
vg_assert(var && var->name);
have_descr = VG_(sizeXA)(described) > 0
&& *(UChar*)VG_(indexXA)(described,0) != '\0';
have_srcloc = var->fileName && var->lineNo > 0;
- dname1[0] = dname2[0] = '\0';
+ tagL[0] = tagR[0] = xagL[0] = xagR[0] = 0;
+ if (xml) {
+ VG_(sprintf)(tagL, "<%s>", basetag); // <auxwhat>
+ VG_(sprintf)(tagR, "</%s>", basetag); // </auxwhat>
+ VG_(sprintf)(xagL, "<x%s>", basetag); // <xauxwhat>
+ VG_(sprintf)(xagR, "</x%s>", basetag); // </xauxwhat>
+ }
+
+# define TAGL(_xa) p2XA(_xa, "%s", tagL)
+# define TAGR(_xa) p2XA(_xa, "%s", tagR)
+# define XAGL(_xa) p2XA(_xa, "%s", xagL)
+# define XAGR(_xa) p2XA(_xa, "%s", xagR)
+# define TXTL(_xa) p2XA(_xa, "%s", "<text>")
+# define TXTR(_xa) p2XA(_xa, "%s", "</text>")
/* ------ local cases ------ */
@@ -2365,13 +2413,23 @@
Location 0x7fefff6cf is 543 bytes inside local var "a",
in frame #1 of thread 1
*/
- VG_(snprintf)(
- dname1, n_dname,
- "Location 0x%lx is %lu byte%s inside local var \"%s\",",
- data_addr, var_offset, vo_plural, var->name );
- VG_(snprintf)(
- dname2, n_dname,
- "in frame #%d of thread %d", frameNo, (Int)tid);
+ if (xml) {
+ TAGL( dn1 );
+ p2XA( dn1,
+ "Location 0x%lx is %lu byte%s inside local var \"%t\",",
+ data_addr, var_offset, vo_plural, var->name );
+ TAGR( dn1 );
+ TAGL( dn2 );
+ p2XA( dn2,
+ "in frame #%d of thread %d", frameNo, (Int)tid );
+ TAGR( dn2 );
+ } else {
+ p2XA( dn1,
+ "Location 0x%lx is %lu byte%s inside local var \"%s\",",
+ data_addr, var_offset, vo_plural, var->name );
+ p2XA( dn2,
+ "in frame #%d of thread %d", frameNo, (Int)tid );
+ }
}
else
if ( frameNo >= 0 && have_srcloc && (!have_descr) ) {
@@ -2379,14 +2437,31 @@
Location 0x7fefff6cf is 543 bytes inside local var "a"
declared at dsyms7.c:17, in frame #1 of thread 1
*/
- VG_(snprintf)(
- dname1, n_dname,
- "Location 0x%lx is %lu byte%s inside local var \"%s\"",
- data_addr, var_offset, vo_plural, var->name );
- VG_(snprintf)(
- dname2, n_dname,
- "declared at %s:%d, in frame #%d of thread %d",
- var->fileName, var->lineNo, frameNo, (Int)tid);
+ if (xml) {
+ TAGL( dn1 );
+ p2XA( dn1,
+ "Location 0x%lx is %lu byte%s inside local var \"%t\"",
+ data_addr, var_offset, vo_plural, var->name );
+ TAGR( dn1 );
+ XAGL( dn2 );
+ TXTL( dn2 );
+ p2XA( dn2,
+ "declared at %t:%d, in frame #%d of thread %d",
+ var->fileName, var->lineNo, frameNo, (Int)tid );
+ TXTR( dn2 );
+ // FIXME: also do <dir>
+ p2XA( dn2,
+ " <file>%t</file> <line>%d</line> ",
+ var->fileName, var->lineNo );
+ XAGR( dn2 );
+ } else {
+ p2XA( dn1,
+ "Location 0x%lx is %lu byte%s inside local var \"%s\"",
+ data_addr, var_offset, vo_plural, var->name );
+ p2XA( dn2,
+ "declared at %s:%d, in frame #%d of thread %d",
+ var->fileName, var->lineNo, frameNo, (Int)tid );
+ }
}
else
if ( frameNo >= 0 && (!have_srcloc) && have_descr ) {
@@ -2394,28 +2469,57 @@
Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2
in frame #1 of thread 1
*/
- VG_(snprintf)(
- dname1, n_dname,
- "Location 0x%lx is %lu byte%s inside %s%s",
- data_addr, residual_offset, ro_plural, var->name,
- (char*)(VG_(indexXA)(described,0)) );
- VG_(snprintf)(
- dname2, n_dname,
- "in frame #%d of thread %d", frameNo, (Int)tid);
+ if (xml) {
+ TAGL( dn1 );
+ p2XA( dn1,
+ "Location 0x%lx is %lu byte%s inside %t%t",
+ data_addr, residual_offset, ro_plural, var->name,
+ (HChar*)(VG_(indexXA)(described,0)) );
+ TAGR( dn1 );
+ TAGL( dn2 );
+ p2XA( dn2,
+ "in frame #%d of thread %d", frameNo, (Int)tid );
+ TAGR( dn2 );
+ } else {
+ p2XA( dn1,
+ "Location 0x%lx is %lu byte%s inside %s%s",
+ data_addr, residual_offset, ro_plural, var->name,
+ (HChar*)(VG_(indexXA)(described,0)) );
+ p2XA( dn2,
+ "in frame #%d of thread %d", frameNo, (Int)tid );
+ }
}
else
if ( frameNo >= 0 && have_srcloc && have_descr ) {
- /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
- declared at dsyms7.c:17, in frame #1 of thread 1 */
- VG_(snprintf)(
- dname1, n_dname,
- "Location 0x%lx is %lu byte%s inside %s%s,",
- data_addr, residual_offset, ro_plural, var->name,
- (char*)(VG_(indexXA)(described,0)) );
- VG_(snprintf)(
- dname2, n_dname,
- "declared at %s:%d, in frame #%d of thread %d",
- var->fileName, var->lineNo, frameNo, (Int)tid);
+ /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
+ declared at dsyms7.c:17, in frame #1 of thread 1 */
+ if (xml) {
+ TAGL( dn1 );
+ p2XA( dn1,
+ "Location 0x%lx is %lu byte%s inside %t%t,",
+ data_addr, residual_offset, ro_plural, var->name,
+ (HChar*)(VG_(indexXA)(described,0)) );
+ TAGR( dn1 );
+ XAGL( dn2 );
+ TXTL( dn2 );
+ p2XA( dn2,
+ "declared at %t:%d, in frame #%d of thread %d",
+ var->fileName, var->lineNo, frameNo, (Int)tid );
+ TXTR( dn2 );
+ // FIXME: also do <dir>
+ p2XA( dn2,
+ " <file>%t</file> <line>%d</line> ",
+ var->fileName, var->lineNo );
+ XAGR( dn2 );
+ } else {
+ p2XA( dn1,
+ "Location 0x%lx is %lu byte%s inside %s%s,",
+ data_addr, residual_offset, ro_plural, var->name,
+ (HChar*)(VG_(indexXA)(described,0)) );
+ p2XA( dn2,
+ "declared at %s:%d, in frame #%d of thread %d",
+ var->fileName, var->lineNo, frameNo, (Int)tid );
+ }
}
else
/* ------ global cases ------ */
@@ -2423,10 +2527,17 @@
/* no srcloc, no description:
Location 0x7fefff6cf is 543 bytes inside global var "a"
*/
- VG_(snprintf)(
- dname1, n_dname,
- "Location 0x%lx is %lu byte%s inside global var \"%s\"",
- data_addr, var_offset, vo_plural, var->name );
+ if (xml) {
+ TAGL( dn1 );
+ p2XA( dn1,
+ "Location 0x%lx is %lu byte%s inside global var \"%t\"",
+ data_addr, var_offset, vo_plural, var->name );
+ TAGR( dn1 );
+ } else {
+ p2XA( dn1,
+ "Location 0x%lx is %lu byte%s inside global var \"%s\"",
+ data_addr, var_offset, vo_plural, var->name );
+ }
}
else
if ( frameNo >= -1 && have_srcloc && (!have_descr) ) {
@@ -2434,14 +2545,31 @@
Location 0x7fefff6cf is 543 bytes inside global var "a"
declared at dsyms7.c:17
*/
- VG_(snprintf)(
- dname1, n_dname,
- "Location 0x%lx is %lu byte%s inside global var \"%s\"",
- data_addr, var_offset, vo_plural, var->name );
- VG_(snprintf)(
- dname2, n_dname,
- "declared at %s:%d",
- var->fileName, var->lineNo);
+ if (xml) {
+ TAGL( dn1 );
+ p2XA( dn1,
+ "Location 0x%lx is %lu byte%s inside global var \"%t\"",
+ data_addr, var_offset, vo_plural, var->name );
+ TAGR( dn1 );
+ XAGL( dn2 );
+ TXTL( dn2 );
+ p2XA( dn2,
+ "declared at %t:%d",
+ var->fileName, var->lineNo);
+ TXTR( dn2 );
+ // FIXME: also do <dir>
+ p2XA( dn2,
+ " <file>%t</file> <line>%d</line> ",
+ var->fileName, var->lineNo );
+ XAGR( dn2 );
+ } else {
+ p2XA( dn1,
+ "Location 0x%lx is %lu byte%s inside global var \"%s\"",
+ data_addr, var_offset, vo_plural, var->name );
+ p2XA( dn2,
+ "declared at %s:%d",
+ var->fileName, var->lineNo);
+ }
}
else
if ( frameNo >= -1 && (!have_srcloc) && have_descr ) {
@@ -2449,43 +2577,82 @@
Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
a global variable
*/
- VG_(snprintf)(
- dname1, n_dname,
- "Location 0x%lx is %lu byte%s inside %s%s,",
- data_addr, residual_offset, ro_plural, var->name,
- (char*)(VG_(indexXA)(described,0)) );
- VG_(snprintf)(
- dname2, n_dname,
- "a global variable");
+ if (xml) {
+ TAGL( dn1 );
+ p2XA( dn1,
+ "Location 0x%lx is %lu byte%s inside %t%t,",
+ data_addr, residual_offset, ro_plural, var->name,
+ (HChar*)(VG_(indexXA)(described,0)) );
+ TAGR( dn1 );
+ TAGL( dn2 );
+ p2XA( dn2,
+ "a global variable");
+ TAGR( dn2 );
+ } else {
+ p2XA( dn1,
+ "Location 0x%lx is %lu byte%s inside %s%s,",
+ data_addr, residual_offset, ro_plural, var->name,
+ (char*)(VG_(indexXA)(described,0)) );
+ p2XA( dn2,
+ "a global variable");
+ }
}
else
if ( frameNo >= -1 && have_srcloc && have_descr ) {
- /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
- a global variable declared at dsyms7.c:17 */
- VG_(snprintf)(
- dname1, n_dname,
- "Location 0x%lx is %lu byte%s inside %s%s,",
- data_addr, residual_offset, ro_plural, var->name,
- (char*)(VG_(indexXA)(described,0)) );
- VG_(snprintf)(
- dname2, n_dname,
- "a global variable declared at %s:%d",
- var->fileName, var->lineNo);
+ /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
+ a global variable declared at dsyms7.c:17 */
+ if (xml) {
+ TAGL( dn1 );
+ p2XA( dn1,
+ "Location 0x%lx is %lu byte%s inside %t%t,",
+ data_addr, residual_offset, ro_plural, var->name,
+ (HChar*)(VG_(indexXA)(described,0)) );
+ TAGR( dn1 );
+ XAGL( dn2 );
+ TXTL( dn2 );
+ p2XA( dn2,
+ "a global variable declared at %t:%d",
+ var->fileName, var->lineNo);
+ TXTR( dn2 );
+ // FIXME: also do <dir>
+ p2XA( dn2,
+ " <file>%t</file> <line>%d</line> ",
+ var->fileName, var->lineNo );
+ XAGR( dn2 );
+ } else {
+ p2XA( dn1,
+ "Location 0x%lx is %lu byte%s inside %s%s,",
+ data_addr, residual_offset, ro_plural, var->name,
+ (HChar*)(VG_(indexXA)(described,0)) );
+ p2XA( dn2,
+ "a global variable declared at %s:%d",
+ var->fileName, var->lineNo);
+ }
}
else
vg_assert(0);
- dname1[n_dname-1] = dname2[n_dname-1] = 0;
+ /* Zero terminate both strings */
+ zterm_XA( dn1 );
+ zterm_XA( dn2 );
+
+# undef TAGL
+# undef TAGR
+# undef XAGL
+# undef XAGR
+# undef TXTL
+# undef TXTR
}
+
/* Determine if data_addr is a local variable in the frame
- characterised by (ip,sp,fp), and if so write its description into
- dname{1,2}[0..n_dname-1], and return True. If not, return
- False. */
+ characterised by (ip,sp,fp), and if so write its description at the
+ ends of DNAME{1,2}, which are XArray*s of HChar, that have been
+ initialised by the caller, zero terminate both, and return True.
+ If it's not a local variable in said frame, return False. */
static
-Bool consider_vars_in_frame ( /*OUT*/Char* dname1,
- /*OUT*/Char* dname2,
- Int n_dname,
+Bool consider_vars_in_frame ( /*MOD*/XArray* /* of HChar */ dname1,
+ /*MOD*/XArray* /* of HChar */ dname2,
Addr data_addr,
Addr ip, Addr sp, Addr fp,
/* shown to user: */
@@ -2593,7 +2760,7 @@
XArray* described = ML_(describe_type)( &residual_offset,
di->admin_tyents,
var->typeR, offset );
- format_message( dname1, dname2, n_dname,
+ format_message( dname1, dname2,
data_addr, var, offset, residual_offset,
described, frameNo, tid );
VG_(deleteXA)( described );
@@ -2605,15 +2772,24 @@
return False;
}
-/* Try to form some description of data_addr by looking at the DWARF3
+/* Try to form some description of DATA_ADDR by looking at the DWARF3
debug info we have. This considers all global variables, and all
- frames in the stacks of all threads. Result (or as much as will
- fit) is put into into dname{1,2}[0 .. n_dname-1] and is guaranteed
- to be zero terminated. */
-Bool VG_(get_data_description)( /*OUT*/Char* dname1,
- /*OUT*/Char* dname2,
- Int n_dname,
- Addr data_addr )
+ frames in the stacks of all threads. Result is written at the ends
+ of DNAME{1,2}V, which are XArray*s of HChar, that have been
+ initialised by the caller, and True is returned. If no description
+ is created, False is returned. Regardless of the return value,
+ DNAME{1,2}V are guaranteed to be zero terminated after the call.
+
+ Note that after the call, DNAME{1,2} may have more than one
+ trailing zero, so callers should establish the useful text length
+ using VG_(strlen) on the contents, rather than VG_(sizeXA) on the
+ XArray itself.
+*/
+Bool VG_(get_data_description)(
+ /*MOD*/ void* /* really, XArray* of HChar */ dname1v,
+ /*MOD*/ void* /* really, XArray* of HChar */ dname2v,
+ Addr data_addr
+ )
{
# define N_FRAMES 8
Addr ips[N_FRAMES], sps[N_FRAMES], fps[N_FRAMES];
@@ -2625,8 +2801,8 @@
DebugInfo* di;
Word j;
- vg_assert(n_dname > 1);
- dname1[n_dname-1] = dname2[n_dname-1] = 0;
+ XArray* dname1 = (XArray*)dname1v;
+ XArray* dname2 = (XArray*)dname2v;
if (0) VG_(printf)("get_data_description: dataaddr %#lx\n", data_addr);
/* First, see if data_addr is (or is part of) a global variable.
@@ -2692,11 +2868,12 @@
XArray* described = ML_(describe_type)( &residual_offset,
di->admin_tyents,
var->typeR, offset );
- format_message( dname1, dname2, n_dname,
+ format_message( dname1, dname2,
data_addr, var, offset, residual_offset,
described, -1/*frameNo*/, tid );
VG_(deleteXA)( described );
- dname1[n_dname-1] = dname2[n_dname-1] = 0;
+ zterm_XA( dname1 );
+ zterm_XA( dname2 );
return True;
}
}
@@ -2716,12 +2893,13 @@
while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) {
if (stack_min >= stack_max)
continue; /* ignore obviously stupid cases */
- if (consider_vars_in_frame( dname1, dname2, n_dname,
+ if (consider_vars_in_frame( dname1, dname2,
data_addr,
VG_(get_IP)(tid),
VG_(get_SP)(tid),
VG_(get_FP)(tid), tid, 0 )) {
- dname1[n_dname-1] = dname2[n_dname-1] = 0;
+ zterm_XA( dname1 );
+ zterm_XA( dname2 );
return True;
}
}
@@ -2740,7 +2918,8 @@
}
}
if (!found) {
- dname1[n_dname-1] = dname2[n_dname-1] = 0;
+ zterm_XA( dname1 );
+ zterm_XA( dname2 );
return False;
}
@@ -2755,11 +2934,12 @@
Oh well. */
vg_assert(n_frames >= 0 && n_frames <= N_FRAMES);
for (j = 0; j < n_frames; j++) {
- if (consider_vars_in_frame( dname1, dname2, n_dname,
+ if (consider_vars_in_frame( dname1, dname2,
data_addr,
ips[j],
sps[j], fps[j], tid, j )) {
- dname1[n_dname-1] = dname2[n_dname-1] = 0;
+ zterm_XA( dname1 );
+ zterm_XA( dname2 );
return True;
}
/* Now, it appears that gcc sometimes appears to produce
@@ -2781,17 +2961,19 @@
either (1) I misunderstood something, or (2) GDB has an
equivalent kludge. */
if (j > 0 /* this is a non-innermost frame */
- && consider_vars_in_frame( dname1, dname2, n_dname,
+ && consider_vars_in_frame( dname1, dname2,
data_addr,
ips[j] + 1,
sps[j], fps[j], tid, j )) {
- dname1[n_dname-1] = dname2[n_dname-1] = 0;
+ zterm_XA( dname1 );
+ zterm_XA( dname2 );
return True;
}
}
/* We didn't find anything useful. */
- dname1[n_dname-1] = dname2[n_dname-1] = 0;
+ zterm_XA( dname1 );
+ zterm_XA( dname2 );
return False;
# undef N_FRAMES
}
diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c
index 24bb473..0271657 100644
--- a/coregrind/m_debuginfo/readdwarf.c
+++ b/coregrind/m_debuginfo/readdwarf.c
@@ -347,7 +347,7 @@
if (len == 0) {
VG_(message)(Vg_UserMsg,
"Warning: DWARF2 reader: "
- "Badly formed extended line op encountered");
+ "Badly formed extended line op encountered\n");
return (Word)bytes_read;
}
@@ -2167,7 +2167,7 @@
if (VG_(clo_verbosity) > 2 || debuginfo->trace_cfi) {
VG_(message)(Vg_DebugMsg,
"summarise_context(loc_start = %#lx)"
- ": cannot summarise(why=%d): ", loc_start, why);
+ ": cannot summarise(why=%d): \n", loc_start, why);
ppUnwindContext(ctx);
}
return False;
@@ -2648,7 +2648,7 @@
if (!VG_(clo_xml))
VG_(message)(Vg_DebugMsg,
"Warning: DWARF2 CFI reader: unhandled DW_OP_ "
- "opcode 0x%x", (Int)opcode);
+ "opcode 0x%x\n", (Int)opcode);
return -1;
}
@@ -3089,7 +3089,7 @@
default:
VG_(message)(Vg_DebugMsg, "DWARF2 CFI reader: unhandled CFI "
- "instruction 0:%d", (Int)lo6);
+ "instruction 0:%d\n", (Int)lo6);
if (di->ddump_frames)
VG_(printf)(" rci:run_CF_instruction:default\n");
i = 0;
@@ -3877,7 +3877,8 @@
bad:
if (!VG_(clo_xml) && VG_(clo_verbosity) > 1)
- VG_(message)(Vg_UserMsg, "Warning: %s in DWARF2 CFI reading", how);
+ VG_(message)(Vg_UserMsg,
+ "Warning: %s in DWARF2 CFI reading\n", how);
return;
}
diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c
index db46cc3..3c194b9 100644
--- a/coregrind/m_debuginfo/readdwarf3.c
+++ b/coregrind/m_debuginfo/readdwarf3.c
@@ -1675,7 +1675,7 @@
if (0 && VG_(clo_verbosity) >= 0) {
VG_(message)(Vg_DebugMsg,
"warning: parse_var_DIE: non-external variable "
- "outside DW_TAG_subprogram");
+ "outside DW_TAG_subprogram\n");
}
/* goto bad_DIE; */
/* This seems to happen a lot. Just ignore it -- if,
diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c
index 2da1cf2..02cea02 100644
--- a/coregrind/m_debuginfo/readelf.c
+++ b/coregrind/m_debuginfo/readelf.c
@@ -925,7 +925,7 @@
}
if (VG_(clo_verbosity) > 1)
- VG_(message)(Vg_DebugMsg, "Reading debug info from %s ..", name);
+ VG_(message)(Vg_DebugMsg, "Reading debug info from %s ..\n", name);
*size = stat_buf.size;
@@ -943,7 +943,7 @@
vg_assert(!sr_isError(res));
if (VG_(clo_verbosity) > 1)
VG_(message)(Vg_DebugMsg,
- ".. CRC mismatch (computed %08x wanted %08x)", calccrc, crc);
+ ".. CRC mismatch (computed %08x wanted %08x)\n", calccrc, crc);
return 0;
}
@@ -1115,7 +1115,7 @@
oimage = (Addr)NULL;
if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))
- VG_(message)(Vg_DebugMsg, "Reading syms from %s (%#lx)",
+ VG_(message)(Vg_DebugMsg, "Reading syms from %s (%#lx)\n",
di->filename, di->rx_map_avma );
/* mmap the object image aboard, so that we can read symbols and
@@ -1143,8 +1143,8 @@
VG_(close)(sr_Res(fd));
if (sr_isError(sres)) {
- VG_(message)(Vg_UserMsg, "warning: mmap failed on %s", di->filename );
- VG_(message)(Vg_UserMsg, " no symbols or debug info loaded" );
+ VG_(message)(Vg_UserMsg, "warning: mmap failed on %s\n", di->filename );
+ VG_(message)(Vg_UserMsg, " no symbols or debug info loaded\n" );
return False;
}
@@ -1491,11 +1491,12 @@
di->bss_debug_svma = 0;
di->bss_debug_bias = 0;
if (!VG_(clo_xml)) {
- VG_(message)(Vg_UserMsg, "Warning: the following file's .bss is "
- "mapped r-x only - ignoring .bss syms");
- VG_(message)(Vg_UserMsg, " %s", di->filename
- ? di->filename
- : (UChar*)"(null?!)" );
+ VG_(message)(Vg_UserMsg,
+ "Warning: the following file's .bss is "
+ "mapped r-x only - ignoring .bss syms\n");
+ VG_(message)(Vg_UserMsg, " %s\n", di->filename
+ ? di->filename
+ : (UChar*)"(null?!)" );
}
} else
@@ -1646,7 +1647,7 @@
di->text_avma, di->text_size, di->text_bias);
if (VG_(clo_verbosity) > 2 || VG_(clo_trace_redir))
- VG_(message)(Vg_DebugMsg, " svma %#010lx, avma %#010lx",
+ VG_(message)(Vg_DebugMsg, " svma %#010lx, avma %#010lx\n",
di->text_avma - di->text_bias,
di->text_avma );
diff --git a/coregrind/m_debuginfo/readpdb.c b/coregrind/m_debuginfo/readpdb.c
index 88fb7f6..2eae5da 100644
--- a/coregrind/m_debuginfo/readpdb.c
+++ b/coregrind/m_debuginfo/readpdb.c
@@ -1220,8 +1220,9 @@
ULong n_syms_read = 0;
if (debug)
- VG_(message)(Vg_UserMsg, "SnarfCodeView addr=%p offset=%d length=%d",
- root, offset, size );
+ VG_(message)(Vg_UserMsg,
+ "SnarfCodeView addr=%p offset=%d length=%d\n",
+ root, offset, size );
VG_(memset)(&vsym, 0, sizeof(vsym)); /* avoid holes */
/*
@@ -1261,7 +1262,7 @@
symname[sym->data_v1.p_name.namelen] = '\0';
if (debug)
- VG_(message)(Vg_UserMsg, "Data %s", symname );
+ VG_(message)(Vg_UserMsg, "Data %s\n", symname );
if (0 /*VG_(needs).data_syms*/) {
nmstr = ML_(addStr)(di, symname, sym->data_v1.p_name.namelen);
@@ -1285,7 +1286,7 @@
if (debug)
VG_(message)(Vg_UserMsg,
- "S_GDATA_V2/S_LDATA_V2/S_PUB_V2 %s", symname );
+ "S_GDATA_V2/S_LDATA_V2/S_PUB_V2 %s\n", symname );
if (sym->generic.id==S_PUB_V2 /*VG_(needs).data_syms*/) {
nmstr = ML_(addStr)(di, symname, k);
@@ -1315,7 +1316,8 @@
if (debug)
VG_(message)(Vg_UserMsg,
- "S_PUB_FUNC1_V3/S_PUB_FUNC2_V3/S_PUB_V3 %s", symname );
+ "S_PUB_FUNC1_V3/S_PUB_FUNC2_V3/S_PUB_V3 %s\n",
+ symname );
if (1 /*sym->generic.id==S_PUB_FUNC1_V3
|| sym->generic.id==S_PUB_FUNC2_V3*/) {
@@ -1361,8 +1363,9 @@
vsym.size = sym->proc_v1.proc_len;
vsym.isText = True;
if (debug)
- VG_(message)(Vg_UserMsg, "Adding function %s addr=%#lx length=%d",
- symname, vsym.addr, vsym.size );
+ VG_(message)(Vg_UserMsg,
+ "Adding function %s addr=%#lx length=%d\n",
+ symname, vsym.addr, vsym.size );
ML_(addSym)( di, &vsym );
n_syms_read++;
break;
@@ -1380,8 +1383,9 @@
vsym.size = sym->proc_v2.proc_len;
vsym.isText = True;
if (debug)
- VG_(message)(Vg_UserMsg, "Adding function %s addr=%#lx length=%d",
- symname, vsym.addr, vsym.size );
+ VG_(message)(Vg_UserMsg,
+ "Adding function %s addr=%#lx length=%d\n",
+ symname, vsym.addr, vsym.size );
ML_(addSym)( di, &vsym );
n_syms_read++;
break;
@@ -1389,7 +1393,7 @@
case S_GPROC_V3: {
if (debug)
VG_(message)(Vg_UserMsg,
- "S_LPROC_V3/S_GPROC_V3 %s", sym->proc_v3.name );
+ "S_LPROC_V3/S_GPROC_V3 %s\n", sym->proc_v3.name );
if (1) {
nmstr = ML_(addStr)(di, sym->proc_v3.name,
@@ -1590,7 +1594,7 @@
if (debug)
VG_(message)(Vg_UserMsg,
- "Adding %d lines for file %s segment %d addr=%#x end=%#x",
+ "Adding %d lines for file %s segment %d addr=%#x end=%#x\n",
linecount, filename, segno, start[k].start, start[k].end );
for ( j = 0; j < linecount; j++ ) {
@@ -1602,7 +1606,7 @@
: start[k].end);
if (debug)
VG_(message)(Vg_UserMsg,
- "Adding line %d addr=%#lx end=%#lx",
+ "Adding line %d addr=%#lx end=%#lx\n",
((unsigned short *)(pnt2.ui + linecount))[j],
startaddr, endaddr );
ML_(addLineInfo)(
@@ -1811,21 +1815,21 @@
if (VG_(clo_verbosity) > 0) {
VG_(message)(Vg_DebugMsg,
- "PDB_READER:");
+ "PDB_READER:\n");
VG_(message)(Vg_DebugMsg,
- " BIAS_FOR_SYMBOLS = %#08lx %s",
+ " BIAS_FOR_SYMBOLS = %#08lx %s\n",
(PtrdiffT)BIAS_FOR_SYMBOLS, VG_STRINGIFY(BIAS_FOR_SYMBOLS));
VG_(message)(Vg_DebugMsg,
- " BIAS_FOR_LINETAB = %#08lx %s",
+ " BIAS_FOR_LINETAB = %#08lx %s\n",
(PtrdiffT)BIAS_FOR_LINETAB, VG_STRINGIFY(BIAS_FOR_LINETAB));
VG_(message)(Vg_DebugMsg,
- " BIAS_FOR_LINETAB2 = %#08lx %s",
+ " BIAS_FOR_LINETAB2 = %#08lx %s\n",
(PtrdiffT)BIAS_FOR_LINETAB2, VG_STRINGIFY(BIAS_FOR_LINETAB2));
VG_(message)(Vg_DebugMsg,
- " BIAS_FOR_FPO = %#08lx %s",
+ " BIAS_FOR_FPO = %#08lx %s\n",
(PtrdiffT)BIAS_FOR_FPO, VG_STRINGIFY(BIAS_FOR_FPO));
VG_(message)(Vg_DebugMsg,
- " RELOC = %#08lx",
+ " RELOC = %#08lx\n",
(PtrdiffT)reloc);
}
@@ -1917,8 +1921,9 @@
break;
default:
if (VG_(clo_verbosity) > 1)
- VG_(message)(Vg_UserMsg, "Unknown .pdb type info version %ld\n",
- types.version );
+ VG_(message)(Vg_UserMsg,
+ "Unknown .pdb type info version %ld\n",
+ types.version );
}
header_size = 0;
@@ -1931,8 +1936,9 @@
break;
default:
if (VG_(clo_verbosity) > 1)
- VG_(message)(Vg_UserMsg, "Unknown .pdb symbol info version %ld\n",
- symbols.version );
+ VG_(message)(Vg_UserMsg,
+ "Unknown .pdb symbol info version %ld\n",
+ symbols.version );
}
/*
@@ -1980,7 +1986,8 @@
if (symbol_size) {
if (VG_(clo_verbosity) > 1)
- VG_(message)(Vg_UserMsg, "Reading symbols for %s", file_name );
+ VG_(message)(Vg_UserMsg, "Reading symbols for %s\n",
+ file_name );
n_syms_read
+= DEBUG_SnarfCodeView( di, sectp_avma, modimage,
sizeof(unsigned long),
@@ -1989,7 +1996,7 @@
if (lineno_size) {
if (VG_(clo_verbosity) > 1)
- VG_(message)(Vg_UserMsg, "Reading lines for %s", file_name );
+ VG_(message)(Vg_UserMsg, "Reading lines for %s\n", file_name );
n_lines_read
+= DEBUG_SnarfLinetab( di, sectp_avma,
modimage + symbol_size, lineno_size );
@@ -2027,10 +2034,14 @@
if ( pdb->u.jg.toc ) ML_(dinfo_free)( pdb->u.jg.toc );
if (VG_(clo_verbosity) > 0) {
- VG_(message)(Vg_DebugMsg," # symbols read = %llu", n_syms_read );
- VG_(message)(Vg_DebugMsg," # lines read = %llu", n_lines_read );
- VG_(message)(Vg_DebugMsg," # line2s read = %llu", n_line2s_read );
- VG_(message)(Vg_DebugMsg," # fpos read = %llu", n_fpos_read );
+ VG_(message)(Vg_DebugMsg,
+ " # symbols read = %llu\n", n_syms_read );
+ VG_(message)(Vg_DebugMsg,
+ " # lines read = %llu\n", n_lines_read );
+ VG_(message)(Vg_DebugMsg,
+ " # line2s read = %llu\n", n_line2s_read );
+ VG_(message)(Vg_DebugMsg,
+ " # fpos read = %llu\n", n_fpos_read );
}
}
@@ -2063,7 +2074,7 @@
IMAGE_SECTION_HEADER* pe_sechdr_avma;
if (VG_(clo_verbosity) > 1)
- VG_(message)(Vg_UserMsg, "Processing PDB file %s ", pdbname );
+ VG_(message)(Vg_UserMsg, "Processing PDB file %s\n", pdbname );
dos_avma = (IMAGE_DOS_HEADER *)obj_avma;
if (dos_avma->e_magic != IMAGE_DOS_SIGNATURE)
@@ -2103,7 +2114,7 @@
if (VG_(clo_verbosity) > 1)
VG_(message)(Vg_UserMsg,
- " Scanning PE section %s at avma %p svma %#lx",
+ " Scanning PE section %s at avma %p svma %#lx\n",
pe_sechdr_avma->Name, pe_seg_avma,
pe_sechdr_avma->VirtualAddress);
@@ -2114,7 +2125,7 @@
mapped_end_avma = mapped_avma + pe_sechdr_avma->Misc.VirtualSize;
if (VG_(clo_verbosity) > 1)
VG_(message)(Vg_DebugMsg,
- " ::: mapped_avma is %#lx", mapped_avma);
+ " ::: mapped_avma is %#lx\n", mapped_avma);
if (pe_sechdr_avma->Characteristics & IMAGE_SCN_CNT_CODE) {
/* Ignore uninitialised code sections - if you have
diff --git a/coregrind/m_debuginfo/readstabs.c b/coregrind/m_debuginfo/readstabs.c
index 1cd72c6..c8eaf2e 100644
--- a/coregrind/m_debuginfo/readstabs.c
+++ b/coregrind/m_debuginfo/readstabs.c
@@ -258,7 +258,7 @@
VG_(message)(Vg_UserMsg,
"Warning: file %s is very big (> 65535 lines) "
"Line numbers and annotation for this file might "
- "be wrong. Sorry",
+ "be wrong. Sorry.\n",
file.name);
/* FALLTHROUGH */
@@ -304,7 +304,7 @@
if (line.prev > line.no + OVERFLOW_DIFFERENCE && file.same) {
VG_(message)(Vg_DebugMsg,
- "Line number overflow detected (%d --> %d) in %s",
+ "Line number overflow detected (%d --> %d) in %s\n",
line.prev, line.no, file.name);
line.ovf++;
}
diff --git a/coregrind/m_debuginfo/readxcoff.c b/coregrind/m_debuginfo/readxcoff.c
index 1be4e94..466e423 100644
--- a/coregrind/m_debuginfo/readxcoff.c
+++ b/coregrind/m_debuginfo/readxcoff.c
@@ -1538,7 +1538,7 @@
"fixme-Name-printing(5)" /*s->name*/ );
if (guessed_toc)
- VG_(message)(Vg_DebugMsg, "WARNING: assuming toc 0x%lx for %s",
+ VG_(message)(Vg_DebugMsg, "WARNING: assuming toc 0x%lx for %s\n",
s->r2value, dis.name);
}
}
@@ -2424,10 +2424,10 @@
if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir)) {
if (di->memname) {
- VG_(message)(Vg_DebugMsg, "Reading syms from %s(%s) (%#lx)",
+ VG_(message)(Vg_DebugMsg, "Reading syms from %s(%s) (%#lx)\n",
di->filename, di->memname, di->text_avma);
} else {
- VG_(message)(Vg_DebugMsg, "Reading syms from %s (%#lx)",
+ VG_(message)(Vg_DebugMsg, "Reading syms from %s (%#lx)\n",
di->filename, di->text_avma);
}
}
diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c
index f8d0834..49ba306 100644
--- a/coregrind/m_debuginfo/storage.c
+++ b/coregrind/m_debuginfo/storage.c
@@ -68,20 +68,20 @@
if (serious) {
VG_(message)(Vg_DebugMsg, "WARNING: Serious error when "
- "reading debug info");
+ "reading debug info\n");
if (True || VG_(clo_verbosity) < 2) {
/* Need to show what the file name is, at verbosity levels 2
or below, since that won't already have been shown */
VG_(message)(Vg_DebugMsg,
- "When reading debug info from %s:",
+ "When reading debug info from %s:\n",
(di && di->filename) ? di->filename : (UChar*)"???");
}
- VG_(message)(Vg_DebugMsg, "%s", msg);
+ VG_(message)(Vg_DebugMsg, "%s\n", msg);
} else { /* !serious */
if (VG_(clo_verbosity) >= 2)
- VG_(message)(Vg_DebugMsg, "%s", msg);
+ VG_(message)(Vg_DebugMsg, "%s\n", msg);
}
}
@@ -90,11 +90,11 @@
/* Print a symbol. */
void ML_(ppSym) ( Int idx, DiSym* sym )
{
- VG_(printf)( "%5d: %#8lx .. %#8lx (%d) %s\n",
- idx,
- sym->addr,
- sym->addr + sym->size - 1, sym->size,
- sym->name );
+ VG_(printf)( "%5d: %#8lx .. %#8lx (%d) %s\n",
+ idx,
+ sym->addr,
+ sym->addr + sym->size - 1, sym->size,
+ sym->name );
}
/* Print a call-frame-info summary. */
@@ -329,7 +329,7 @@
if (VG_(clo_verbosity) > 2) {
VG_(message)(Vg_DebugMsg,
"warning: line info addresses out of order "
- "at entry %d: 0x%lx 0x%lx", entry, this, next);
+ "at entry %d: 0x%lx 0x%lx\n", entry, this, next);
}
size = 1;
}
@@ -338,7 +338,7 @@
if (0)
VG_(message)(Vg_DebugMsg,
"warning: line info address range too large "
- "at entry %d: %d", entry, size);
+ "at entry %d: %d\n", entry, size);
size = 1;
}
@@ -351,7 +351,7 @@
if (0)
VG_(message)(Vg_DebugMsg,
"warning: ignoring line info entry falling "
- "outside current DebugInfo: %#lx %#lx %#lx %#lx",
+ "outside current DebugInfo: %#lx %#lx %#lx %#lx\n",
di->text_avma,
di->text_avma + di->text_size,
this, next-1);
@@ -365,12 +365,12 @@
complained = True;
VG_(message)(Vg_UserMsg,
"warning: ignoring line info entry with "
- "huge line number (%d)", lineno);
+ "huge line number (%d)\n", lineno);
VG_(message)(Vg_UserMsg,
" Can't handle line numbers "
- "greater than %d, sorry", MAX_LINENO);
+ "greater than %d, sorry\n", MAX_LINENO);
VG_(message)(Vg_UserMsg,
- "(Nb: this message is only shown once)");
+ "(Nb: this message is only shown once)\n");
}
return;
}
@@ -382,7 +382,7 @@
loc.dirname = dirname;
if (0) VG_(message)(Vg_DebugMsg,
- "addLoc: addr %#lx, size %d, line %d, file %s",
+ "addLoc: addr %#lx, size %d, line %d, file %s\n",
this,size,lineno,filename);
addLoc ( di, &loc );
@@ -433,7 +433,7 @@
if (VG_(clo_verbosity) > 1) {
VG_(message)(
Vg_DebugMsg,
- "warning: DiCfSI %#lx .. %#lx outside segment %#lx .. %#lx",
+ "warning: DiCfSI %#lx .. %#lx outside segment %#lx .. %#lx\n",
cfsi.base,
cfsi.base + cfsi.len - 1,
di->text_avma,
@@ -871,7 +871,7 @@
if (VG_(clo_verbosity) >= 0) {
VG_(message)(Vg_DebugMsg,
"warning: addVar: in range %#lx .. %#lx outside "
- "segment %#lx .. %#lx (%s)",
+ "segment %#lx .. %#lx (%s)\n",
aMin, aMax,
di->text_avma, di->text_avma + di->text_size -1,
name
@@ -898,7 +898,7 @@
if (badness) {
static Int complaints = 10;
if (VG_(clo_verbosity) >= 2 && complaints > 0) {
- VG_(message)(Vg_DebugMsg, "warning: addVar: %s (%s)",
+ VG_(message)(Vg_DebugMsg, "warning: addVar: %s (%s)\n",
badness, name );
complaints--;
}
diff --git a/coregrind/m_demangle/demangle.c b/coregrind/m_demangle/demangle.c
index 7d8f6e3..9ad4b26 100644
--- a/coregrind/m_demangle/demangle.c
+++ b/coregrind/m_demangle/demangle.c
@@ -297,12 +297,14 @@
if (error) {
/* Something's wrong. Give up. */
- VG_(message)(Vg_UserMsg, "m_demangle: error Z-demangling: %s", sym);
+ VG_(message)(Vg_UserMsg,
+ "m_demangle: error Z-demangling: %s\n", sym);
return False;
}
if (oflow) {
/* It didn't fit. Give up. */
- VG_(message)(Vg_UserMsg, "m_demangle: oflow Z-demangling: %s", sym);
+ VG_(message)(Vg_UserMsg,
+ "m_demangle: oflow Z-demangling: %s\n", sym);
return False;
}
diff --git a/coregrind/m_errormgr.c b/coregrind/m_errormgr.c
index a5ef3c8..64ae47a 100644
--- a/coregrind/m_errormgr.c
+++ b/coregrind/m_errormgr.c
@@ -261,7 +261,8 @@
return VG_(needs).core_errors && VG_(clo_verbosity) >= 1 && !VG_(clo_xml);
}
-/* Compare errors, to detect duplicates. */
+/* Compare errors, to detect duplicates.
+*/
static Bool eq_Error ( VgRes res, Error* e1, Error* e2 )
{
if (e1->ekind != e2->ekind)
@@ -286,54 +287,99 @@
}
}
-static void pp_Error ( Error* err )
+
+/* Helper function for suppression generation: print a single line of
+ a suppression pseudo-stack-trace, either in XML or text mode.
+*/
+#define ERRTXT_LEN 4096
+
+static void printSuppForIp(UInt n, Addr ip)
{
- if (VG_(clo_xml)) {
- VG_UMSG("<error>");
- VG_UMSG(" <unique>0x%x</unique>", err->unique);
- VG_UMSG(" <tid>%d</tid>", err->tid);
- }
+ static UChar buf[ERRTXT_LEN];
- if (!VG_(clo_xml)) {
- if (VG_(tdict).tool_show_ThreadIDs_for_errors
- && err->tid > 0 && err->tid != last_tid_printed) {
- VG_UMSG("Thread %d:", err->tid );
- last_tid_printed = err->tid;
- }
- }
+ 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);
- switch (err->ekind) {
- //(example code, see comment on CoreSuppKind above)
- //case ThreadErr:
- // vg_assert(VG_(needs).core_errors);
- // VG_(tm_error_print)(err);
- // break;
- default:
- if (VG_(needs).tool_errors)
- VG_TDICT_CALL( tool_pp_Error, err );
- else {
- VG_(printf)("\nUnhandled error type: %u. VG_(needs).tool_errors\n"
- "probably needs to be set?\n",
- err->ekind);
- VG_(tool_panic)("unhandled error type");
- }
+ } else {
+ if (VG_(clo_xml))
+ VG_(printf_xml_no_f_c)(" <sframe> <obj>*</obj> </sframe>\n");
+ else
+ VG_(printf)(" obj:*\n");
}
-
- if (VG_(clo_xml))
- VG_UMSG("</error>");
}
-/* Figure out if we want to perform a given action for this error, possibly
- by asking the user. */
+
+/* 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);
+
+ //(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");
+
+ } 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);
+ }
+
+ // Print stack trace elements
+ VG_(apply_StackTrace)(printSuppForIp,
+ VG_(get_ExeContext_StackTrace)(ec),
+ VG_(get_ExeContext_n_ips)(ec));
+
+ if (VG_(clo_xml)) {
+ VG_(printf_xml)(" </suppression>\n");
+ } else {
+ VG_(printf)("}\n");
+ }
+}
+
+
+/* Figure out if we want to perform a given action for this error,
+ possibly by asking the user.
+*/
Bool VG_(is_action_requested) ( Char* action, Bool* clo )
{
Char ch, ch2;
Int res;
+ /* First off, we shouldn't be asking the user anything if
+ we're in XML mode. */
+ if (VG_(clo_xml))
+ return False; /* That's a Nein, oder Nay as they say down here in B-W */
+
if (*clo == False)
return False;
- VG_UMSG("");
+ VG_(umsg)("\n");
again:
VG_(printf)(
@@ -366,8 +412,120 @@
}
+/* Do text-mode actions on error, that is, immediately after an error
+ is printed. These are:
+ * possibly, attach to a debugger
+ * possibly, generate a suppression.
+ Note this should not be called in XML mode!
+*/
+static
+void do_actions_on_error(Error* err, Bool allow_db_attach)
+{
+ Bool still_noisy = True;
+
+ /* Should be assured by caller */
+ vg_assert( ! VG_(clo_xml) );
+
+ /* Perhaps we want a debugger attach at this point? */
+ if (allow_db_attach &&
+ VG_(is_action_requested)( "Attach to debugger", & VG_(clo_db_attach) ))
+ {
+ if (0) VG_(printf)("starting debugger\n");
+ VG_(start_debugger)( err->tid );
+ }
+ /* Or maybe we want to generate the error's suppression? */
+ if (VG_(clo_gen_suppressions) == 2
+ || (VG_(clo_gen_suppressions) == 1
+ && VG_(is_action_requested)( "Print suppression", &still_noisy ))
+ ) {
+ gen_suppression(err);
+ }
+ if (VG_(clo_gen_suppressions) == 1 && !still_noisy)
+ VG_(clo_gen_suppressions) = 0;
+}
+
+
+/* Prints an error. Not entirely simple because of the differences
+ between XML and text mode output.
+
+ In XML mode:
+
+ * calls the tool's pre-show method, so the tool can create any
+ preamble ahead of the message, if it wants.
+
+ * prints the opening tag, and the <unique> and <tid> fields
+
+ * prints the tool-specific parts of the message
+
+ * if suppression generation is required, a suppression
+
+ * the closing tag
+
+ In text mode:
+
+ * calls the tool's pre-show method, so the tool can create any
+ preamble ahead of the message, if it wants.
+
+ * prints the tool-specific parts of the message
+
+ * calls do_actions_on_error. This optionally does a debugger
+ attach (and detach), and optionally prints a suppression; both
+ of these may require user input.
+*/
+static void pp_Error ( Error* err, Bool allow_db_attach )
+{
+ /* If this fails, you probably specified your tool's method
+ dictionary incorrectly. */
+ vg_assert(VG_(needs).tool_errors);
+
+ if (VG_(clo_xml)) {
+
+ /* Note, allow_db_attach is ignored in here. */
+
+ /* Ensure that suppression generation is either completely
+ enabled or completely disabled; either way, we won't require
+ any user input. m_main.process_cmd_line_options should
+ ensure the asserted condition holds. */
+ vg_assert( VG_(clo_gen_suppressions) == 0 /* disabled */
+ || VG_(clo_gen_suppressions) == 2 /* for all errors */ );
+
+ /* Pre-show it to the tool */
+ VG_TDICT_CALL( tool_before_pp_Error, err );
+
+ /* standard preamble */
+ VG_(printf_xml)("<error>\n");
+ VG_(printf_xml)(" <unique>0x%x</unique>\n", err->unique);
+ VG_(printf_xml)(" <tid>%d</tid>\n", err->tid);
+
+ /* actually print it */
+ VG_TDICT_CALL( tool_pp_Error, err );
+
+ if (VG_(clo_gen_suppressions) > 0)
+ gen_suppression(err);
+
+ /* postamble */
+ VG_(printf_xml)("</error>\n");
+
+ } else {
+
+ VG_TDICT_CALL( tool_before_pp_Error, err );
+
+ if (VG_(tdict).tool_show_ThreadIDs_for_errors
+ && err->tid > 0 && err->tid != last_tid_printed) {
+ VG_(umsg)("Thread %d:\n", err->tid );
+ last_tid_printed = err->tid;
+ }
+
+ VG_TDICT_CALL( tool_pp_Error, err );
+
+ do_actions_on_error(err, allow_db_attach);
+
+ }
+}
+
+
/* Construct an error */
-static __inline__
+static
void construct_error ( Error* err, ThreadId tid, ErrorKind ekind, Addr a,
Char* s, void* extra, ExeContext* where )
{
@@ -397,75 +555,7 @@
vg_assert( tid < VG_N_THREADS );
}
-#define ERRTXT_LEN 4096
-static void printSuppForIp(UInt n, Addr ip)
-{
- static UChar buf[ERRTXT_LEN];
-
- if ( VG_(get_fnname_no_cxx_demangle) (ip, buf, ERRTXT_LEN) ) {
- VG_(printf)(" fun:%s\n", buf);
- } else if ( VG_(get_objname)(ip, buf, ERRTXT_LEN) ) {
- VG_(printf)(" obj:%s\n", buf);
- } else {
- VG_(printf)(" obj:*\n");
- }
-}
-
-static void gen_suppression(Error* err)
-{
- ExeContext* ec = VG_(get_error_where)(err);
-
- //(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");
-
- } else {
- Char* name = VG_TDICT_CALL(tool_get_error_name, err);
- if (NULL == name) {
- VG_UMSG("(%s does not allow error to be suppressed)",
- VG_(details).name);
- return;
- }
- 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);
- }
-
- // Print stack trace elements
- VG_(apply_StackTrace)(printSuppForIp,
- VG_(get_ExeContext_StackTrace)(ec),
- VG_(get_ExeContext_n_ips)(ec));
-
- VG_(printf)("}\n");
-}
-
-static
-void do_actions_on_error(Error* err, Bool allow_db_attach)
-{
- Bool still_noisy = True;
-
- /* Perhaps we want a debugger attach at this point? */
- if (allow_db_attach &&
- VG_(is_action_requested)( "Attach to debugger", & VG_(clo_db_attach) ))
- {
- if (0) VG_(printf)("starting debugger\n");
- VG_(start_debugger)( err->tid );
- }
- /* Or maybe we want to generate the error's suppression? */
- if (VG_(clo_gen_suppressions) == 2
- || (VG_(clo_gen_suppressions) == 1
- && VG_(is_action_requested)( "Print suppression", &still_noisy ))
- ) {
- gen_suppression(err);
- }
- if (VG_(clo_gen_suppressions) == 1 && !still_noisy)
- VG_(clo_gen_suppressions) = 0;
-}
/* Shared between VG_(maybe_record_error)() and VG_(unique_error)(),
just for pretty printing purposes. */
@@ -498,25 +588,29 @@
|| n_errs_found >= M_COLLECT_NO_ERRORS_AFTER_FOUND)
&& !VG_(clo_xml)) {
if (!stopping_message) {
- VG_UMSG("");
+ VG_(umsg)("\n");
if (n_errs_shown >= M_COLLECT_NO_ERRORS_AFTER_SHOWN) {
- VG_UMSG(
+ VG_(umsg)(
"More than %d different errors detected. "
- "I'm not reporting any more.",
+ "I'm not reporting any more.\n",
M_COLLECT_NO_ERRORS_AFTER_SHOWN );
} else {
- VG_UMSG(
+ VG_(umsg)(
"More than %d total errors detected. "
- "I'm not reporting any more.",
+ "I'm not reporting any more.\n",
M_COLLECT_NO_ERRORS_AFTER_FOUND );
}
- VG_UMSG("Final error counts will be inaccurate. Go fix your program!");
- VG_UMSG("Rerun with --error-limit=no to disable this cutoff. Note");
- VG_UMSG("that errors may occur in your program without prior warning from");
- VG_UMSG("Valgrind, because errors are no longer being displayed.");
- VG_UMSG("");
+ VG_(umsg)("Final error counts will be inaccurate. "
+ "Go fix your program!\n");
+ VG_(umsg)("Rerun with --error-limit=no to disable "
+ "this cutoff. Note\n");
+ VG_(umsg)("that errors may occur in your program without "
+ "prior warning from\n");
+ VG_(umsg)("Valgrind, because errors are no longer "
+ "being displayed.\n");
+ VG_(umsg)("\n");
stopping_message = True;
}
return;
@@ -529,10 +623,11 @@
&& !VG_(clo_xml)) {
exe_res = Vg_LowRes;
if (!slowdown_message) {
- VG_UMSG("");
- VG_UMSG("More than %d errors detected. Subsequent errors",
- M_COLLECT_ERRORS_SLOWLY_AFTER);
- VG_UMSG("will still be recorded, but in less detail than before.");
+ VG_(umsg)("\n");
+ VG_(umsg)("More than %d errors detected. Subsequent errors\n",
+ M_COLLECT_ERRORS_SLOWLY_AFTER);
+ VG_(umsg)("will still be recorded, but in less "
+ "detail than before.\n");
slowdown_message = True;
}
}
@@ -618,12 +713,19 @@
errors = p;
if (p->supp == NULL) {
n_errs_found++;
- if (!is_first_shown_context)
- VG_UMSG("");
- pp_Error(p);
+ /* A bit of prettyprinting, to ensure there's a blank line
+ in between each error. */
+ if (!is_first_shown_context) {
+ if (VG_(clo_xml))
+ VG_(printf_xml)("\n");
+ else
+ VG_(umsg)("\n");
+ }
+ /* Actually show the error; more complex than you might think. */
+ pp_Error( p, /*allow_db_attach*/True );
+ /* update stats */
is_first_shown_context = False;
n_errs_shown++;
- do_actions_on_error(p, /*allow_db_attach*/True);
} else {
n_errs_suppressed++;
p->supp->count++;
@@ -662,12 +764,19 @@
n_errs_found++;
if (print_error) {
- if (!is_first_shown_context)
- VG_UMSG("");
- pp_Error(&err);
+ /* A bit of prettyprinting, to ensure there's a blank line
+ in between each error. */
+ if (!is_first_shown_context) {
+ if (VG_(clo_xml))
+ VG_(printf_xml)("\n");
+ else
+ VG_(umsg)("\n");
+ }
+ /* Actually show the error; more complex than you might think. */
+ pp_Error(&err, allow_db_attach);
+ /* update stats */
is_first_shown_context = False;
n_errs_shown++;
- do_actions_on_error(&err, allow_db_attach);
}
return False;
@@ -691,7 +800,7 @@
Bool any_supp;
if (VG_(clo_xml))
- VG_UMSG("<suppcounts>");
+ VG_(printf_xml)("<suppcounts>\n");
any_supp = False;
for (su = suppressions; su != NULL; su = su->next) {
@@ -699,19 +808,18 @@
continue;
any_supp = True;
if (VG_(clo_xml)) {
- VG_(message_no_f_c)(Vg_DebugMsg,
- " <pair>\n"
- " <count>%d</count>\n"
- " <name>%t</name>\n"
- " </pair>",
- su->count, su->sname);
+ VG_(printf_xml_no_f_c)( " <pair>\n"
+ " <count>%d</count>\n"
+ " <name>%t</name>\n"
+ " </pair>\n",
+ su->count, su->sname );
} else {
- VG_DMSG("supp: %6d %s", su->count, su->sname);
+ VG_(dmsg)("supp: %6d %s\n", su->count, su->sname);
}
}
if (VG_(clo_xml))
- VG_UMSG("</suppcounts>");
+ VG_(printf_xml)("</suppcounts>\n");
return any_supp;
}
@@ -750,10 +858,10 @@
}
/* We only get here if not printing XML. */
- VG_UMSG("ERROR SUMMARY: "
- "%d errors from %d contexts (suppressed: %d from %d)",
- n_errs_found, n_err_contexts,
- n_errs_suppressed, n_supp_contexts );
+ VG_(umsg)("ERROR SUMMARY: "
+ "%d errors from %d contexts (suppressed: %d from %d)\n",
+ n_errs_found, n_err_contexts,
+ n_errs_suppressed, n_supp_contexts );
if (VG_(clo_verbosity) <= 1)
return;
@@ -771,10 +879,13 @@
}
if (p_min == NULL) VG_(tool_panic)("show_all_errors()");
- VG_UMSG("");
- VG_UMSG("%d errors in context %d of %d:",
- p_min->count, i+1, n_err_contexts);
- pp_Error( p_min );
+ VG_(umsg)("\n");
+ VG_(umsg)("%d errors in context %d of %d:\n",
+ p_min->count, i+1, n_err_contexts);
+ pp_Error( p_min, False/*allow_db_attach*/ );
+
+ // We're not printing XML -- we'd have exited above if so.
+ vg_assert(! VG_(clo_xml));
if ((i+1 == VG_(clo_dump_error))) {
StackTrace ips = VG_(get_ExeContext_StackTrace)(p_min->where);
@@ -788,17 +899,17 @@
}
if (n_supp_contexts > 0)
- VG_UMSG( "");
+ VG_(umsg)("\n");
any_supp = show_used_suppressions();
if (n_err_contexts > 0) {
if (any_supp)
- VG_UMSG("");
- VG_UMSG("IN SUMMARY: "
- "%d errors from %d contexts (suppressed: %d from %d)",
- n_errs_found, n_err_contexts, n_errs_suppressed,
- n_supp_contexts );
- VG_UMSG("");
+ VG_(umsg)("\n");
+ VG_(umsg)("IN SUMMARY: "
+ "%d errors from %d contexts (suppressed: %d from %d)\n",
+ n_errs_found, n_err_contexts, n_errs_suppressed,
+ n_supp_contexts );
+ VG_(umsg)("\n");
}
}
@@ -807,18 +918,18 @@
void VG_(show_error_counts_as_XML) ( void )
{
Error* err;
- VG_UMSG("<errorcounts>");
+ VG_(printf_xml)("<errorcounts>\n");
for (err = errors; err != NULL; err = err->next) {
if (err->supp != NULL)
continue;
if (err->count <= 0)
continue;
- VG_UMSG(" <pair>");
- VG_UMSG(" <count>%d</count>", err->count);
- VG_UMSG(" <unique>0x%x</unique>", err->unique);
- VG_UMSG(" </pair>");
+ VG_(printf_xml)(" <pair>\n");
+ VG_(printf_xml)(" <count>%d</count>\n", err->count);
+ VG_(printf_xml)(" <unique>0x%x</unique>\n", err->unique);
+ VG_(printf_xml)(" </pair>\n");
}
- VG_UMSG("</errorcounts>");
+ VG_(printf_xml)("</errorcounts>\n");
}
@@ -955,8 +1066,8 @@
// Check it's not a directory.
if (VG_(is_dir)( filename )) {
if (VG_(clo_xml))
- VG_UMSG("</valgrindoutput>\n");
- VG_UMSG("FATAL: suppressions file \"%s\" is a directory", filename );
+ VG_(umsg)("</valgrindoutput>\n");
+ VG_(umsg)("FATAL: suppressions file \"%s\" is a directory\n", filename );
VG_(exit)(1);
}
@@ -964,8 +1075,8 @@
sres = VG_(open)( filename, VKI_O_RDONLY, 0 );
if (sr_isError(sres)) {
if (VG_(clo_xml))
- VG_UMSG("</valgrindoutput>\n");
- VG_UMSG("FATAL: can't open suppressions file \"%s\"", filename );
+ VG_(umsg)("</valgrindoutput>\n");
+ VG_(umsg)("FATAL: can't open suppressions file \"%s\"\n", filename );
VG_(exit)(1);
}
fd = sr_Res(sres);
@@ -1121,13 +1232,13 @@
syntax_error:
if (VG_(clo_xml))
- VG_UMSG("</valgrindoutput>\n");
- VG_UMSG("FATAL: in suppressions file \"%s\" near line %d:",
+ VG_(umsg)("</valgrindoutput>\n");
+ VG_(umsg)("FATAL: in suppressions file \"%s\" near line %d:\n",
filename, lineno );
- VG_UMSG(" %s", err_str );
+ VG_(umsg)(" %s\n", err_str );
VG_(close)(fd);
- VG_UMSG("exiting now.");
+ VG_(umsg)("exiting now.\n");
VG_(exit)(1);
# undef BOMB
@@ -1141,7 +1252,8 @@
suppressions = NULL;
for (i = 0; i < VG_(clo_n_suppressions); i++) {
if (VG_(clo_verbosity) > 1) {
- VG_DMSG("Reading suppressions file: %s", VG_(clo_suppressions)[i] );
+ VG_(dmsg)("Reading suppressions file: %s\n",
+ VG_(clo_suppressions)[i] );
}
load_one_suppressions_file( VG_(clo_suppressions)[i] );
}
@@ -1299,12 +1411,12 @@
*/
void VG_(print_errormgr_stats) ( void )
{
- VG_DMSG(
- " errormgr: %'lu supplist searches, %'lu comparisons during search",
+ VG_(dmsg)(
+ " errormgr: %'lu supplist searches, %'lu comparisons during search\n",
em_supplist_searches, em_supplist_cmps
);
- VG_DMSG(
- " errormgr: %'lu errlist searches, %'lu comparisons during search",
+ VG_(dmsg)(
+ " errormgr: %'lu errlist searches, %'lu comparisons during search\n",
em_errlist_searches, em_errlist_cmps
);
}
diff --git a/coregrind/m_execontext.c b/coregrind/m_execontext.c
index 645f1c4..7f00e4b 100644
--- a/coregrind/m_execontext.c
+++ b/coregrind/m_execontext.c
@@ -149,18 +149,18 @@
{
init_ExeContext_storage();
VG_(message)(Vg_DebugMsg,
- " exectx: %'lu lists, %'llu contexts (avg %'llu per list)",
+ " exectx: %'lu lists, %'llu contexts (avg %'llu per list)\n",
ec_htab_size, ec_totstored, ec_totstored / (ULong)ec_htab_size
);
VG_(message)(Vg_DebugMsg,
- " exectx: %'llu searches, %'llu full compares (%'llu per 1000)",
+ " exectx: %'llu searches, %'llu full compares (%'llu per 1000)\n",
ec_searchreqs, ec_searchcmps,
ec_searchreqs == 0
? 0ULL
: ( (ec_searchcmps * 1000ULL) / ec_searchreqs )
);
VG_(message)(Vg_DebugMsg,
- " exectx: %'llu cmp2, %'llu cmp4, %'llu cmpAll",
+ " exectx: %'llu cmp2, %'llu cmp4, %'llu cmpAll\n",
ec_cmp2s, ec_cmp4s, ec_cmpAlls
);
}
diff --git a/coregrind/m_libcassert.c b/coregrind/m_libcassert.c
index 8e3eba2..bfab45c 100644
--- a/coregrind/m_libcassert.c
+++ b/coregrind/m_libcassert.c
@@ -146,8 +146,8 @@
}
stacktop = tst->os_state.valgrind_stack_init_SP;
-
- n_ips =
+
+ n_ips =
VG_(get_StackTrace_wrk)(
0/*tid is unknown*/,
ips, BACKTRACE_DEPTH,
@@ -155,6 +155,7 @@
NULL/*array to dump FP values in*/,
ip, sp, fp, lr, sp, stacktop
);
+ VG_(clo_xml) = False;
VG_(pp_StackTrace) (ips, n_ips);
VG_(show_sched_status)();
@@ -200,7 +201,7 @@
}
if (VG_(clo_xml))
- VG_UMSG("</valgrindoutput>\n");
+ VG_(printf_xml)("</valgrindoutput>\n");
// Treat vg_assert2(0, "foo") specially, as a panicky abort
if (VG_STREQ(expr, "0")) {
@@ -221,7 +222,7 @@
Addr ip, Addr sp, Addr fp, Addr lr )
{
if (VG_(clo_xml))
- VG_UMSG("</valgrindoutput>\n");
+ VG_(printf_xml)("</valgrindoutput>\n");
VG_(printf)("\n%s: the 'impossible' happened:\n %s\n", name, str);
report_and_quit(report, ip, sp, fp, lr);
}
@@ -245,18 +246,20 @@
void VG_(unimplemented) ( Char* msg )
{
if (VG_(clo_xml))
- VG_UMSG("</valgrindoutput>\n");
- VG_UMSG("");
- VG_UMSG("Valgrind detected that your program requires");
- VG_UMSG("the following unimplemented functionality:");
- VG_UMSG(" %s", msg);
- VG_UMSG("This may be because the functionality is hard to implement,");
- VG_UMSG("or because no reasonable program would behave this way,");
- VG_UMSG("or because nobody has yet needed it. In any case, let us know at");
- VG_UMSG("%s and/or try to work around the problem, if you can.", VG_BUGS_TO);
- VG_UMSG("");
- VG_UMSG("Valgrind has to exit now. Sorry. Bye!");
- VG_UMSG("");
+ VG_(printf_xml)("</valgrindoutput>\n");
+ VG_(umsg)("\n");
+ VG_(umsg)("Valgrind detected that your program requires\n");
+ VG_(umsg)("the following unimplemented functionality:\n");
+ VG_(umsg)(" %s\n", msg);
+ VG_(umsg)("This may be because the functionality is hard to implement,\n");
+ VG_(umsg)("or because no reasonable program would behave this way,\n");
+ VG_(umsg)("or because nobody has yet needed it. "
+ "In any case, let us know at\n");
+ VG_(umsg)("%s and/or try to work around the problem, if you can.\n",
+ VG_BUGS_TO);
+ VG_(umsg)("\n");
+ VG_(umsg)("Valgrind has to exit now. Sorry. Bye!\n");
+ VG_(umsg)("\n");
VG_(show_sched_status)();
VG_(exit)(1);
}
diff --git a/coregrind/m_libcprint.c b/coregrind/m_libcprint.c
index 8783f9c..91f07a9 100644
--- a/coregrind/m_libcprint.c
+++ b/coregrind/m_libcprint.c
@@ -40,130 +40,158 @@
#include "valgrind.h" // For RUNNING_ON_VALGRIND
-
/* ---------------------------------------------------------------------
Writing to file or a socket
------------------------------------------------------------------ */
-/* Tell the logging mechanism whether we are logging to a file
- descriptor or a socket descriptor. */
-Bool VG_(logging_to_socket) = False;
-
+/* The destination sinks for normal and XML output. These have their
+ initial values here; they are set to final values by
+ m_main.main_process_cmd_line_options(). See comment at the top of
+ that function for the associated logic. */
+OutputSink VG_(log_output_sink) = { 2, False }; /* 2 = stderr */
+OutputSink VG_(xml_output_sink) = { -1, False }; /* disabled */
+
/* Do the low-level send of a message to the logging sink. */
-static void send_bytes_to_logging_sink ( Char* msg, Int nbytes )
+static
+void send_bytes_to_logging_sink ( OutputSink* sink, Char* msg, Int nbytes )
{
- if (!VG_(logging_to_socket)) {
- /* VG_(clo_log_fd) could have been set to -1 in the various
+ if (sink->is_socket) {
+ Int rc = VG_(write_socket)( sink->fd, msg, nbytes );
+ if (rc == -1) {
+ // For example, the listener process died. Switch back to stderr.
+ sink->is_socket = False;
+ sink->fd = 2;
+ VG_(write)( sink->fd, msg, nbytes );
+ }
+ } else {
+ /* sink->fd could have been set to -1 in the various
sys-wrappers for sys_fork, if --child-silent-after-fork=yes
is in effect. That is a signal that we should not produce
any more output. */
- if (VG_(clo_log_fd) >= 0)
- VG_(write)( VG_(clo_log_fd), msg, nbytes );
- } else {
- Int rc = VG_(write_socket)( VG_(clo_log_fd), msg, nbytes );
- if (rc == -1) {
- // For example, the listener process died. Switch back to stderr.
- VG_(logging_to_socket) = False;
- VG_(clo_log_fd) = 2;
- VG_(write)( VG_(clo_log_fd), msg, nbytes );
- }
+ if (sink->fd >= 0)
+ VG_(write)( sink->fd, msg, nbytes );
}
}
+
/* ---------------------------------------------------------------------
printf() and friends
------------------------------------------------------------------ */
+/* --------- printf --------- */
+
typedef
struct {
- HChar buf[128];
- Int n;
+ HChar buf[512];
+ Int buf_used;
+ OutputSink* sink;
}
- printf_buf;
-
-static UInt vprintf_to_buf ( printf_buf *prbuf,
- const HChar *format, va_list vargs );
-static UInt printf_to_buf ( printf_buf* prbuf, const HChar *format, ... );
+ printf_buf_t;
// Adds a single char to the buffer. When the buffer gets sufficiently
// full, we write its contents to the logging sink.
-static void add_to_myprintf_buf ( HChar c, void *p )
+static void add_to__printf_buf ( HChar c, void *p )
{
- printf_buf *myprintf_buf = (printf_buf *)p;
+ printf_buf_t *b = (printf_buf_t *)p;
- if (myprintf_buf->n > sizeof(myprintf_buf->buf) - 2 ) {
- send_bytes_to_logging_sink( myprintf_buf->buf, myprintf_buf->n );
- myprintf_buf->n = 0;
+ if (b->buf_used > sizeof(b->buf) - 2 ) {
+ send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used );
+ b->buf_used = 0;
}
- myprintf_buf->buf[myprintf_buf->n++] = c;
- myprintf_buf->buf[myprintf_buf->n] = 0;
- tl_assert(myprintf_buf->n < sizeof(myprintf_buf->buf));
+ b->buf[b->buf_used++] = c;
+ b->buf[b->buf_used] = 0;
+ tl_assert(b->buf_used < sizeof(b->buf));
+}
+
+static UInt vprintf_to_buf ( printf_buf_t* b,
+ const HChar *format, va_list vargs )
+{
+ UInt ret = 0;
+ if (b->sink->fd >= 0) {
+ ret = VG_(debugLog_vprintf)
+ ( add_to__printf_buf, b, format, vargs );
+ }
+ return ret;
+}
+
+static UInt vprintf_WRK ( OutputSink* sink,
+ const HChar *format, va_list vargs )
+{
+ printf_buf_t myprintf_buf
+ = { "", 0, sink };
+ UInt ret
+ = vprintf_to_buf(&myprintf_buf, format, vargs);
+ // Write out any chars left in the buffer.
+ if (myprintf_buf.buf_used > 0) {
+ send_bytes_to_logging_sink( myprintf_buf.sink,
+ myprintf_buf.buf,
+ myprintf_buf.buf_used );
+ }
+ return ret;
}
UInt VG_(vprintf) ( const HChar *format, va_list vargs )
{
- UInt ret = 0;
- printf_buf myprintf_buf = {"",0};
-
- ret = vprintf_to_buf(&myprintf_buf, format, vargs);
- // Write out any chars left in the buffer.
- if (myprintf_buf.n > 0) {
- send_bytes_to_logging_sink( myprintf_buf.buf, myprintf_buf.n );
- }
- return ret;
-}
-
-static UInt vprintf_to_buf ( printf_buf *prbuf,
- const HChar *format, va_list vargs )
-{
- UInt ret = 0;
-
- if (VG_(clo_log_fd) >= 0) {
- ret = VG_(debugLog_vprintf)
- ( add_to_myprintf_buf, prbuf, format, vargs );
- }
- return ret;
+ return vprintf_WRK( &VG_(log_output_sink), format, vargs );
}
UInt VG_(printf) ( const HChar *format, ... )
{
UInt ret;
va_list vargs;
-
va_start(vargs, format);
ret = VG_(vprintf)(format, vargs);
va_end(vargs);
-
return ret;
}
-static UInt printf_to_buf ( printf_buf* prbuf, const HChar *format, ... )
+UInt VG_(vprintf_xml) ( const HChar *format, va_list vargs )
+{
+ return vprintf_WRK( &VG_(xml_output_sink), format, vargs );
+}
+
+UInt VG_(printf_xml) ( const HChar *format, ... )
{
UInt ret;
va_list vargs;
-
va_start(vargs, format);
- ret = vprintf_to_buf(prbuf, format, vargs);
+ ret = VG_(vprintf_xml)(format, vargs);
va_end(vargs);
-
return ret;
}
-/* A general replacement for sprintf(). */
-static void add_to_vg_sprintf_buf ( HChar c, void *p )
+/* An exact clone of VG_(printf_xml), unfortunately. */
+UInt VG_(printf_xml_no_f_c) ( const HChar *format, ... )
{
- char **vg_sprintf_ptr = p;
- *(*vg_sprintf_ptr)++ = c;
+ UInt ret;
+ va_list vargs;
+ va_start(vargs, format);
+ ret = VG_(vprintf_xml)(format, vargs);
+ va_end(vargs);
+ return ret;
+}
+
+
+/* --------- sprintf --------- */
+
+/* If we had an explicit buf structure here, it would contain only one
+ field, indicating where the next char is to go. So use p directly
+ for that, rather than having it be a pointer to a structure. */
+
+static void add_to__sprintf_buf ( HChar c, void *p )
+{
+ HChar** b = p;
+ *(*b)++ = c;
}
UInt VG_(vsprintf) ( Char* buf, const HChar *format, va_list vargs )
{
Int ret;
- Char *vg_sprintf_ptr = buf;
+ HChar* sprintf_ptr = buf;
ret = VG_(debugLog_vprintf)
- ( add_to_vg_sprintf_buf, &vg_sprintf_ptr, format, vargs );
- add_to_vg_sprintf_buf('\0', &vg_sprintf_ptr);
+ ( add_to__sprintf_buf, &sprintf_ptr, format, vargs );
+ add_to__sprintf_buf('\0', &sprintf_ptr);
vg_assert(VG_(strlen)(buf) == ret);
@@ -174,27 +202,26 @@
{
UInt ret;
va_list vargs;
-
va_start(vargs,format);
ret = VG_(vsprintf)(buf, format, vargs);
va_end(vargs);
-
return ret;
}
-/* A replacement for snprintf. */
+/* --------- snprintf --------- */
+
typedef
struct {
HChar* buf;
Int buf_size;
Int buf_used;
}
- snprintf_buf;
+ snprintf_buf_t;
-static void add_to_vg_snprintf_buf ( HChar c, void* p )
+static void add_to__snprintf_buf ( HChar c, void* p )
{
- snprintf_buf* b = p;
+ snprintf_buf_t* b = p;
if (b->buf_size > 0 && b->buf_used < b->buf_size) {
b->buf[b->buf_used++] = c;
if (b->buf_used < b->buf_size)
@@ -207,13 +234,13 @@
UInt VG_(vsnprintf) ( Char* buf, Int size, const HChar *format, va_list vargs )
{
Int ret;
- snprintf_buf b;
+ snprintf_buf_t b;
b.buf = buf;
b.buf_size = size < 0 ? 0 : size;
b.buf_used = 0;
ret = VG_(debugLog_vprintf)
- ( add_to_vg_snprintf_buf, &b, format, vargs );
+ ( add_to__snprintf_buf, &b, format, vargs );
return b.buf_used;
}
@@ -222,15 +249,24 @@
{
UInt ret;
va_list vargs;
-
va_start(vargs,format);
ret = VG_(vsnprintf)(buf, size, format, vargs);
va_end(vargs);
-
return ret;
}
+/* --------- vcbprintf --------- */
+
+void VG_(vcbprintf)( void(*char_sink)(HChar, void* opaque),
+ void* opaque,
+ const HChar* format, va_list vargs )
+{
+ (void) VG_(debugLog_vprintf)
+ ( char_sink, opaque, format, vargs );
+}
+
+
/* ---------------------------------------------------------------------
percentify()
------------------------------------------------------------------ */
@@ -321,48 +357,137 @@
message()
------------------------------------------------------------------ */
+/* A buffer for accumulating VG_(message) style output. This is
+ pretty much the same as VG_(printf)'s scheme, with two differences:
+
+ * The message buffer persists between calls, so that multiple
+ calls to VG_(message) can build up output.
+
+ * Whenever the first character on a line is emitted, the
+ ==PID== style preamble is stuffed in before it.
+*/
+typedef
+ struct {
+ HChar buf[512+128];
+ Int buf_used;
+ Bool atLeft; /* notionally, is the next char position at the
+ leftmost column? */
+ /* Current message kind - changes from call to call */
+ VgMsgKind kind;
+ /* PID; acquired just once and stays constant */
+ Int my_pid;
+ /* destination */
+ OutputSink* sink;
+ }
+ vmessage_buf_t;
+
+static vmessage_buf_t vmessage_buf
+ = { "", 0, True, Vg_UserMsg, -1, &VG_(log_output_sink) };
+
+
+// Adds a single char to the buffer. We aim to have at least 128
+// bytes free in the buffer, so that it's always possible to emit
+// the preamble into the buffer if c happens to be the character
+// following a \n. When the buffer gets too full, we write its
+// contents to the logging sink.
+static void add_to__vmessage_buf ( HChar c, void *p )
+{
+ HChar tmp[64];
+ vmessage_buf_t* b = (vmessage_buf_t*)p;
+
+ vg_assert(b->buf_used >= 0 && b->buf_used < sizeof(b->buf)-128);
+
+ if (UNLIKELY(b->atLeft)) {
+ // insert preamble
+ HChar ch;
+ Int i, depth;
+
+ switch (b->kind) {
+ case Vg_UserMsg: ch = '='; break;
+ case Vg_DebugMsg: ch = '-'; break;
+ case Vg_DebugExtraMsg: ch = '+'; break;
+ case Vg_ClientMsg: ch = '*'; break;
+ default: ch = '?'; break;
+ }
+
+ // Print one '>' in front of the messages for each level of
+ // self-hosting being performed.
+ depth = RUNNING_ON_VALGRIND;
+ if (depth > 10)
+ depth = 10; // ?!?!
+ for (i = 0; i < depth; i++) {
+ b->buf[b->buf_used++] = '>';
+ }
+
+ b->buf[b->buf_used++] = ch;
+ b->buf[b->buf_used++] = ch;
+
+ if (VG_(clo_time_stamp)) {
+ VG_(memset)(tmp, 0, sizeof(tmp));
+ VG_(elapsed_wallclock_time)(tmp);
+ tmp[sizeof(tmp)-1] = 0;
+ for (i = 0; tmp[i]; i++)
+ b->buf[b->buf_used++] = tmp[i];
+ }
+
+ VG_(sprintf)(tmp, "%d", b->my_pid);
+ tmp[sizeof(tmp)-1] = 0;
+ for (i = 0; tmp[i]; i++)
+ b->buf[b->buf_used++] = tmp[i];
+
+ b->buf[b->buf_used++] = ch;
+ b->buf[b->buf_used++] = ch;
+ b->buf[b->buf_used++] = ' ';
+
+ /* We can't possibly have stuffed 96 chars in merely as a result
+ of making the preamble (can we?) */
+ vg_assert(b->buf_used < sizeof(b->buf)-32);
+ }
+
+ b->buf[b->buf_used++] = c;
+ b->buf[b->buf_used] = 0;
+
+ if (b->buf_used >= sizeof(b->buf) - 128) {
+ send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used );
+ b->buf_used = 0;
+ }
+
+ b->atLeft = c == '\n';
+}
+
+
UInt VG_(vmessage) ( VgMsgKind kind, const HChar* format, va_list vargs )
{
- UInt count = 0;
- Char c;
- Int i, depth;
- printf_buf myprintf_buf = {"",0};
+ UInt ret;
- switch (kind) {
- case Vg_UserMsg: c = '='; break;
- case Vg_DebugMsg: c = '-'; break;
- case Vg_DebugExtraMsg: c = '+'; break;
- case Vg_ClientMsg: c = '*'; break;
- default: c = '?'; break;
+ /* Note (carefully) that the buf persists from call to call, unlike
+ with the other printf variants in earlier parts of this file. */
+ vmessage_buf_t* b = &vmessage_buf; /* shorthand for convenience */
+
+ /* We have to set this each call, so that the correct flavour
+ of preamble is emitted at each \n. */
+ b->kind = kind;
+
+ /* Cache the results of getpid just once, so we don't have to call
+ getpid once for each line of text output. */
+ if (UNLIKELY(b->my_pid == -1)) {
+ b->my_pid = VG_(getpid)();
+ vg_assert(b->my_pid >= 0);
}
- // Print one '>' in front of the messages for each level of self-hosting
- // being performed.
- depth = RUNNING_ON_VALGRIND;
- for (i = 0; i < depth; i++) {
- count += printf_to_buf (&myprintf_buf, ">");
- }
-
- if (!VG_(clo_xml))
- count += printf_to_buf (&myprintf_buf, "%c%c", c,c);
+ ret = VG_(debugLog_vprintf) ( add_to__vmessage_buf,
+ b, format, vargs );
- if (VG_(clo_time_stamp)) {
- HChar buf[50];
- VG_(elapsed_wallclock_time)(buf);
- count += printf_to_buf(&myprintf_buf, "%s ", buf);
+ /* If the message finished exactly with a \n, then flush it at this
+ point. If not, assume more bits of the same line will turn up
+ in later messages, so don't bother to flush it right now. */
+
+ if (b->atLeft && b->buf_used > 0) {
+ send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used );
+ b->buf_used = 0;
}
- if (!VG_(clo_xml))
- count += printf_to_buf (&myprintf_buf, "%d%c%c ", VG_(getpid)(), c,c);
-
- count += vprintf_to_buf (&myprintf_buf, format, vargs);
- count += printf_to_buf (&myprintf_buf, "\n");
-
- if (myprintf_buf.n > 0) {
- send_bytes_to_logging_sink( myprintf_buf.buf, myprintf_buf.n );
- }
-
- return count;
+ return ret;
}
/* Send a simple single-part XML message. */
@@ -387,6 +512,47 @@
return count;
}
+/* VG_(message) variants with hardwired first argument. */
+UInt VG_(umsg) ( const HChar* format, ... )
+{
+ UInt count;
+ va_list vargs;
+ va_start(vargs,format);
+ count = VG_(vmessage) ( Vg_UserMsg, format, vargs );
+ va_end(vargs);
+ return count;
+}
+
+UInt VG_(dmsg) ( const HChar* format, ... )
+{
+ UInt count;
+ va_list vargs;
+ va_start(vargs,format);
+ count = VG_(vmessage) ( Vg_DebugMsg, format, vargs );
+ va_end(vargs);
+ return count;
+}
+
+UInt VG_(emsg) ( const HChar* format, ... )
+{
+ UInt count;
+ va_list vargs;
+ va_start(vargs,format);
+ count = VG_(vmessage) ( Vg_DebugExtraMsg, format, vargs );
+ va_end(vargs);
+ return count;
+}
+
+/* Flush any output that has accumulated in vmessage_buf as a
+ result of previous calls to VG_(message) et al. */
+void VG_(message_flush) ( void )
+{
+ vmessage_buf_t* b = &vmessage_buf;
+ send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used );
+ b->buf_used = 0;
+}
+
+
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
diff --git a/coregrind/m_libcproc.c b/coregrind/m_libcproc.c
index 1c02ba4..46bdfe6 100644
--- a/coregrind/m_libcproc.c
+++ b/coregrind/m_libcproc.c
@@ -435,7 +435,8 @@
res = VG_(mk_SysRes_Success)( VG_(strtoll10)(pid, &s) );
if (*s != '\0') {
VG_(message)(Vg_DebugMsg,
- "Warning: invalid file name linked to by /proc/self: %s", pid);
+ "Warning: invalid file name linked to by /proc/self: %s\n",
+ pid);
}
}
}
diff --git a/coregrind/m_main.c b/coregrind/m_main.c
index f41f201..2ba71a8 100644
--- a/coregrind/m_main.c
+++ b/coregrind/m_main.c
@@ -87,13 +87,13 @@
// Memory stats
if (VG_(clo_verbosity) > 2) {
- VG_(message)(Vg_DebugMsg, "");
+ VG_(message)(Vg_DebugMsg, "\n");
VG_(message)(Vg_DebugMsg,
- "------ Valgrind's internal memory use stats follow ------" );
+ "------ Valgrind's internal memory use stats follow ------\n" );
VG_(sanity_check_malloc_all)();
- VG_(message)(Vg_DebugMsg, "------" );
+ VG_(message)(Vg_DebugMsg, "------\n" );
VG_(print_all_arena_stats)();
- VG_(message)(Vg_DebugMsg, "");
+ VG_(message)(Vg_DebugMsg, "\n");
}
}
@@ -140,8 +140,11 @@
" tools that make use of it (Memcheck, Helgrind)\n"
"\n"
" user options for Valgrind tools that report errors:\n"
-" --xml=yes all output is in XML (some tools only)\n"
-" --xml-user-comment=STR copy STR verbatim to XML output\n"
+" --xml=yes emit error output in XML (some tools only)\n"
+" --xml-fd=<number> XML output to file descriptor\n"
+" --xml-file=<file> XML output to <file>\n"
+" --xml-socket=ipaddr:port XML output to socket ipaddr:port\n"
+" --xml-user-comment=STR copy STR verbatim into XML output\n"
" --demangle=no|yes automatically demangle C++ names? [yes]\n"
" --num-callers=<number> show <number> callers in stack traces [12]\n"
" --error-limit=no|yes stop showing new errors if too many? [yes]\n"
@@ -217,8 +220,8 @@
Char* gdb_path = GDB_PATH;
// Ensure the message goes to stdout
- VG_(clo_log_fd) = 1;
- vg_assert( !VG_(logging_to_socket) );
+ VG_(log_output_sink).fd = 1;
+ VG_(log_output_sink).is_socket = False;
/* 'usage1' expects one char* argument */
VG_(printf)(usage1, gdb_path);
@@ -276,7 +279,8 @@
vg_assert(str);
// Nb: the version string goes to stdout.
- if VG_XACT_CLO(str, "--version", VG_(clo_log_fd), 1) {
+ if VG_XACT_CLO(str, "--version", VG_(log_output_sink).fd, 1) {
+ VG_(log_output_sink).is_socket = False;
VG_(printf)("valgrind-" VERSION "\n");
VG_(exit)(0);
}
@@ -298,26 +302,59 @@
}
/* The main processing for command line options. See comments above
- on early_process_cmd_line_options.
+ on early_process_cmd_line_options.
+
+ Comments on how the logging options are handled:
+
+ User can specify:
+ --log-fd= for a fd to write to (default setting, fd = 2)
+ --log-file= for a file name to write to
+ --log-socket= for a socket to write to
+
+ As a result of examining these and doing relevant socket/file
+ opening, a final fd is established. This is stored in
+ VG_(log_output_sink) in m_libcprint. Also, if --log-file=STR was
+ specified, then STR, after expansion of %p and %q templates within
+ it, is stored in VG_(clo_log_fname_expanded), in m_options, just in
+ case anybody wants to know what it is.
+
+ When printing, VG_(log_output_sink) is consulted to find the
+ fd to send output to.
+
+ Exactly analogous actions are undertaken for the XML output
+ channel, with the one difference that the default fd is -1, meaning
+ the channel is disabled by default.
*/
-static Bool main_process_cmd_line_options( const HChar* toolname )
+static
+void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
+ /*OUT*/Char** xml_fname_unexpanded,
+ const HChar* toolname )
{
// VG_(clo_log_fd) is used by all the messaging. It starts as 2 (stderr)
// and we cannot change it until we know what we are changing it to is
// ok. So we have tmp_log_fd to hold the tmp fd prior to that point.
SysRes sres;
- Int i, tmp_log_fd;
+ Int i, tmp_log_fd, tmp_xml_fd;
Int toolname_len = VG_(strlen)(toolname);
Char* tmp_str; // Used in a couple of places.
enum {
VgLogTo_Fd,
VgLogTo_File,
VgLogTo_Socket
- } log_to = VgLogTo_Fd; // Where is logging output to be sent?
+ } log_to = VgLogTo_Fd, // Where is logging output to be sent?
+ xml_to = VgLogTo_Fd; // Where is XML output to be sent?
- /* log to stderr by default, but usage message goes to stdout */
+ /* Temporarily holds the string STR specified with
+ --{log,xml}-{name,socket}=STR. 'fs' stands for
+ file-or-socket. */
+ Char* log_fsname_unexpanded = NULL;
+ Char* xml_fsname_unexpanded = NULL;
+
+ /* Log to stderr by default, but usage message goes to stdout. XML
+ output is initially disabled. */
tmp_log_fd = 2;
-
+ tmp_xml_fd = -1;
+
/* Check for sane path in ./configure --prefix=... */
if (VG_LIBDIR[0] != '/')
VG_(err_config_error)("Please use absolute paths in "
@@ -325,6 +362,8 @@
vg_assert( VG_(args_for_valgrind) );
+ /* BEGIN command-line processing loop */
+
for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
@@ -454,25 +493,35 @@
else if VG_INT_CLO(arg, "--log-fd", tmp_log_fd) {
log_to = VgLogTo_Fd;
- VG_(clo_log_name) = NULL;
+ log_fsname_unexpanded = NULL;
+ }
+ else if VG_INT_CLO(arg, "--xml-fd", tmp_xml_fd) {
+ xml_to = VgLogTo_Fd;
+ xml_fsname_unexpanded = NULL;
}
- else if VG_STR_CLO(arg, "--log-file", VG_(clo_log_name)) {
+ else if VG_STR_CLO(arg, "--log-file", log_fsname_unexpanded) {
log_to = VgLogTo_File;
}
-
- else if VG_STR_CLO(arg, "--log-socket", VG_(clo_log_name)) {
+ else if VG_STR_CLO(arg, "--xml-file", xml_fsname_unexpanded) {
+ xml_to = VgLogTo_File;
+ }
+
+ else if VG_STR_CLO(arg, "--log-socket", log_fsname_unexpanded) {
log_to = VgLogTo_Socket;
}
+ else if VG_STR_CLO(arg, "--xml-socket", xml_fsname_unexpanded) {
+ xml_to = VgLogTo_Socket;
+ }
else if VG_STR_CLO(arg, "--xml-user-comment",
VG_(clo_xml_user_comment)) {}
else if VG_STR_CLO(arg, "--suppressions", tmp_str) {
if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
- VG_(message)(Vg_UserMsg, "Too many suppression files specified.");
+ VG_(message)(Vg_UserMsg, "Too many suppression files specified.\n");
VG_(message)(Vg_UserMsg,
- "Increase VG_CLO_MAX_SFILES and recompile.");
+ "Increase VG_CLO_MAX_SFILES and recompile.\n");
VG_(err_bad_option)(arg);
}
VG_(clo_suppressions)[VG_(clo_n_suppressions)] = tmp_str;
@@ -485,7 +534,7 @@
if (8 != VG_(strlen)(tmp_str)) {
VG_(message)(Vg_UserMsg,
- "--trace-flags argument must have 8 digits");
+ "--trace-flags argument must have 8 digits\n");
VG_(err_bad_option)(arg);
}
for (j = 0; j < 8; j++) {
@@ -493,7 +542,7 @@
else if ('1' == tmp_str[j]) VG_(clo_trace_flags) |= (1 << (7-j));
else {
VG_(message)(Vg_UserMsg, "--trace-flags argument can only "
- "contain 0s and 1s");
+ "contain 0s and 1s\n");
VG_(err_bad_option)(arg);
}
}
@@ -505,7 +554,7 @@
if (8 != VG_(strlen)(tmp_str)) {
VG_(message)(Vg_UserMsg,
- "--profile-flags argument must have 8 digits");
+ "--profile-flags argument must have 8 digits\n");
VG_(err_bad_option)(arg);
}
for (j = 0; j < 8; j++) {
@@ -513,7 +562,7 @@
else if ('1' == tmp_str[j]) VG_(clo_profile_flags) |= (1 << (7-j));
else {
VG_(message)(Vg_UserMsg, "--profile-flags argument can only "
- "contain 0s and 1s");
+ "contain 0s and 1s\n");
VG_(err_bad_option)(arg);
}
}
@@ -534,6 +583,8 @@
}
}
+ /* END command-line processing loop */
+
/* Make VEX control parameters sane */
if (VG_(clo_vex_control).guest_chase_thresh
@@ -552,34 +603,72 @@
if (VG_(clo_gen_suppressions) > 0 &&
!VG_(needs).core_errors && !VG_(needs).tool_errors) {
VG_(message)(Vg_UserMsg,
- "Can't use --gen-suppressions= with this tool,");
+ "Can't use --gen-suppressions= with this tool,\n");
VG_(message)(Vg_UserMsg,
- "as it doesn't generate errors.");
+ "as it doesn't generate errors.\n");
VG_(err_bad_option)("--gen-suppressions=");
}
+ /* If XML output is requested, check that the tool actually
+ supports it. */
+ if (VG_(clo_xml) && !VG_(needs).xml_output) {
+ VG_(clo_xml) = False;
+ VG_(message)(Vg_UserMsg,
+ "%s does not support XML output.\n", VG_(details).name);
+ VG_(err_bad_option)("--xml=yes");
+ /*NOTREACHED*/
+ }
+
+ vg_assert( VG_(clo_gen_suppressions) >= 0 );
+ vg_assert( VG_(clo_gen_suppressions) <= 2 );
+
/* If we've been asked to emit XML, mash around various other
options so as to constrain the output somewhat, and to remove
- any need for user input during the run. */
+ any need for user input during the run.
+ */
if (VG_(clo_xml)) {
- /* Disable suppression generation (requires user input) */
- VG_(clo_gen_suppressions) = 0;
- /* Disable attaching to GDB (requires user input) */
- VG_(clo_db_attach) = False;
- /* Set a known verbosity level */
- VG_(clo_verbosity) = 1;
+
+ /* We can't allow --gen-suppressions=yes, since that requires us
+ to print the error and then ask the user if she wants a
+ suppression for it, but in XML mode we won't print it until
+ we know whether we also need to print a suppression. Hence a
+ circular dependency. So disallow this.
+ (--gen-suppressions=all is still OK since we don't need any
+ user interaction in this case.) */
+ if (VG_(clo_gen_suppressions) == 1) {
+ VG_(umsg)(
+ "When --xml=yes is specified, only --gen-suppressions=no\n"
+ "or --gen-suppressions=all are allowed, but not "
+ "--gen-suppressions=yes.\n");
+ /* FIXME: this is really a misuse of VG_(err_bad_option). */
+ VG_(err_bad_option)(
+ "--xml=yes together with --gen-suppressions=yes");
+ }
+
+ /* We can't allow DB attaching (or we maybe could, but results
+ could be chaotic ..) since it requires user input. Hence
+ disallow. */
+ if (VG_(clo_db_attach)) {
+ VG_(umsg)("--db-attach=yes is not allowed in XML mode,\n"
+ "as it would require user input.\n");
+ /* FIXME: this is really a misuse of VG_(err_bad_option). */
+ VG_(err_bad_option)(
+ "--xml=yes together with --db-attach=yes");
+ }
+
+ /* Disallow dump_error in XML mode; sounds like a recipe for
+ chaos. No big deal; dump_error is a flag for debugging V
+ itself. */
+ if (VG_(clo_dump_error) > 0) {
+ /* FIXME: this is really a misuse of VG_(err_bad_option). */
+ VG_(err_bad_option)(
+ "--xml=yes together with --dump-error=");
+ }
+
/* Disable error limits (this might be a bad idea!) */
VG_(clo_error_limit) = False;
/* Disable emulation warnings */
- VG_(clo_show_emwarns) = False;
- /* Disable waiting for GDB to debug Valgrind */
- VG_(clo_wait_for_gdb) = False;
- /* No file-descriptor leak checking yet */
- VG_(clo_track_fds) = False;
- /* Disable timestamped output */
- VG_(clo_time_stamp) = False;
- /* Disable heap profiling, since that prints lots of stuff. */
- VG_(clo_profile_heap) = False;
+
/* Also, we want to set options for the leak checker, but that
will have to be done in Memcheck's flag-handling code, not
here. */
@@ -592,116 +681,233 @@
the terminal any problems to do with processing command line
opts.)
- So set up logging now. After this is done, VG_(clo_log_fd)
- should be connected to whatever sink has been selected, and we
- indiscriminately chuck stuff into it without worrying what the
- nature of it is. Oh the wonder of Unix streams. */
+ So set up logging now. After this is done, VG_(log_output_sink)
+ and (if relevant) VG_(xml_output_sink) should be connected to
+ whatever sink has been selected, and we indiscriminately chuck
+ stuff into it without worrying what the nature of it is. Oh the
+ wonder of Unix streams. */
- vg_assert(VG_(clo_log_fd) == 2 /* stderr */);
- vg_assert(VG_(logging_to_socket) == False);
+ vg_assert(VG_(log_output_sink).fd == 2 /* stderr */);
+ vg_assert(VG_(log_output_sink).is_socket == False);
+ vg_assert(VG_(clo_log_fname_expanded) == NULL);
+
+ vg_assert(VG_(xml_output_sink).fd == -1 /* disabled */);
+ vg_assert(VG_(xml_output_sink).is_socket == False);
+ vg_assert(VG_(clo_xml_fname_expanded) == NULL);
+
+ /* --- set up the normal text output channel --- */
switch (log_to) {
case VgLogTo_Fd:
- vg_assert(VG_(clo_log_name) == NULL);
+ vg_assert(log_fsname_unexpanded == NULL);
break;
case VgLogTo_File: {
Char* logfilename;
- vg_assert(VG_(clo_log_name) != NULL);
- vg_assert(VG_(strlen)(VG_(clo_log_name)) <= 900); /* paranoia */
+ vg_assert(log_fsname_unexpanded != NULL);
+ vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */
// Nb: we overwrite an existing file of this name without asking
// any questions.
- logfilename = VG_(expand_file_name)("--log-file", VG_(clo_log_name));
+ logfilename = VG_(expand_file_name)("--log-file",
+ log_fsname_unexpanded);
sres = VG_(open)(logfilename,
VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
VKI_S_IRUSR|VKI_S_IWUSR);
if (!sr_isError(sres)) {
tmp_log_fd = sr_Res(sres);
+ VG_(clo_log_fname_expanded) = logfilename;
} else {
VG_(message)(Vg_UserMsg,
- "Can't create log file '%s' (%s); giving up!",
+ "Can't create log file '%s' (%s); giving up!\n",
logfilename, VG_(strerror)(sr_Err(sres)));
VG_(err_bad_option)(
"--log-file=<file> (didn't work out for some reason.)");
/*NOTREACHED*/
}
- break; /* switch (VG_(clo_log_to)) */
+ break;
}
case VgLogTo_Socket: {
- vg_assert(VG_(clo_log_name) != NULL);
- vg_assert(VG_(strlen)(VG_(clo_log_name)) <= 900); /* paranoia */
- tmp_log_fd = VG_(connect_via_socket)( VG_(clo_log_name) );
+ vg_assert(log_fsname_unexpanded != NULL);
+ vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */
+ tmp_log_fd = VG_(connect_via_socket)( log_fsname_unexpanded );
if (tmp_log_fd == -1) {
VG_(message)(Vg_UserMsg,
- "Invalid --log-socket=ipaddr or --log-socket=ipaddr:port spec");
+ "Invalid --log-socket=ipaddr or "
+ "--log-socket=ipaddr:port spec\n");
VG_(message)(Vg_UserMsg,
- "of '%s'; giving up!", VG_(clo_log_name) );
+ "of '%s'; giving up!\n", log_fsname_unexpanded );
VG_(err_bad_option)(
"--log-socket=");
/*NOTREACHED*/
}
if (tmp_log_fd == -2) {
VG_(message)(Vg_UserMsg,
- "valgrind: failed to connect to logging server '%s'.",
- VG_(clo_log_name) );
+ "valgrind: failed to connect to logging server '%s'.\n",
+ log_fsname_unexpanded );
VG_(message)(Vg_UserMsg,
- "Log messages will sent to stderr instead." );
+ "Log messages will sent to stderr instead.\n" );
VG_(message)(Vg_UserMsg,
- "" );
+ "\n" );
/* We don't change anything here. */
- vg_assert(VG_(clo_log_fd) == 2);
+ vg_assert(VG_(log_output_sink).fd == 2);
tmp_log_fd = 2;
} else {
vg_assert(tmp_log_fd > 0);
- VG_(logging_to_socket) = True;
+ VG_(log_output_sink).is_socket = True;
}
break;
}
}
+ /* --- set up the XML output channel --- */
- /* Check that the requested tool actually supports XML output. */
- if (VG_(clo_xml) && !VG_(needs).xml_output) {
- VG_(clo_xml) = False;
- VG_(message)(Vg_UserMsg,
- "%s does not support XML output.", VG_(details).name);
- VG_(err_bad_option)("--xml=yes");
- /*NOTREACHED*/
+ switch (xml_to) {
+
+ case VgLogTo_Fd:
+ vg_assert(xml_fsname_unexpanded == NULL);
+ break;
+
+ case VgLogTo_File: {
+ Char* xmlfilename;
+
+ vg_assert(xml_fsname_unexpanded != NULL);
+ vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */
+
+ // Nb: we overwrite an existing file of this name without asking
+ // any questions.
+ xmlfilename = VG_(expand_file_name)("--xml-file",
+ xml_fsname_unexpanded);
+ sres = VG_(open)(xmlfilename,
+ VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
+ VKI_S_IRUSR|VKI_S_IWUSR);
+ if (!sr_isError(sres)) {
+ tmp_xml_fd = sr_Res(sres);
+ VG_(clo_xml_fname_expanded) = xmlfilename;
+ /* strdup here is probably paranoid overkill, but ... */
+ *xml_fname_unexpanded = VG_(strdup)( "main.mpclo.2",
+ xml_fsname_unexpanded );
+ } else {
+ VG_(message)(Vg_UserMsg,
+ "Can't create XML file '%s' (%s); giving up!\n",
+ xmlfilename, VG_(strerror)(sr_Err(sres)));
+ VG_(err_bad_option)(
+ "--xml-file=<file> (didn't work out for some reason.)");
+ /*NOTREACHED*/
+ }
+ break;
+ }
+
+ case VgLogTo_Socket: {
+ vg_assert(xml_fsname_unexpanded != NULL);
+ vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */
+ tmp_xml_fd = VG_(connect_via_socket)( xml_fsname_unexpanded );
+ if (tmp_xml_fd == -1) {
+ VG_(message)(Vg_UserMsg,
+ "Invalid --xml-socket=ipaddr or "
+ "--xml-socket=ipaddr:port spec\n");
+ VG_(message)(Vg_UserMsg,
+ "of '%s'; giving up!\n", xml_fsname_unexpanded );
+ VG_(err_bad_option)(
+ "--xml-socket=");
+ /*NOTREACHED*/
+ }
+ if (tmp_xml_fd == -2) {
+ VG_(message)(Vg_UserMsg,
+ "valgrind: failed to connect to XML logging server '%s'.\n",
+ xml_fsname_unexpanded );
+ VG_(message)(Vg_UserMsg,
+ "XML output will sent to stderr instead.\n" );
+ VG_(message)(Vg_UserMsg,
+ "\n" );
+ /* We don't change anything here. */
+ vg_assert(VG_(xml_output_sink).fd == 2);
+ tmp_xml_fd = 2;
+ } else {
+ vg_assert(tmp_xml_fd > 0);
+ VG_(xml_output_sink).is_socket = True;
+ }
+ break;
+ }
}
+ /* If we've got this far, and XML mode was requested, but no XML
+ output channel appears to have been specified, just stop. We
+ could continue, and XML output will simply vanish into nowhere,
+ but that is likely to confuse the hell out of users, which is
+ distinctly Ungood. */
+ if (VG_(clo_xml) && tmp_xml_fd == -1) {
+ VG_(umsg)(
+ "--xml=yes has been specified, but there is no XML output\n"
+ "destination. You must specify an XML output destination\n"
+ "using --xml-fd=, --xml-file= or --xml=socket=.\n" );
+ /* FIXME: this is really a misuse of VG_(err_bad_option). */
+ VG_(err_bad_option)(
+ "--xml=yes, but no XML destination specified");
+ }
+
+ // Finalise the output fds: the log fd ..
+
if (tmp_log_fd >= 0) {
- // Move log_fd into the safe range, so it doesn't conflict with any app fds.
+ // Move log_fd into the safe range, so it doesn't conflict with
+ // any app fds.
tmp_log_fd = VG_(fcntl)(tmp_log_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
if (tmp_log_fd < 0) {
- VG_(message)(Vg_UserMsg, "valgrind: failed to move logfile fd into safe range, using stderr");
- VG_(clo_log_fd) = 2; // stderr
+ VG_(message)(Vg_UserMsg, "valgrind: failed to move logfile fd "
+ "into safe range, using stderr\n");
+ VG_(log_output_sink).fd = 2; // stderr
+ VG_(log_output_sink).is_socket = False;
} else {
- VG_(clo_log_fd) = tmp_log_fd;
- VG_(fcntl)(VG_(clo_log_fd), VKI_F_SETFD, VKI_FD_CLOEXEC);
+ VG_(log_output_sink).fd = tmp_log_fd;
+ VG_(fcntl)(VG_(log_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
}
} else {
// If they said --log-fd=-1, don't print anything. Plausible for use in
// regression testing suites that use client requests to count errors.
- VG_(clo_log_fd) = tmp_log_fd;
+ VG_(log_output_sink).fd = -1;
+ VG_(log_output_sink).is_socket = False;
}
+ // Finalise the output fds: and the XML fd ..
+
+ if (tmp_xml_fd >= 0) {
+ // Move xml_fd into the safe range, so it doesn't conflict with
+ // any app fds.
+ tmp_xml_fd = VG_(fcntl)(tmp_xml_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
+ if (tmp_xml_fd < 0) {
+ VG_(message)(Vg_UserMsg, "valgrind: failed to move XML file fd "
+ "into safe range, using stderr\n");
+ VG_(xml_output_sink).fd = 2; // stderr
+ VG_(xml_output_sink).is_socket = False;
+ } else {
+ VG_(xml_output_sink).fd = tmp_xml_fd;
+ VG_(fcntl)(VG_(xml_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
+ }
+ } else {
+ // If they said --xml-fd=-1, don't print anything. Plausible for use in
+ // regression testing suites that use client requests to count errors.
+ VG_(xml_output_sink).fd = -1;
+ VG_(xml_output_sink).is_socket = False;
+ }
+
+ // Suppressions related stuff
+
if (VG_(clo_n_suppressions) < VG_CLO_MAX_SFILES-1 &&
(VG_(needs).core_errors || VG_(needs).tool_errors)) {
/* If we haven't reached the max number of suppressions, load
the default one. */
static const Char default_supp[] = "default.supp";
Int len = VG_(strlen)(VG_(libdir)) + 1 + sizeof(default_supp);
- Char *buf = VG_(arena_malloc)(VG_AR_CORE, "main.mpclo.2", len);
+ Char *buf = VG_(arena_malloc)(VG_AR_CORE, "main.mpclo.3", len);
VG_(sprintf)(buf, "%s/%s", VG_(libdir), default_supp);
VG_(clo_suppressions)[VG_(clo_n_suppressions)] = buf;
VG_(clo_n_suppressions)++;
}
- return (log_to == VgLogTo_Fd);
+ *logging_to_fd = log_to == VgLogTo_Fd || log_to == VgLogTo_Socket;
}
// Write the name and value of log file qualifiers to the xml file.
@@ -732,9 +938,9 @@
i++;
}
- VG_(message_no_f_c)(Vg_UserMsg,
+ VG_(message_no_f_c)(Vg_UserMsg,
"<logfilequalifier> <var>%t</var> "
- "<value>%t</value> </logfilequalifier>",
+ "<value>%t</value> </logfilequalifier>\n",
qualname,qual);
format[i] = '}';
i++;
@@ -755,146 +961,154 @@
If logging to file or a socket, write details of parent PID and
command line args, to help people trying to interpret the
results of a run which encompasses multiple processes. */
-static void print_preamble(Bool logging_to_fd, const char* toolname)
+static void print_preamble ( Bool logging_to_fd,
+ Char* xml_fname_unexpanded,
+ const HChar* toolname )
{
+ Int i;
HChar* xpre = VG_(clo_xml) ? " <line>" : "";
HChar* xpost = VG_(clo_xml) ? "</line>" : "";
- Int i;
+ UInt (*umsg_or_xml)( const HChar*, ... )
+ = VG_(clo_xml) ? VG_(printf_xml) : VG_(umsg);
vg_assert( VG_(args_for_client) );
vg_assert( VG_(args_for_valgrind) );
vg_assert( toolname );
if (VG_(clo_xml)) {
- VG_(message)(Vg_UserMsg, "<?xml version=\"1.0\"?>");
- VG_(message)(Vg_UserMsg, "");
- VG_(message)(Vg_UserMsg, "<valgrindoutput>");
- VG_(message)(Vg_UserMsg, "");
- VG_(message)(Vg_UserMsg, "<protocolversion>3</protocolversion>");
- VG_(message)(Vg_UserMsg, "");
+ VG_(printf_xml)("<?xml version=\"1.0\"?>\n");
+ VG_(printf_xml)("\n");
+ VG_(printf_xml)("<valgrindoutput>\n");
+ VG_(printf_xml)("\n");
+ VG_(printf_xml)("<protocolversion>4</protocolversion>\n");
+ VG_(printf_xml)("<protocoltool>%s</protocoltool>\n", toolname);
+ VG_(printf_xml)("\n");
}
- if (VG_(clo_verbosity > 0)) {
+ if (VG_(clo_xml) || VG_(clo_verbosity > 0)) {
if (VG_(clo_xml))
- VG_(message)(Vg_UserMsg, "<preamble>");
+ VG_(printf_xml)("<preamble>\n");
/* Tool details */
- VG_(message)(Vg_UserMsg, "%s%s%s%s, %s.%s",
+ umsg_or_xml( "%s%s%s%s, %s.%s\n",
xpre,
VG_(details).name,
NULL == VG_(details).version ? "" : "-",
NULL == VG_(details).version
? (Char*)"" : VG_(details).version,
VG_(details).description,
- xpost);
+ xpost );
if (VG_(strlen)(toolname) >= 4 && VG_STREQN(4, toolname, "exp-")) {
- VG_UMSG(
- "%sNOTE: This is an Experimental-Class Valgrind Tool.%s",
+ umsg_or_xml(
+ "%sNOTE: This is an Experimental-Class Valgrind Tool.%s\n",
xpre, xpost
);
}
- VG_(message)(Vg_UserMsg, "%s%s%s",
+ umsg_or_xml("%s%s%s\n",
xpre, VG_(details).copyright_author, xpost);
/* Core details */
- VG_(message)(Vg_UserMsg,
- "%sBuilt with Valgrind and LibVEX; rerun with -h for copyright info%s",
- xpre, xpost );
+ umsg_or_xml(
+ "%sBuilt with Valgrind and LibVEX; rerun with -h for copyright info%s\n",
+ xpre, xpost
+ );
if (VG_(clo_xml))
- VG_(message)(Vg_UserMsg, "</preamble>");
+ VG_(printf_xml)("</preamble>\n");
}
if (!VG_(clo_xml) && VG_(clo_verbosity) > 0 && !logging_to_fd) {
- VG_(message)(Vg_UserMsg, "");
- VG_(message)(Vg_UserMsg,
- "My PID = %d, parent PID = %d. Prog and args are:",
- VG_(getpid)(), VG_(getppid)() );
+ VG_(umsg)("\n");
+ VG_(umsg)("My PID = %d, parent PID = %d. Prog and args are:\n",
+ VG_(getpid)(), VG_(getppid)() );
if (VG_(args_the_exename))
- VG_(message)(Vg_UserMsg, " %s", VG_(args_the_exename));
+ VG_(umsg)(" %s\n", VG_(args_the_exename));
for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
- VG_(message)(Vg_UserMsg,
- " %s",
- * (HChar**) VG_(indexXA)( VG_(args_for_client), i ));
+ VG_(umsg)(" %s\n",
+ * (HChar**) VG_(indexXA)( VG_(args_for_client), i ));
}
else
if (VG_(clo_xml)) {
- VG_(message)(Vg_UserMsg, "");
- VG_(message)(Vg_UserMsg, "<pid>%d</pid>", VG_(getpid)());
- VG_(message)(Vg_UserMsg, "<ppid>%d</ppid>", VG_(getppid)());
- VG_(message_no_f_c)(Vg_UserMsg, "<tool>%t</tool>", toolname);
- if (VG_(clo_log_name))
- print_file_vars(VG_(clo_log_name));
+ VG_(printf_xml)("\n");
+ VG_(printf_xml)("<pid>%d</pid>\n", VG_(getpid)());
+ VG_(printf_xml)("<ppid>%d</ppid>\n", VG_(getppid)());
+ VG_(printf_xml_no_f_c)("<tool>%t</tool>\n", toolname);
+ if (xml_fname_unexpanded)
+ print_file_vars(xml_fname_unexpanded);
if (VG_(clo_xml_user_comment)) {
/* Note: the user comment itself is XML and is therefore to
be passed through verbatim (%s) rather than escaped
(%t). */
- VG_(message)(Vg_UserMsg, "<usercomment>%s</usercomment>",
- VG_(clo_xml_user_comment));
+ VG_(printf_xml)("<usercomment>%s</usercomment>\n",
+ VG_(clo_xml_user_comment));
}
- VG_(message)(Vg_UserMsg, "");
- VG_(message)(Vg_UserMsg, "<args>");
+ VG_(printf_xml)("\n");
+ VG_(printf_xml)("<args>\n");
- VG_(message)(Vg_UserMsg, " <vargv>");
+ VG_(printf_xml)(" <vargv>\n");
if (VG_(name_of_launcher))
- VG_(message_no_f_c)(Vg_UserMsg, " <exe>%t</exe>",
- VG_(name_of_launcher));
+ VG_(printf_xml_no_f_c)(" <exe>%t</exe>\n",
+ VG_(name_of_launcher));
else
- VG_(message_no_f_c)(Vg_UserMsg, " <exe>%t</exe>",
- "(launcher name unknown)");
+ VG_(printf_xml_no_f_c)(Vg_UserMsg, " <exe>%t</exe>\n",
+ "(launcher name unknown)");
for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
- VG_(message_no_f_c)(Vg_UserMsg,
- " <arg>%t</arg>",
- * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ));
+ VG_(printf_xml_no_f_c)(
+ " <arg>%t</arg>\n",
+ * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
+ );
}
- VG_(message)(Vg_UserMsg, " </vargv>");
+ VG_(printf_xml)(" </vargv>\n");
- VG_(message)(Vg_UserMsg, " <argv>");
+ VG_(printf_xml)(" <argv>\n");
if (VG_(args_the_exename))
- VG_(message_no_f_c)(Vg_UserMsg, " <exe>%t</exe>",
- VG_(args_the_exename));
+ VG_(printf_xml_no_f_c)(" <exe>%t</exe>\n",
+ VG_(args_the_exename));
for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
- VG_(message_no_f_c)(Vg_UserMsg,
- " <arg>%t</arg>",
- * (HChar**) VG_(indexXA)( VG_(args_for_client), i ));
+ VG_(printf_xml_no_f_c)(
+ " <arg>%t</arg>\n",
+ * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
+ );
}
- VG_(message)(Vg_UserMsg, " </argv>");
+ VG_(printf_xml)(" </argv>\n");
- VG_(message)(Vg_UserMsg, "</args>");
+ VG_(printf_xml)("</args>\n");
}
// Empty line after the preamble
if (VG_(clo_verbosity) > 0)
- VG_(message)(Vg_UserMsg, "");
+ VG_(message)(Vg_UserMsg, "\n");
+ if (VG_(clo_xml))
+ VG_(printf_xml)("\n");
if (VG_(clo_verbosity) > 1) {
SysRes fd;
VexArch vex_arch;
VexArchInfo vex_archinfo;
if (!logging_to_fd)
- VG_(message)(Vg_DebugMsg, "");
- VG_(message)(Vg_DebugMsg, "Command line");
+ VG_(message)(Vg_DebugMsg, "\n");
+ VG_(message)(Vg_DebugMsg, "Command line\n");
if (VG_(args_the_exename))
- VG_(message)(Vg_DebugMsg, " %s", VG_(args_the_exename));
+ VG_(message)(Vg_DebugMsg, " %s\n", VG_(args_the_exename));
for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
VG_(message)(Vg_DebugMsg,
- " %s",
+ " %s\n",
* (HChar**) VG_(indexXA)( VG_(args_for_client), i ));
- VG_(message)(Vg_DebugMsg, "Startup, with flags:");
+ VG_(message)(Vg_DebugMsg, "Startup, with flags:\n");
for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
VG_(message)(Vg_DebugMsg,
- " %s",
+ " %s\n",
* (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ));
}
- VG_(message)(Vg_DebugMsg, "Contents of /proc/version:");
+ VG_(message)(Vg_DebugMsg, "Contents of /proc/version:\n");
fd = VG_(open) ( "/proc/version", VKI_O_RDONLY, 0 );
if (sr_isError(fd)) {
- VG_(message)(Vg_DebugMsg, " can't open /proc/version");
+ VG_(message)(Vg_DebugMsg, " can't open /proc/version\n");
} else {
# define BUF_LEN 256
Char version_buf[BUF_LEN];
@@ -902,9 +1116,9 @@
vg_assert(n <= BUF_LEN);
if (n > 0) {
version_buf[n-1] = '\0';
- VG_(message)(Vg_DebugMsg, " %s", version_buf);
+ VG_(message)(Vg_DebugMsg, " %s\n", version_buf);
} else {
- VG_(message)(Vg_DebugMsg, " (empty?)");
+ VG_(message)(Vg_DebugMsg, " (empty?)\n");
}
VG_(close)(sr_Res(fd));
# undef BUF_LEN
@@ -913,16 +1127,17 @@
VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
VG_(message)(
Vg_DebugMsg,
- "Arch and hwcaps: %s, %s",
+ "Arch and hwcaps: %s, %s\n",
LibVEX_ppVexArch ( vex_arch ),
LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
);
VG_(message)(
Vg_DebugMsg,
- "Page sizes: currently %d, max supported %d",
+ "Page sizes: currently %d, max supported %d\n",
(Int)VKI_PAGE_SIZE, (Int)VKI_MAX_PAGE_SIZE
);
- VG_(message)(Vg_DebugMsg, "Valgrind library directory: %s", VG_(libdir));
+ VG_(message)(Vg_DebugMsg,
+ "Valgrind library directory: %s\n", VG_(libdir));
}
}
@@ -1131,8 +1346,9 @@
HChar* toolname = "memcheck"; // default to Memcheck
Int need_help = 0; // 0 = no, 1 = --help, 2 = --help-debug
ThreadId tid_main = VG_INVALID_THREADID;
+ Bool logging_to_fd = False;
+ Char* xml_fname_unexpanded = NULL;
Int loglevel, i;
- Bool logging_to_fd;
struct vki_rlimit zero = { 0, 0 };
XArray* addr2dihandle = NULL;
@@ -1628,7 +1844,8 @@
VG_(debugLog)(1, "main",
"(main_) Process Valgrind's command line options, "
"setup logging\n");
- logging_to_fd = main_process_cmd_line_options(toolname);
+ main_process_cmd_line_options ( &logging_to_fd, &xml_fname_unexpanded,
+ toolname );
//--------------------------------------------------------------
// Zeroise the millisecond counter by doing a first read of it.
@@ -1639,12 +1856,12 @@
//--------------------------------------------------------------
// Print the preamble
// p: tl_pre_clo_init [for 'VG_(details).name' and friends]
- // p: main_process_cmd_line_options() [for VG_(clo_verbosity),
- // VG_(clo_xml),
- // logging_to_fd]
+ // p: main_process_cmd_line_options()
+ // [for VG_(clo_verbosity), VG_(clo_xml),
+ // logging_to_fd, xml_fname_unexpanded]
//--------------------------------------------------------------
VG_(debugLog)(1, "main", "Print the preamble...\n");
- print_preamble(logging_to_fd, toolname);
+ print_preamble(logging_to_fd, xml_fname_unexpanded, toolname);
VG_(debugLog)(1, "main", "...finished the preamble\n");
//--------------------------------------------------------------
@@ -2050,13 +2267,12 @@
if (VG_(clo_xml)) {
HChar buf[50];
VG_(elapsed_wallclock_time)(buf);
- VG_(message_no_f_c)(Vg_UserMsg,
- "<status>\n"
- " <state>RUNNING</state>\n"
- " <time>%t</time>\n"
- "</status>",
- buf);
- VG_(message)(Vg_UserMsg, "");
+ VG_(printf_xml_no_f_c)( "<status>\n"
+ " <state>RUNNING</state>\n"
+ " <time>%t</time>\n"
+ "</status>\n",
+ buf );
+ VG_(printf_xml_no_f_c)( "\n" );
}
VG_(debugLog)(1, "main", "Running thread 1\n");
@@ -2149,41 +2365,62 @@
VG_(threads)[tid].status = VgTs_Empty;
//--------------------------------------------------------------
- // Finalisation: cleanup, messages, etc. Order no so important, only
+ // Finalisation: cleanup, messages, etc. Order not so important, only
// affects what order the messages come.
//--------------------------------------------------------------
if (VG_(clo_verbosity) > 0)
- VG_(message)(Vg_UserMsg, "");
+ VG_(message)(Vg_UserMsg, "\n");
+ if (VG_(clo_xml))
+ VG_(printf_xml)("\n");
if (VG_(clo_xml)) {
HChar buf[50];
- if (VG_(needs).core_errors || VG_(needs).tool_errors) {
- VG_(show_error_counts_as_XML)();
- VG_(message)(Vg_UserMsg, "");
- }
VG_(elapsed_wallclock_time)(buf);
- VG_(message_no_f_c)(Vg_UserMsg,
- "<status>\n"
- " <state>FINISHED</state>\n"
- " <time>%t</time>\n"
- "</status>",
- buf);
- VG_(message)(Vg_UserMsg, "");
+ VG_(printf_xml_no_f_c)( "<status>\n"
+ " <state>FINISHED</state>\n"
+ " <time>%t</time>\n"
+ "</status>\n",
+ buf);
}
/* Print out file descriptor summary and stats. */
if (VG_(clo_track_fds))
VG_(show_open_fds)();
- if (VG_(needs).core_errors || VG_(needs).tool_errors)
- VG_(show_all_errors)();
+ /* ** HACK ALERT ** HACK ALERT ** HACK ALERT ** HACK ALERT ** */
+ if (VG_(clo_xml)) {
+ /* THIS IS WHAT WE SHOULD CHANGE IT TO */
+ /* For the moment, do it like this (the "right way") in XML
+ mode, so that output is as described in XML Protocol 4. */
+ /* A good test is memcheck/tests/amd64/defcfaexpr; ensure
+ the output does not change */
+ VG_TDICT_CALL(tool_fini, 0/*exitcode*/);
- VG_TDICT_CALL(tool_fini, 0/*exitcode*/);
+ /* Show the error counts. */
+ if (VG_(needs).core_errors || VG_(needs).tool_errors) {
+ VG_(printf_xml)( "\n" );
+ VG_(show_error_counts_as_XML)();
+ VG_(printf_xml)( "\n" );
+ }
+
+ /* In XML mode, this merely prints the used suppressions. */
+ if (VG_(needs).core_errors || VG_(needs).tool_errors)
+ VG_(show_all_errors)();
+
+ } else {
+ /* THIS IS WHAT IT HAS ALWAYS BEEN,
+ resulting in https://bugs.kde.org/show_bug.cgi?id=186790 */
+ if (VG_(needs).core_errors || VG_(needs).tool_errors)
+ VG_(show_all_errors)();
+
+ VG_TDICT_CALL(tool_fini, 0/*exitcode*/);
+ }
+ /* END ** HACK ALERT ** HACK ALERT ** HACK ALERT ** HACK ALERT ** */
if (VG_(clo_xml)) {
- VG_(message)(Vg_UserMsg, "");
- VG_(message)(Vg_UserMsg, "</valgrindoutput>");
- VG_(message)(Vg_UserMsg, "");
+ VG_(printf_xml)("\n");
+ VG_(printf_xml)("</valgrindoutput>\n");
+ VG_(printf_xml)("\n");
}
VG_(sanity_check_general)( True /*include expensive checks*/ );
@@ -2210,6 +2447,9 @@
if (0)
LibVEX_ShowAllocStats();
+ /* Flush any output cached by previous calls to VG_(message). */
+ VG_(message_flush)();
+
/* Ok, finally exit in the os-specific way, according to the scheduler's
return code. In short, if the (last) thread exited by calling
sys_exit, do likewise; if the (last) thread stopped due to a fatal
@@ -2282,9 +2522,9 @@
r2 = VG_(get_tocptr)( __libc_freeres_wrapper );
if (r2 == 0) {
VG_(message)(Vg_UserMsg,
- "Caught __NR_exit, but can't run __libc_freeres()");
+ "Caught __NR_exit, but can't run __libc_freeres()\n");
VG_(message)(Vg_UserMsg,
- " since cannot establish TOC pointer for it.");
+ " since cannot establish TOC pointer for it.\n");
return;
}
# endif
@@ -2293,7 +2533,7 @@
VG_(clo_trace_syscalls) ||
VG_(clo_trace_sched))
VG_(message)(Vg_DebugMsg,
- "Caught __NR_exit; running __libc_freeres()");
+ "Caught __NR_exit; running __libc_freeres()\n");
/* set thread context to point to libc_freeres_wrapper */
/* ppc64-linux note: __libc_freeres_wrapper gives us the real
diff --git a/coregrind/m_mallocfree.c b/coregrind/m_mallocfree.c
index 14ee741..bad1f7f 100644
--- a/coregrind/m_mallocfree.c
+++ b/coregrind/m_mallocfree.c
@@ -495,7 +495,7 @@
for (i = 0; i < VG_N_ARENAS; i++) {
Arena* a = arenaId_to_ArenaP(i);
VG_(message)(Vg_DebugMsg,
- "%8s: %8ld mmap'd, %8ld/%8ld max/curr",
+ "%8s: %8ld mmap'd, %8ld/%8ld max/curr\n",
a->name, a->bytes_mmaped, a->bytes_on_loan_max, a->bytes_on_loan
);
}
@@ -1047,7 +1047,7 @@
if (VG_(clo_verbosity) > 2)
VG_(message)(Vg_DebugMsg,
"%8s: %2d sbs, %5d bs, %2d/%-2d free bs, "
- "%7ld mmap, %7ld loan",
+ "%7ld mmap, %7ld loan\n",
a->name,
superblockctr,
blockctr_sb, blockctr_sb_free, blockctr_li,
diff --git a/coregrind/m_options.c b/coregrind/m_options.c
index 69270dd..5db49f5 100644
--- a/coregrind/m_options.c
+++ b/coregrind/m_options.c
@@ -56,8 +56,8 @@
Bool VG_(clo_demangle) = True;
Bool VG_(clo_trace_children) = False;
Bool VG_(clo_child_silent_after_fork) = False;
-Int VG_(clo_log_fd) = 2; /* must be signed, as -1 is possible. */
-Char* VG_(clo_log_name) = NULL;
+Char* VG_(clo_log_fname_expanded) = NULL;
+Char* VG_(clo_xml_fname_expanded) = NULL;
Bool VG_(clo_time_stamp) = False;
Int VG_(clo_input_fd) = 0; /* stdin */
Int VG_(clo_n_suppressions) = 0;
@@ -99,8 +99,8 @@
static void revert_to_stderr ( void )
{
- vg_assert( !VG_(logging_to_socket) );
- VG_(clo_log_fd) = 2; /* stderr */
+ VG_(log_output_sink).fd = 2; /* stderr */
+ VG_(log_output_sink).is_socket = False;
}
__attribute__((noreturn))
@@ -143,7 +143,7 @@
if (VG_STREQ(format, "")) {
// Empty name, bad.
- VG_UMSG("%s: filename is empty", option_name);
+ VG_(umsg)("%s: filename is empty", option_name);
goto bad;
}
@@ -152,10 +152,11 @@
// that we don't allow a legitimate filename beginning with '~' but that
// seems very unlikely.
if (format[0] == '~') {
- VG_UMSG("%s: filename begins with '~'", option_name);
- VG_UMSG("You probably expected the shell to expand the '~', but it");
- VG_UMSG("didn't. The rules for '~'-expansion vary from shell to shell.");
- VG_UMSG("You might have more luck using $HOME instead.");
+ VG_(umsg)("%s: filename begins with '~'\n", option_name);
+ VG_(umsg)("You probably expected the shell to expand the '~', but it\n");
+ VG_(umsg)("didn't. The rules for '~'-expansion "
+ "vary from shell to shell.\n");
+ VG_(umsg)("You might have more luck using $HOME instead.\n");
goto bad;
}
@@ -209,7 +210,7 @@
qualname = &format[i];
while (True) {
if (0 == format[i]) {
- VG_(message)(Vg_UserMsg, "%s: malformed %%q specifier",
+ VG_(message)(Vg_UserMsg, "%s: malformed %%q specifier\n",
option_name);
goto bad;
} else if ('}' == format[i]) {
@@ -219,7 +220,7 @@
qual = VG_(getenv)(qualname);
if (NULL == qual) {
VG_(message)(Vg_UserMsg,
- "%s: environment variable %s is not set",
+ "%s: environment variable %s is not set\n",
option_name, qualname);
format[i] = '}'; // Put the '}' back.
goto bad;
@@ -234,14 +235,14 @@
j += VG_(sprintf)(&out[j], "%s", qual);
} else {
VG_(message)(Vg_UserMsg,
- "%s: expected '{' after '%%q'", option_name);
+ "%s: expected '{' after '%%q'\n", option_name);
goto bad;
}
}
else {
// Something else, abort.
VG_(message)(Vg_UserMsg,
- "%s: expected 'p' or 'q' or '%%' after '%%'", option_name);
+ "%s: expected 'p' or 'q' or '%%' after '%%'\n", option_name);
goto bad;
}
}
diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c
index d824a79..6b8d60c 100644
--- a/coregrind/m_redir.c
+++ b/coregrind/m_redir.c
@@ -412,7 +412,7 @@
/* Complain */
VG_(message)(Vg_DebugMsg,
- "WARNING: no TOC ptr for redir/wrap to %s %s",
+ "WARNING: no TOC ptr for redir/wrap to %s %s\n",
demangled_sopatt, demangled_fnpatt);
}
}
@@ -653,7 +653,7 @@
bad:
vg_assert(what);
if (VG_(clo_verbosity) > 1) {
- VG_(message)(Vg_UserMsg, "WARNING: %s", what);
+ VG_(message)(Vg_UserMsg, "WARNING: %s\n", what);
show_active( " new: ", &act);
}
}
@@ -1081,12 +1081,12 @@
static void show_spec ( HChar* left, Spec* spec )
{
- VG_(message)(Vg_DebugMsg,
- "%s%25s %30s %s-> 0x%08llx",
- left,
- spec->from_sopatt, spec->from_fnpatt,
- spec->isWrap ? "W" : "R",
- (ULong)spec->to_addr );
+ VG_(message)( Vg_DebugMsg,
+ "%s%25s %30s %s-> 0x%08llx\n",
+ left,
+ spec->from_sopatt, spec->from_fnpatt,
+ spec->isWrap ? "W" : "R",
+ (ULong)spec->to_addr );
}
static void show_active ( HChar* left, Active* act )
@@ -1100,7 +1100,7 @@
ok = VG_(get_fnname_w_offset)(act->to_addr, name2, 64);
if (!ok) VG_(strcpy)(name2, "???");
- VG_(message)(Vg_DebugMsg, "%s0x%08llx (%20s) %s-> 0x%08llx %s",
+ VG_(message)(Vg_DebugMsg, "%s0x%08llx (%20s) %s-> 0x%08llx %s\n",
left,
(ULong)act->from_addr, name1,
act->isWrap ? "W" : "R",
@@ -1112,23 +1112,23 @@
TopSpec* ts;
Spec* sp;
Active* act;
- VG_(message)(Vg_DebugMsg, "<<");
- VG_(message)(Vg_DebugMsg, " ------ REDIR STATE %s ------", who);
+ VG_(message)(Vg_DebugMsg, "<<\n");
+ VG_(message)(Vg_DebugMsg, " ------ REDIR STATE %s ------\n", who);
for (ts = topSpecs; ts; ts = ts->next) {
VG_(message)(Vg_DebugMsg,
- " TOPSPECS of soname %s",
+ " TOPSPECS of soname %s\n",
ts->seginfo ? (HChar*)VG_(seginfo_soname)(ts->seginfo)
: "(hardwired)" );
for (sp = ts->specs; sp; sp = sp->next)
show_spec(" ", sp);
}
- VG_(message)(Vg_DebugMsg, " ------ ACTIVE ------");
+ VG_(message)(Vg_DebugMsg, " ------ ACTIVE ------\n");
VG_(OSetGen_ResetIter)( activeSet );
while ( (act = VG_(OSetGen_Next)(activeSet)) ) {
show_active(" ", act);
}
- VG_(message)(Vg_DebugMsg, ">>");
+ VG_(message)(Vg_DebugMsg, ">>\n");
}
/*--------------------------------------------------------------------*/
diff --git a/coregrind/m_replacemalloc/replacemalloc_core.c b/coregrind/m_replacemalloc/replacemalloc_core.c
index fbae2bc..de1d984 100644
--- a/coregrind/m_replacemalloc/replacemalloc_core.c
+++ b/coregrind/m_replacemalloc/replacemalloc_core.c
@@ -60,7 +60,9 @@
{
VG_(message)(Vg_UserMsg,
"Invalid --alignment= setting. "
- "Should be a power of 2, >= %d, <= 4096.", VG_MIN_MALLOC_SZB);
+ "Should be a power of 2, >= %d, <= 4096.\n",
+ VG_MIN_MALLOC_SZB
+ );
VG_(err_bad_option)("--alignment");
}
}
diff --git a/coregrind/m_scheduler/scheduler.c b/coregrind/m_scheduler/scheduler.c
index 91bb20c..295e0ab 100644
--- a/coregrind/m_scheduler/scheduler.c
+++ b/coregrind/m_scheduler/scheduler.c
@@ -127,12 +127,12 @@
void VG_(print_scheduler_stats)(void)
{
VG_(message)(Vg_DebugMsg,
- "scheduler: %'llu jumps (bb entries).", bbs_done );
+ "scheduler: %'llu jumps (bb entries).\n", bbs_done );
VG_(message)(Vg_DebugMsg,
- "scheduler: %'llu/%'llu major/minor sched events.",
+ "scheduler: %'llu/%'llu major/minor sched events.\n",
n_scheduling_events_MAJOR, n_scheduling_events_MINOR);
VG_(message)(Vg_DebugMsg,
- " sanity: %d cheap, %d expensive checks.",
+ " sanity: %d cheap, %d expensive checks.\n",
sanity_fast_count, sanity_slow_count );
}
@@ -147,7 +147,7 @@
static
void print_sched_event ( ThreadId tid, Char* what )
{
- VG_(message)(Vg_DebugMsg, " SCHED[%d]: %s", tid, what );
+ VG_(message)(Vg_DebugMsg, " SCHED[%d]: %s\n", tid, what );
}
static
@@ -320,7 +320,7 @@
if (VG_(threads)[tid].status == VgTs_WaitSys) {
if (VG_(clo_trace_signals)) {
VG_(message)(Vg_DebugMsg,
- "get_thread_out_of_syscall zaps tid %d lwp %d",
+ "get_thread_out_of_syscall zaps tid %d lwp %d\n",
tid, VG_(threads)[tid].os_state.lwpid);
}
# if defined(VGO_darwin)
@@ -1024,8 +1024,8 @@
n_scheduling_events_MINOR++;
if (0)
- VG_(message)(Vg_DebugMsg, "thread %d: running for %d bbs",
- tid, VG_(dispatch_ctr) - 1 );
+ VG_(message)(Vg_DebugMsg, "thread %d: running for %d bbs\n",
+ tid, VG_(dispatch_ctr) - 1 );
trc = run_thread_for_a_while ( tid );
@@ -1120,8 +1120,8 @@
: counts[ew]++ < 3;
if (show && VG_(clo_show_emwarns) && !VG_(clo_xml)) {
VG_(message)( Vg_UserMsg,
- "Emulation warning: unsupported action:");
- VG_(message)( Vg_UserMsg, " %s", what);
+ "Emulation warning: unsupported action:\n");
+ VG_(message)( Vg_UserMsg, " %s\n", what);
VG_(get_and_pp_StackTrace)( tid, VG_(clo_backtrace_size) );
}
break;
@@ -1135,12 +1135,12 @@
? "unknown (?!)"
: LibVEX_EmWarn_string(ew);
VG_(message)( Vg_UserMsg,
- "Emulation fatal error -- Valgrind cannot continue:");
- VG_(message)( Vg_UserMsg, " %s", what);
+ "Emulation fatal error -- Valgrind cannot continue:\n");
+ VG_(message)( Vg_UserMsg, " %s\n", what);
VG_(get_and_pp_StackTrace)( tid, VG_(clo_backtrace_size) );
- VG_(message)(Vg_UserMsg, "");
- VG_(message)(Vg_UserMsg, "Valgrind has to exit now. Sorry.");
- VG_(message)(Vg_UserMsg, "");
+ VG_(message)(Vg_UserMsg, "\n");
+ VG_(message)(Vg_UserMsg, "Valgrind has to exit now. Sorry.\n");
+ VG_(message)(Vg_UserMsg, "\n");
VG_(exit)(1);
break;
}
@@ -1158,10 +1158,10 @@
break;
case VEX_TRC_JMP_NODECODE:
- VG_(message)(Vg_UserMsg,
- "valgrind: Unrecognised instruction at address %#lx.",
+ VG_(umsg)(
+ "valgrind: Unrecognised instruction at address %#lx.\n",
VG_(get_IP)(tid));
-#define M(a) VG_(message)(Vg_UserMsg, a);
+#define M(a) VG_(umsg)(a "\n");
M("Your program just tried to execute an instruction that Valgrind" );
M("did not recognise. There are two possible reasons for this." );
M("1. Your program has a bug and erroneously jumped to a non-code" );
@@ -1318,8 +1318,8 @@
/* This is equivalent to an exit() syscall, but we don't set the
exitcode (since it might already be set) */
if (0 || VG_(clo_trace_syscalls) || VG_(clo_trace_sched))
- VG_(message)(Vg_DebugMsg,
- "__libc_freeres() done; really quitting!");
+ VG_(message)(Vg_DebugMsg,
+ "__libc_freeres() done; really quitting!\n");
VG_(threads)[tid].exitreason = VgSrc_ExitThread;
break;
@@ -1349,7 +1349,7 @@
case VG_USERREQ__CLIENT_CALL0: {
UWord (*f)(ThreadId) = (void*)arg[1];
if (f == NULL)
- VG_(message)(Vg_DebugMsg, "VG_USERREQ__CLIENT_CALL0: func=%p", f);
+ VG_(message)(Vg_DebugMsg, "VG_USERREQ__CLIENT_CALL0: func=%p\n", f);
else
SET_CLCALL_RETVAL(tid, f ( tid ), (Addr)f);
break;
@@ -1357,7 +1357,7 @@
case VG_USERREQ__CLIENT_CALL1: {
UWord (*f)(ThreadId, UWord) = (void*)arg[1];
if (f == NULL)
- VG_(message)(Vg_DebugMsg, "VG_USERREQ__CLIENT_CALL1: func=%p", f);
+ VG_(message)(Vg_DebugMsg, "VG_USERREQ__CLIENT_CALL1: func=%p\n", f);
else
SET_CLCALL_RETVAL(tid, f ( tid, arg[2] ), (Addr)f );
break;
@@ -1365,7 +1365,7 @@
case VG_USERREQ__CLIENT_CALL2: {
UWord (*f)(ThreadId, UWord, UWord) = (void*)arg[1];
if (f == NULL)
- VG_(message)(Vg_DebugMsg, "VG_USERREQ__CLIENT_CALL2: func=%p", f);
+ VG_(message)(Vg_DebugMsg, "VG_USERREQ__CLIENT_CALL2: func=%p\n", f);
else
SET_CLCALL_RETVAL(tid, f ( tid, arg[2], arg[3] ), (Addr)f );
break;
@@ -1373,7 +1373,7 @@
case VG_USERREQ__CLIENT_CALL3: {
UWord (*f)(ThreadId, UWord, UWord, UWord) = (void*)arg[1];
if (f == NULL)
- VG_(message)(Vg_DebugMsg, "VG_USERREQ__CLIENT_CALL3: func=%p", f);
+ VG_(message)(Vg_DebugMsg, "VG_USERREQ__CLIENT_CALL3: func=%p\n", f);
else
SET_CLCALL_RETVAL(tid, f ( tid, arg[2], arg[3], arg[4] ), (Addr)f );
break;
@@ -1388,18 +1388,21 @@
case VG_USERREQ__PRINTF: {
Int count =
VG_(vmessage)( Vg_ClientMsg, (char *)arg[1], (void*)arg[2] );
+ VG_(message_flush)();
SET_CLREQ_RETVAL( tid, count );
break; }
case VG_USERREQ__INTERNAL_PRINTF: {
Int count =
VG_(vmessage)( Vg_DebugMsg, (char *)arg[1], (void*)arg[2] );
+ VG_(message_flush)();
SET_CLREQ_RETVAL( tid, count );
break; }
case VG_USERREQ__PRINTF_BACKTRACE: {
Int count =
VG_(vmessage)( Vg_ClientMsg, (char *)arg[1], (void*)arg[2] );
+ VG_(message_flush)();
VG_(get_and_pp_StackTrace)( tid, VG_(clo_backtrace_size) );
SET_CLREQ_RETVAL( tid, count );
break; }
@@ -1500,7 +1503,7 @@
if (c2 == 0) c2 = '_';
VG_(message)(Vg_UserMsg, "Warning:\n"
" unhandled client request: 0x%lx (%c%c+0x%lx). Perhaps\n"
- " VG_(needs).client_requests should be set?",
+ " VG_(needs).client_requests should be set?\n",
arg[0], c1, c2, arg[0] & 0xffff);
whined = True;
}
@@ -1622,7 +1625,7 @@
if (remains < VKI_PAGE_SIZE)
VG_(message)(Vg_DebugMsg,
"WARNING: Thread %d is within %ld bytes "
- "of running out of stack!",
+ "of running out of stack!\n",
tid, remains);
}
}
diff --git a/coregrind/m_sigframe/sigframe-amd64-linux.c b/coregrind/m_sigframe/sigframe-amd64-linux.c
index b3b97d1..30f78dc 100644
--- a/coregrind/m_sigframe/sigframe-amd64-linux.c
+++ b/coregrind/m_sigframe/sigframe-amd64-linux.c
@@ -390,12 +390,12 @@
if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) {
VG_(message)(
Vg_UserMsg,
- "Can't extend stack to %#lx during signal delivery for thread %d:",
+ "Can't extend stack to %#lx during signal delivery for thread %d:\n",
addr, tid);
if (stackseg == NULL)
- VG_(message)(Vg_UserMsg, " no stack segment");
+ VG_(message)(Vg_UserMsg, " no stack segment\n");
else
- VG_(message)(Vg_UserMsg, " too small or bad protection modes");
+ VG_(message)(Vg_UserMsg, " too small or bad protection modes\n");
/* set SIGSEGV to default handler */
VG_(set_default_handler)(VKI_SIGSEGV);
@@ -543,7 +543,7 @@
if (frame->magicPI != 0x31415927 ||
frame->magicE != 0x27182818) {
VG_(message)(Vg_UserMsg, "Thread %d return signal frame "
- "corrupted. Killing process.",
+ "corrupted. Killing process.\n",
tst->tid);
VG_(set_default_handler)(VKI_SIGSEGV);
VG_(synth_fault)(tst->tid);
@@ -626,7 +626,7 @@
if (VG_(clo_trace_signals))
VG_(message)(
Vg_DebugMsg,
- "VG_(signal_return) (thread %d): isRT=%d valid magic; RIP=%#llx",
+ "VG_(signal_return) (thread %d): isRT=%d valid magic; RIP=%#llx\n",
tid, isRT, tst->arch.vex.guest_RIP);
/* tell the tools */
diff --git a/coregrind/m_sigframe/sigframe-ppc32-aix5.c b/coregrind/m_sigframe/sigframe-ppc32-aix5.c
index 3cecd57..d6b6e28 100644
--- a/coregrind/m_sigframe/sigframe-ppc32-aix5.c
+++ b/coregrind/m_sigframe/sigframe-ppc32-aix5.c
@@ -221,7 +221,7 @@
if (VG_(clo_trace_signals))
VG_(message)(Vg_DebugMsg,
- "vg_pop_signal_frame (thread %d): valid magic; CIA=%#x",
+ "vg_pop_signal_frame (thread %d): valid magic; CIA=%#x\n",
tid, tst->arch.vex.guest_CIA);
VG_TRACK( die_mem_stack_signal,
diff --git a/coregrind/m_sigframe/sigframe-ppc32-linux.c b/coregrind/m_sigframe/sigframe-ppc32-linux.c
index d36988c..7144230 100644
--- a/coregrind/m_sigframe/sigframe-ppc32-linux.c
+++ b/coregrind/m_sigframe/sigframe-ppc32-linux.c
@@ -520,12 +520,12 @@
if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) {
VG_(message)(
Vg_UserMsg,
- "Can't extend stack to %#lx during signal delivery for thread %d:",
+ "Can't extend stack to %#lx during signal delivery for thread %d:\n",
addr, tid);
if (stackseg == NULL)
- VG_(message)(Vg_UserMsg, " no stack segment");
+ VG_(message)(Vg_UserMsg, " no stack segment\n");
else
- VG_(message)(Vg_UserMsg, " too small or bad protection modes");
+ VG_(message)(Vg_UserMsg, " too small or bad protection modes\n");
/* set SIGSEGV to default handler */
VG_(set_default_handler)(VKI_SIGSEGV);
@@ -942,7 +942,8 @@
if (VG_(clo_trace_signals))
VG_(message)(Vg_DebugMsg,
- "vg_pop_signal_frame (thread %d): isRT=%d valid magic; EIP=%#x",
+ "vg_pop_signal_frame (thread %d): "
+ "isRT=%d valid magic; EIP=%#x\n",
tid, has_siginfo, tst->arch.vex.guest_CIA);
/* tell the tools */
diff --git a/coregrind/m_sigframe/sigframe-ppc64-aix5.c b/coregrind/m_sigframe/sigframe-ppc64-aix5.c
index 083a5a1..1f94a93 100644
--- a/coregrind/m_sigframe/sigframe-ppc64-aix5.c
+++ b/coregrind/m_sigframe/sigframe-ppc64-aix5.c
@@ -233,7 +233,7 @@
if (frame->magicPI != 0x31415927) {
if (!VG_(clo_xml))
VG_(message)(Vg_DebugMsg,
- "WARNING: dubious signal return: searching %ld bytes for frame",
+ "WARNING: dubious signal return: searching %ld bytes for frame\n",
scannable_bytes);
for (i = 0; i < scannable_bytes/4; i++) {
if (frame->magicPI == 0x31415927)
@@ -255,7 +255,7 @@
if (VG_(clo_trace_signals))
VG_(message)(Vg_DebugMsg,
- "vg_pop_signal_frame (thread %d): valid magic; CIA=%#llx",
+ "vg_pop_signal_frame (thread %d): valid magic; CIA=%#llx\n",
tid, tst->arch.vex.guest_CIA);
VG_TRACK( die_mem_stack_signal,
diff --git a/coregrind/m_sigframe/sigframe-ppc64-linux.c b/coregrind/m_sigframe/sigframe-ppc64-linux.c
index 16411d7..f3cd180 100644
--- a/coregrind/m_sigframe/sigframe-ppc64-linux.c
+++ b/coregrind/m_sigframe/sigframe-ppc64-linux.c
@@ -150,12 +150,12 @@
if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) {
VG_(message)(
Vg_UserMsg,
- "Can't extend stack to %#lx during signal delivery for thread %d:",
+ "Can't extend stack to %#lx during signal delivery for thread %d:\n",
addr, tid);
if (stackseg == NULL)
- VG_(message)(Vg_UserMsg, " no stack segment");
+ VG_(message)(Vg_UserMsg, " no stack segment\n");
else
- VG_(message)(Vg_UserMsg, " too small or bad protection modes");
+ VG_(message)(Vg_UserMsg, " too small or bad protection modes\n");
/* set SIGSEGV to default handler */
VG_(set_default_handler)(VKI_SIGSEGV);
@@ -377,7 +377,8 @@
if (VG_(clo_trace_signals))
VG_(message)(Vg_DebugMsg,
- "vg_pop_signal_frame (thread %d): isRT=%d valid magic; EIP=%#llx",
+ "vg_pop_signal_frame (thread %d): isRT=%d "
+ "valid magic; EIP=%#llx\n",
tid, has_siginfo, tst->arch.vex.guest_CIA);
/* tell the tools */
diff --git a/coregrind/m_sigframe/sigframe-x86-linux.c b/coregrind/m_sigframe/sigframe-x86-linux.c
index 11b779f..cfaaafb 100644
--- a/coregrind/m_sigframe/sigframe-x86-linux.c
+++ b/coregrind/m_sigframe/sigframe-x86-linux.c
@@ -411,12 +411,12 @@
if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) {
VG_(message)(
Vg_UserMsg,
- "Can't extend stack to %#lx during signal delivery for thread %d:",
+ "Can't extend stack to %#lx during signal delivery for thread %d:\n",
addr, tid);
if (stackseg == NULL)
- VG_(message)(Vg_UserMsg, " no stack segment");
+ VG_(message)(Vg_UserMsg, " no stack segment\n");
else
- VG_(message)(Vg_UserMsg, " too small or bad protection modes");
+ VG_(message)(Vg_UserMsg, " too small or bad protection modes\n");
/* set SIGSEGV to default handler */
VG_(set_default_handler)(VKI_SIGSEGV);
@@ -627,7 +627,7 @@
if (frame->magicPI != 0x31415927 ||
frame->magicE != 0x27182818) {
VG_(message)(Vg_UserMsg, "Thread %d return signal frame "
- "corrupted. Killing process.",
+ "corrupted. Killing process.\n",
tst->tid);
VG_(set_default_handler)(VKI_SIGSEGV);
VG_(synth_fault)(tst->tid);
@@ -716,7 +716,7 @@
if (VG_(clo_trace_signals))
VG_(message)(
Vg_DebugMsg,
- "VG_(signal_return) (thread %d): isRT=%d valid magic; EIP=%#x",
+ "VG_(signal_return) (thread %d): isRT=%d valid magic; EIP=%#x\n",
tid, isRT, tst->arch.vex.guest_EIP);
/* tell the tools */
diff --git a/coregrind/m_signals.c b/coregrind/m_signals.c
index c4a1a36..8765c76 100644
--- a/coregrind/m_signals.c
+++ b/coregrind/m_signals.c
@@ -871,12 +871,12 @@
VG_(sigdelset)( &ksa.sa_mask, VKI_SIGSTOP );
if (VG_(clo_trace_signals) && VG_(clo_verbosity) > 2)
- VG_DMSG("setting ksig %d to: hdlr %p, flags 0x%lx, "
- "mask(msb..lsb) 0x%llx 0x%llx",
- sig, ksa.ksa_handler,
- (UWord)ksa.sa_flags,
- _VKI_NSIG_WORDS > 1 ? (ULong)ksa.sa_mask.sig[1] : 0,
- (ULong)ksa.sa_mask.sig[0]);
+ VG_(dmsg)("setting ksig %d to: hdlr %p, flags 0x%lx, "
+ "mask(msb..lsb) 0x%llx 0x%llx\n",
+ sig, ksa.ksa_handler,
+ (UWord)ksa.sa_flags,
+ _VKI_NSIG_WORDS > 1 ? (ULong)ksa.sa_mask.sig[1] : 0,
+ (ULong)ksa.sa_mask.sig[0]);
res = VG_(sigaction)( sig, &ksa, &ksa_old );
vg_assert(res == 0);
@@ -935,13 +935,13 @@
m_SP = VG_(get_SP)(tid);
if (VG_(clo_trace_signals))
- VG_EMSG("sys_sigaltstack: tid %d, "
- "ss %p{%p,sz=%llu,flags=0x%llx}, oss %p (current SP %p)",
- tid, (void*)ss,
- ss ? ss->ss_sp : 0,
- (ULong)(ss ? ss->ss_size : 0),
- (ULong)(ss ? ss->ss_flags : 0),
- (void*)oss, (void*)m_SP);
+ VG_(emsg)("sys_sigaltstack: tid %d, "
+ "ss %p{%p,sz=%llu,flags=0x%llx}, oss %p (current SP %p)\n",
+ tid, (void*)ss,
+ ss ? ss->ss_sp : 0,
+ (ULong)(ss ? ss->ss_size : 0),
+ (ULong)(ss ? ss->ss_flags : 0),
+ (void*)oss, (void*)m_SP);
if (oss != NULL) {
oss->ss_sp = VG_(threads)[tid].altstack.ss_sp;
@@ -980,10 +980,10 @@
vki_sigaction_fromK_t* old_act )
{
if (VG_(clo_trace_signals))
- VG_EMSG("sys_sigaction: sigNo %d, "
- "new %#lx, old %#lx, new flags 0x%llx",
- signo, (UWord)new_act, (UWord)old_act,
- (ULong)(new_act ? new_act->sa_flags : 0));
+ VG_(emsg)("sys_sigaction: sigNo %d, "
+ "new %#lx, old %#lx, new flags 0x%llx\n",
+ signo, (UWord)new_act, (UWord)old_act,
+ (ULong)(new_act ? new_act->sa_flags : 0));
/* Rule out various error conditions. The aim is to ensure that if
when the call is passed to the kernel it will definitely
@@ -1046,25 +1046,25 @@
bad_signo:
if (VG_(showing_core_errors)() && !VG_(clo_xml)) {
- VG_UMSG("Warning: bad signal number %d in sigaction()", signo);
+ VG_(umsg)("Warning: bad signal number %d in sigaction()\n", signo);
}
return VG_(mk_SysRes_Error)( VKI_EINVAL );
bad_signo_reserved:
if (VG_(showing_core_errors)() && !VG_(clo_xml)) {
- VG_UMSG("Warning: ignored attempt to set %s handler in sigaction();",
- signame(signo));
- VG_UMSG(" the %s signal is used internally by Valgrind",
- signame(signo));
+ VG_(umsg)("Warning: ignored attempt to set %s handler in sigaction();\n",
+ signame(signo));
+ VG_(umsg)(" the %s signal is used internally by Valgrind\n",
+ signame(signo));
}
return VG_(mk_SysRes_Error)( VKI_EINVAL );
bad_sigkill_or_sigstop:
if (VG_(showing_core_errors)() && !VG_(clo_xml)) {
- VG_UMSG("Warning: ignored attempt to set %s handler in sigaction();",
- signame(signo));
- VG_UMSG(" the %s signal is uncatchable",
- signame(signo));
+ VG_(umsg)("Warning: ignored attempt to set %s handler in sigaction();\n",
+ signame(signo));
+ VG_(umsg)(" the %s signal is uncatchable\n",
+ signame(signo));
}
return VG_(mk_SysRes_Error)( VKI_EINVAL );
}
@@ -1129,19 +1129,19 @@
vki_sigset_t* oldset )
{
if (VG_(clo_trace_signals))
- VG_EMSG("do_setmask: tid = %d how = %d (%s), newset = %p (%s)",
- tid, how,
- how==VKI_SIG_BLOCK ? "SIG_BLOCK" : (
- how==VKI_SIG_UNBLOCK ? "SIG_UNBLOCK" : (
- how==VKI_SIG_SETMASK ? "SIG_SETMASK" : "???")),
- newset, newset ? format_sigset(newset) : "NULL" );
+ VG_(emsg)("do_setmask: tid = %d how = %d (%s), newset = %p (%s)\n",
+ tid, how,
+ how==VKI_SIG_BLOCK ? "SIG_BLOCK" : (
+ how==VKI_SIG_UNBLOCK ? "SIG_UNBLOCK" : (
+ how==VKI_SIG_SETMASK ? "SIG_SETMASK" : "???")),
+ newset, newset ? format_sigset(newset) : "NULL" );
/* Just do this thread. */
vg_assert(VG_(is_valid_tid)(tid));
if (oldset) {
*oldset = VG_(threads)[tid].sig_mask;
if (VG_(clo_trace_signals))
- VG_EMSG("\toldset=%p %s", oldset, format_sigset(oldset));
+ VG_(emsg)("\toldset=%p %s\n", oldset, format_sigset(oldset));
}
if (newset) {
do_sigprocmask_bitops (how, &VG_(threads)[tid].sig_mask, newset );
@@ -1166,7 +1166,7 @@
return VG_(mk_SysRes_Success)( 0 );
default:
- VG_DMSG("sigprocmask: unknown 'how' field %d", how);
+ VG_(dmsg)("sigprocmask: unknown 'how' field %d\n", how);
return VG_(mk_SysRes_Error)( VKI_EINVAL );
}
}
@@ -1229,7 +1229,7 @@
tst = & VG_(threads)[tid];
if (VG_(clo_trace_signals)) {
- VG_DMSG("push_signal_frame (thread %d): signal %d", tid, sigNo);
+ VG_(dmsg)("push_signal_frame (thread %d): signal %d\n", tid, sigNo);
VG_(get_and_pp_StackTrace)(tid, 10);
}
@@ -1243,11 +1243,11 @@
esp_top_of_frame
= (Addr)(tst->altstack.ss_sp) + tst->altstack.ss_size;
if (VG_(clo_trace_signals))
- VG_DMSG("delivering signal %d (%s) to thread %d: "
- "on ALT STACK (%p-%p; %ld bytes)",
- sigNo, signame(sigNo), tid, tst->altstack.ss_sp,
- (UChar *)tst->altstack.ss_sp + tst->altstack.ss_size,
- (unsigned long)tst->altstack.ss_size );
+ VG_(dmsg)("delivering signal %d (%s) to thread %d: "
+ "on ALT STACK (%p-%p; %ld bytes)\n",
+ sigNo, signame(sigNo), tid, tst->altstack.ss_sp,
+ (UChar *)tst->altstack.ss_sp + tst->altstack.ss_size,
+ (Word)tst->altstack.ss_size );
/* Signal delivery to tools */
VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/True );
@@ -1469,9 +1469,9 @@
vg_assert(!core || (core && terminate));
if (VG_(clo_trace_signals))
- VG_DMSG("delivering %d (code %d) to default handler; action: %s%s",
- sigNo, info->si_code, terminate ? "terminate" : "ignore",
- core ? "+core" : "");
+ VG_(dmsg)("delivering %d (code %d) to default handler; action: %s%s\n",
+ sigNo, info->si_code, terminate ? "terminate" : "ignore",
+ core ? "+core" : "");
if (!terminate)
return; /* nothing to do */
@@ -1492,9 +1492,10 @@
(could_core && is_signal_from_kernel(tid, sigNo, info->si_code))
) &&
!VG_(clo_xml) ) {
- VG_UMSG("");
- VG_UMSG("Process terminating with default action of signal %d (%s)%s",
- sigNo, signame(sigNo), core ? ": dumping core" : "");
+ VG_(umsg)("\n");
+ VG_(umsg)(
+ "Process terminating with default action of signal %d (%s)%s\n",
+ sigNo, signame(sigNo), core ? ": dumping core" : "");
/* Be helpful - decode some more details about this fault */
if (is_signal_from_kernel(tid, sigNo, info->si_code)) {
@@ -1504,8 +1505,10 @@
switch(sigNo) {
case VKI_SIGSEGV:
switch(info->si_code) {
- case VKI_SEGV_MAPERR: event = "Access not within mapped region"; break;
- case VKI_SEGV_ACCERR: event = "Bad permissions for mapped region"; break;
+ case VKI_SEGV_MAPERR: event = "Access not within mapped region";
+ break;
+ case VKI_SEGV_ACCERR: event = "Bad permissions for mapped region";
+ break;
case VKI_SEGV_MADE_UP_GPF:
/* General Protection Fault: The CPU/kernel
isn't telling us anything useful, but this
@@ -1562,9 +1565,10 @@
if (event != NULL) {
if (haveaddr)
- VG_UMSG(" %s at address %p", event, info->VKI_SIGINFO_si_addr);
+ VG_(umsg)(" %s at address %p\n",
+ event, info->VKI_SIGINFO_si_addr);
else
- VG_UMSG(" %s", event);
+ VG_(umsg)(" %s\n", event);
}
}
/* Print a stack trace. Be cautious if the thread's SP is in an
@@ -1581,14 +1585,15 @@
if (sigNo == VKI_SIGSEGV
&& info && is_signal_from_kernel(tid, sigNo, info->si_code)
&& info->si_code == VKI_SEGV_MAPERR) {
- VG_UMSG(" If you believe this happened as a result of a stack" );
- VG_UMSG(" overflow in your program's main thread (unlikely but");
- VG_UMSG(" possible), you can try to increase the size of the" );
- VG_UMSG(" main thread stack using the --main-stacksize= flag." );
+ VG_(umsg)(" If you believe this happened as a result of a stack\n" );
+ VG_(umsg)(" overflow in your program's main thread (unlikely but\n");
+ VG_(umsg)(" possible), you can try to increase the size of the\n" );
+ VG_(umsg)(" main thread stack using the --main-stacksize= flag.\n" );
// FIXME: assumes main ThreadId == 1
if (VG_(is_valid_tid)(1)) {
- VG_UMSG(" The main thread stack size used in this run was %d.",
- (Int)VG_(threads)[1].client_stack_szB);
+ VG_(umsg)(
+ " The main thread stack size used in this run was %d.\n",
+ (Int)VG_(threads)[1].client_stack_szB);
}
}
}
@@ -1634,8 +1639,8 @@
ThreadState *tst = VG_(get_ThreadState)(tid);
if (VG_(clo_trace_signals))
- VG_DMSG("delivering signal %d (%s):%d to thread %d",
- sigNo, signame(sigNo), info->si_code, tid );
+ VG_(dmsg)("delivering signal %d (%s):%d to thread %d\n",
+ sigNo, signame(sigNo), info->si_code, tid );
if (sigNo == VG_SIGVGKILL) {
/* If this is a SIGVGKILL, we're expecting it to interrupt any
@@ -1849,8 +1854,8 @@
sq = tst->sig_queue;
if (VG_(clo_trace_signals))
- VG_DMSG("Queueing signal %d (idx %d) to thread %d",
- si->si_signo, sq->next, tid);
+ VG_(dmsg)("Queueing signal %d (idx %d) to thread %d\n",
+ si->si_signo, sq->next, tid);
/* Add signal to the queue. If the queue gets overrun, then old
queued signals may get lost.
@@ -1859,8 +1864,8 @@
least a non-siginfo signal gets deliviered.
*/
if (sq->sigs[sq->next].si_signo != 0)
- VG_UMSG("Signal %d being dropped from thread %d's queue",
- sq->sigs[sq->next].si_signo, tid);
+ VG_(umsg)("Signal %d being dropped from thread %d's queue\n",
+ sq->sigs[sq->next].si_signo, tid);
sq->sigs[sq->next] = *si;
sq->next = (sq->next+1) % N_QUEUED_SIGNALS;
@@ -1891,12 +1896,14 @@
do {
if (0)
VG_(printf)("idx=%d si_signo=%d inset=%d\n", idx,
- sq->sigs[idx].si_signo, VG_(sigismember)(set, sq->sigs[idx].si_signo));
+ sq->sigs[idx].si_signo,
+ VG_(sigismember)(set, sq->sigs[idx].si_signo));
- if (sq->sigs[idx].si_signo != 0 && VG_(sigismember)(set, sq->sigs[idx].si_signo)) {
+ if (sq->sigs[idx].si_signo != 0
+ && VG_(sigismember)(set, sq->sigs[idx].si_signo)) {
if (VG_(clo_trace_signals))
- VG_DMSG("Returning queued signal %d (idx %d) for thread %d",
- sq->sigs[idx].si_signo, idx, tid);
+ VG_(dmsg)("Returning queued signal %d (idx %d) for thread %d\n",
+ sq->sigs[idx].si_signo, idx, tid);
ret = &sq->sigs[idx];
goto out;
}
@@ -1947,8 +1954,8 @@
info->si_code = sanitize_si_code(info->si_code);
if (VG_(clo_trace_signals))
- VG_DMSG("async signal handler: signal=%d, tid=%d, si_code=%d",
- sigNo, tid, info->si_code);
+ VG_(dmsg)("async signal handler: signal=%d, tid=%d, si_code=%d\n",
+ sigNo, tid, info->si_code);
/* Update thread state properly. The signal can only have been
delivered whilst we were in
@@ -2105,7 +2112,8 @@
get here unless the client wants this signal right now. This means
we can simply use the async_signalhandler. */
if (VG_(clo_trace_signals))
- VG_DMSG("Delivering user-sent sync signal %d as async signal", sigNo);
+ VG_(dmsg)("Delivering user-sent sync signal %d as async signal\n",
+ sigNo);
async_signalhandler(sigNo, info, uc);
VG_(core_panic)("async_signalhandler returned!?\n");
@@ -2116,7 +2124,7 @@
unblocked, so we can't rely on the kernel to route them properly, so
we need to queue them manually. */
if (VG_(clo_trace_signals))
- VG_DMSG("Routing user-sent sync signal %d via queue", sigNo);
+ VG_(dmsg)("Routing user-sent sync signal %d via queue\n", sigNo);
# if defined(VGO_linux)
/* On Linux, first we have to do a sanity check of the siginfo. */
@@ -2132,8 +2140,8 @@
Since we depend on siginfo to work out why we were sent a
signal and what we should do about it, we really can't
continue unless we get it. */
- VG_UMSG("Signal %d (%s) appears to have lost its siginfo; "
- "I can't go on.", sigNo, signame(sigNo));
+ VG_(umsg)("Signal %d (%s) appears to have lost its siginfo; "
+ "I can't go on.\n", sigNo, signame(sigNo));
VG_(printf)(
" This may be because one of your programs has consumed your ration of\n"
" siginfo structures. For more information, see:\n"
@@ -2184,13 +2192,13 @@
if (VG_(clo_trace_signals)) {
if (seg == NULL)
- VG_DMSG("SIGSEGV: si_code=%d faultaddr=%#lx tid=%d ESP=%#lx "
- "seg=NULL",
- info->si_code, fault, tid, esp);
+ VG_(dmsg)("SIGSEGV: si_code=%d faultaddr=%#lx tid=%d ESP=%#lx "
+ "seg=NULL\n",
+ info->si_code, fault, tid, esp);
else
- VG_DMSG("SIGSEGV: si_code=%d faultaddr=%#lx tid=%d ESP=%#lx "
- "seg=%#lx-%#lx",
- info->si_code, fault, tid, esp, seg->start, seg->end);
+ VG_(dmsg)("SIGSEGV: si_code=%d faultaddr=%#lx tid=%d ESP=%#lx "
+ "seg=%#lx-%#lx\n",
+ info->si_code, fault, tid, esp, seg->start, seg->end);
}
if (info->si_code == VKI_SEGV_MAPERR
@@ -2209,12 +2217,12 @@
Addr base = VG_PGROUNDDN(esp - VG_STACK_REDZONE_SZB);
if (VG_(extend_stack)(base, VG_(threads)[tid].client_stack_szB)) {
if (VG_(clo_trace_signals))
- VG_DMSG(" -> extended stack base to %#lx",
- VG_PGROUNDDN(fault));
+ VG_(dmsg)(" -> extended stack base to %#lx\n",
+ VG_PGROUNDDN(fault));
return True;
} else {
- VG_UMSG("Stack overflow in thread %d: can't grow stack to %#lx",
- tid, fault);
+ VG_(umsg)("Stack overflow in thread %d: can't grow stack to %#lx\n",
+ tid, fault);
return False;
}
} else {
@@ -2265,13 +2273,13 @@
client code, and therefore it was actually generated by
Valgrind internally.
*/
- VG_DMSG("VALGRIND INTERNAL ERROR: Valgrind received "
- "a signal %d (%s) - exiting",
- sigNo, signame(sigNo));
+ VG_(dmsg)("VALGRIND INTERNAL ERROR: Valgrind received "
+ "a signal %d (%s) - exiting\n",
+ sigNo, signame(sigNo));
- VG_DMSG("si_code=%x; Faulting address: %p; sp: %#lx",
- info->si_code, info->VKI_SIGINFO_si_addr,
- VG_UCONTEXT_STACK_PTR(uc));
+ VG_(dmsg)("si_code=%x; Faulting address: %p; sp: %#lx\n",
+ info->si_code, info->VKI_SIGINFO_si_addr,
+ VG_UCONTEXT_STACK_PTR(uc));
if (0)
VG_(kill_self)(sigNo); /* generate a core dump */
@@ -2314,11 +2322,11 @@
from_user = !is_signal_from_kernel(tid, sigNo, info->si_code);
if (VG_(clo_trace_signals)) {
- VG_DMSG("sync signal handler: "
- "signal=%d, si_code=%d, EIP=%#lx, eip=%#lx, from %s",
- sigNo, info->si_code, VG_(get_IP)(tid),
- VG_UCONTEXT_INSTR_PTR(uc),
- ( from_user ? "user" : "kernel" ));
+ VG_(dmsg)("sync signal handler: "
+ "signal=%d, si_code=%d, EIP=%#lx, eip=%#lx, from %s\n",
+ sigNo, info->si_code, VG_(get_IP)(tid),
+ VG_UCONTEXT_INSTR_PTR(uc),
+ ( from_user ? "user" : "kernel" ));
}
vg_assert(sigNo >= 1 && sigNo <= VG_(max_signal));
@@ -2358,7 +2366,7 @@
ThreadStatus at_signal = VG_(threads)[tid].status;
if (VG_(clo_trace_signals))
- VG_DMSG("sigvgkill for lwp %d tid %d", VG_(gettid)(), tid);
+ VG_(dmsg)("sigvgkill for lwp %d tid %d\n", VG_(gettid)(), tid);
VG_(acquire_BigLock)(tid, "sigvgkill_handler");
@@ -2448,19 +2456,19 @@
/* If there was nothing queued, ask the kernel for a pending signal */
if (sip == NULL && VG_(sigtimedwait_zero)(&pollset, &si) > 0) {
if (VG_(clo_trace_signals))
- VG_DMSG("poll_signals: got signal %d for thread %d",
- si.si_signo, tid);
+ VG_(dmsg)("poll_signals: got signal %d for thread %d\n",
+ si.si_signo, tid);
sip = &si;
}
if (sip != NULL) {
/* OK, something to do; deliver it */
if (VG_(clo_trace_signals))
- VG_DMSG("Polling found signal %d for tid %d", sip->si_signo, tid);
+ VG_(dmsg)("Polling found signal %d for tid %d\n", sip->si_signo, tid);
if (!is_sig_ign(sip->si_signo))
deliver_signal(tid, sip, NULL);
else if (VG_(clo_trace_signals))
- VG_DMSG(" signal %d ignored", sip->si_signo);
+ VG_(dmsg)(" signal %d ignored\n", sip->si_signo);
sip->si_signo = 0; /* remove from signal queue, if that's
where it came from */
@@ -2560,7 +2568,7 @@
}
if (VG_(clo_trace_signals))
- VG_DMSG("Max kernel-supported signal is %d", VG_(max_signal));
+ VG_(dmsg)("Max kernel-supported signal is %d\n", VG_(max_signal));
/* Our private internal signals are treated as ignored */
scss.scss_per_sig[VG_SIGVGKILL].scss_handler = VKI_SIG_IGN;
diff --git a/coregrind/m_stacks.c b/coregrind/m_stacks.c
index db16239..c9e9abf 100644
--- a/coregrind/m_stacks.c
+++ b/coregrind/m_stacks.c
@@ -305,14 +305,14 @@
moans--;
VG_(message)(Vg_UserMsg,
"Warning: client switching stacks? "
- "SP change: 0x%lx --> 0x%lx", old_SP, new_SP);
+ "SP change: 0x%lx --> 0x%lx\n", old_SP, new_SP);
VG_(message)(Vg_UserMsg,
- " to suppress, use: --max-stackframe=%ld or greater",
+ " to suppress, use: --max-stackframe=%ld or greater\n",
(delta < 0 ? -delta : delta));
if (moans == 0)
VG_(message)(Vg_UserMsg,
" further instances of this message "
- "will not be shown.");
+ "will not be shown.\n");
}
} else if (delta < 0) {
VG_TRACK( new_mem_stack_w_ECU, new_SP, -delta, ecu );
diff --git a/coregrind/m_stacktrace.c b/coregrind/m_stacktrace.c
index 6e3c8d0..130107a 100644
--- a/coregrind/m_stacktrace.c
+++ b/coregrind/m_stacktrace.c
@@ -523,9 +523,9 @@
VG_(describe_IP)(ip, buf, BUF_LEN);
if (VG_(clo_xml)) {
- VG_(message)(Vg_UserMsg, " %s", buf);
+ VG_(printf_xml)(" %s\n", buf);
} else {
- VG_(message)(Vg_UserMsg, " %s %s", ( n == 0 ? "at" : "by" ), buf);
+ VG_(message)(Vg_UserMsg, " %s %s\n", ( n == 0 ? "at" : "by" ), buf);
}
}
@@ -535,12 +535,12 @@
vg_assert( n_ips > 0 );
if (VG_(clo_xml))
- VG_(message)(Vg_UserMsg, " <stack>");
+ VG_(printf_xml)(" <stack>\n");
VG_(apply_StackTrace)( printIpDesc, ips, n_ips );
if (VG_(clo_xml))
- VG_(message)(Vg_UserMsg, " </stack>");
+ VG_(printf_xml)(" </stack>\n");
}
/* Get and immediately print a StackTrace. */
diff --git a/coregrind/m_syswrap/syswrap-aix5.c b/coregrind/m_syswrap/syswrap-aix5.c
index 90e966e..6108cce 100644
--- a/coregrind/m_syswrap/syswrap-aix5.c
+++ b/coregrind/m_syswrap/syswrap-aix5.c
@@ -219,9 +219,9 @@
tst->os_state.exitcode = 1;
if (!VG_(clo_xml)) {
VG_(message)(Vg_UserMsg,
- "WARNING: AIX: %s", why);
+ "WARNING: AIX: %s\n", why);
VG_(message)(Vg_UserMsg,
- "WARNING: (too difficult to continue past this point).");
+ "WARNING: (too difficult to continue past this point).\n");
VG_(get_and_pp_StackTrace)(tid, 10);
}
}
@@ -1044,12 +1044,12 @@
too much of a mess to continue, so we have to abort. */
hosed:
vg_assert(FAILURE);
- VG_(message)(Vg_UserMsg, "execve(%#lx(%s), %#lx, %#lx) failed, errno %ld",
+ VG_(message)(Vg_UserMsg, "execve(%#lx(%s), %#lx, %#lx) failed, errno %ld\n",
ARG1, (Char*)ARG1, ARG2, ARG3, ERR);
VG_(message)(Vg_UserMsg, "EXEC FAILED: I can't recover from "
- "execve() failing, so I'm dying.");
+ "execve() failing, so I'm dying.\n");
VG_(message)(Vg_UserMsg, "Add more stringent tests in PRE(sys_execve), "
- "or work out how to recover.");
+ "or work out how to recover.\n");
VG_(exit)(101);
}
@@ -1435,14 +1435,14 @@
moans--;
VG_(message)(Vg_UserMsg,
"Warning: noted but unhandled ioctl 0x%lx"
- " with no size/direction hints",
+ " with no size/direction hints\n",
ARG2);
VG_(message)(Vg_UserMsg,
" This could cause spurious value errors"
- " to appear.");
+ " to appear.\n");
VG_(message)(Vg_UserMsg,
" See README_MISSING_SYSCALL_OR_IOCTL for "
- "guidance on writing a proper wrapper." );
+ "guidance on writing a proper wrapper.\n" );
}
} else {
if ((dir & _VKI_IOC_WRITE) && size > 0)
diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c
index 0f1a6ae..605d844 100644
--- a/coregrind/m_syswrap/syswrap-amd64-linux.c
+++ b/coregrind/m_syswrap/syswrap-amd64-linux.c
@@ -267,7 +267,8 @@
VG_(printf)("tid %d: guessed client stack range %#lx-%#lx\n",
ctid, seg->start, VG_PGROUNDUP(rsp));
} else {
- VG_(message)(Vg_UserMsg, "!? New thread %d starts with RSP(%#lx) unmapped\n",
+ VG_(message)(Vg_UserMsg,
+ "!? New thread %d starts with RSP(%#lx) unmapped\n",
ctid, rsp);
ctst->client_stack_szB = 0;
}
@@ -440,11 +441,16 @@
default:
/* should we just ENOSYS? */
- VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx", ARG1);
- VG_(message)(Vg_UserMsg, "");
- VG_(message)(Vg_UserMsg, "The only supported clone() uses are:");
- VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)");
- VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork");
+ VG_(message)(Vg_UserMsg,
+ "Unsupported clone() flags: 0x%lx\n", ARG1);
+ VG_(message)(Vg_UserMsg,
+ "\n");
+ VG_(message)(Vg_UserMsg,
+ "The only supported clone() uses are:\n");
+ VG_(message)(Vg_UserMsg,
+ " - via a threads library (LinuxThreads or NPTL)\n");
+ VG_(message)(Vg_UserMsg,
+ " - via the implementation of fork or vfork\n");
VG_(unimplemented)
("Valgrind does not support general clone().");
}
diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c
index a1fb344..6332859 100644
--- a/coregrind/m_syswrap/syswrap-generic.c
+++ b/coregrind/m_syswrap/syswrap-generic.c
@@ -84,7 +84,7 @@
if (!ret && syscallname != NULL) {
VG_(message)(Vg_UserMsg, "Warning: client syscall %s tried "
- "to modify addresses %#lx-%#lx",
+ "to modify addresses %#lx-%#lx\n",
syscallname, start, start+size-1);
if (VG_(clo_verbosity) > 1) {
VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
@@ -671,30 +671,30 @@
struct vki_sockaddr_in paddr;
UInt plen = sizeof(struct vki_sockaddr_in);
- if(VG_(getpeername)(fd, (struct vki_sockaddr *)&paddr, &plen) != -1) {
- VG_(message)(Vg_UserMsg, "Open AF_INET socket %d: %s <-> %s", fd,
+ if (VG_(getpeername)(fd, (struct vki_sockaddr *)&paddr, &plen) != -1) {
+ VG_(message)(Vg_UserMsg, "Open AF_INET socket %d: %s <-> %s\n", fd,
inet2name(&(laddr.in), llen, lname),
inet2name(&paddr, plen, pname));
} else {
- VG_(message)(Vg_UserMsg, "Open AF_INET socket %d: %s <-> unbound",
+ VG_(message)(Vg_UserMsg, "Open AF_INET socket %d: %s <-> unbound\n",
fd, inet2name(&(laddr.in), llen, lname));
}
return;
}
case VKI_AF_UNIX: {
static char lname[256];
- VG_(message)(Vg_UserMsg, "Open AF_UNIX socket %d: %s", fd,
+ VG_(message)(Vg_UserMsg, "Open AF_UNIX socket %d: %s\n", fd,
unix2name(&(laddr.un), llen, lname));
return;
}
default:
- VG_(message)(Vg_UserMsg, "Open pf-%d socket %d:",
+ VG_(message)(Vg_UserMsg, "Open pf-%d socket %d:\n",
laddr.a.sa_family, fd);
return;
}
}
- VG_(message)(Vg_UserMsg, "Open socket %d:", fd);
+ VG_(message)(Vg_UserMsg, "Open socket %d:\n", fd);
}
@@ -703,18 +703,19 @@
{
OpenFd *i = allocated_fds;
- VG_(message)(Vg_UserMsg, "FILE DESCRIPTORS: %d open at exit.", fd_count);
+ VG_(message)(Vg_UserMsg, "FILE DESCRIPTORS: %d open at exit.\n", fd_count);
- while(i) {
- if(i->pathname) {
- VG_(message)(Vg_UserMsg, "Open file descriptor %d: %s", i->fd,
+ while (i) {
+ if (i->pathname) {
+ VG_(message)(Vg_UserMsg, "Open file descriptor %d: %s\n", i->fd,
i->pathname);
} else {
Int val;
UInt len = sizeof(val);
- if (VG_(getsockopt)(i->fd, VKI_SOL_SOCKET, VKI_SO_TYPE, &val, &len) == -1) {
- VG_(message)(Vg_UserMsg, "Open file descriptor %d:", i->fd);
+ if (VG_(getsockopt)(i->fd, VKI_SOL_SOCKET, VKI_SO_TYPE, &val, &len)
+ == -1) {
+ VG_(message)(Vg_UserMsg, "Open file descriptor %d:\n", i->fd);
} else {
getsockdetails(i->fd);
}
@@ -722,16 +723,16 @@
if(i->where) {
VG_(pp_ExeContext)(i->where);
- VG_(message)(Vg_UserMsg, "");
+ VG_(message)(Vg_UserMsg, "\n");
} else {
- VG_(message)(Vg_UserMsg, " <inherited from parent>");
- VG_(message)(Vg_UserMsg, "");
+ VG_(message)(Vg_UserMsg, " <inherited from parent>\n");
+ VG_(message)(Vg_UserMsg, "\n");
}
i = i->next;
}
- VG_(message)(Vg_UserMsg, "");
+ VG_(message)(Vg_UserMsg, "\n");
}
/* If /proc/self/fd doesn't exist (e.g. you've got a Linux kernel that doesn't
@@ -790,7 +791,8 @@
ML_(record_fd_open_named)(-1, fno);
} else {
VG_(message)(Vg_DebugMsg,
- "Warning: invalid file name in /proc/self/fd: %s", d.d_name);
+ "Warning: invalid file name in /proc/self/fd: %s\n",
+ d.d_name);
}
}
@@ -1154,8 +1156,8 @@
if (fd < 0 || fd >= VG_(fd_hard_limit))
allowed = False;
- /* hijacking the logging fd is never allowed */
- if (fd == VG_(clo_log_fd))
+ /* hijacking the output fds is never allowed */
+ if (fd == VG_(log_output_sink).fd || fd == VG_(xml_output_sink).fd)
allowed = False;
/* if creating a new fd (rather than using an existing one), the
@@ -1184,12 +1186,15 @@
/* croak? */
if ((!allowed) && VG_(showing_core_errors)() ) {
VG_(message)(Vg_UserMsg,
- "Warning: invalid file descriptor %d in syscall %s()",
+ "Warning: invalid file descriptor %d in syscall %s()\n",
fd, syscallname);
- if (fd == VG_(clo_log_fd)) {
+ if (fd == VG_(log_output_sink).fd && VG_(log_output_sink).fd >= 0)
VG_(message)(Vg_UserMsg,
- " Use --log-fd=<number> to select an alternative log fd.");
- }
+ " Use --log-fd=<number> to select an alternative log fd.\n");
+ if (fd == VG_(xml_output_sink).fd && VG_(xml_output_sink).fd >= 0)
+ VG_(message)(Vg_UserMsg,
+ " Use --xml-fd=<number> to select an alternative XML "
+ "output fd.\n");
// DDD: consider always printing this stack trace, it's useful.
// Also consider also making this a proper core error, ie.
// suppressible and all that.
@@ -2700,12 +2705,12 @@
too much of a mess to continue, so we have to abort. */
hosed:
vg_assert(FAILURE);
- VG_(message)(Vg_UserMsg, "execve(%#lx(%s), %#lx, %#lx) failed, errno %ld",
+ VG_(message)(Vg_UserMsg, "execve(%#lx(%s), %#lx, %#lx) failed, errno %ld\n",
ARG1, (char*)ARG1, ARG2, ARG3, ERR);
VG_(message)(Vg_UserMsg, "EXEC FAILED: I can't recover from "
- "execve() failing, so I'm dying.");
+ "execve() failing, so I'm dying.\n");
VG_(message)(Vg_UserMsg, "Add more stringent tests in PRE(sys_execve), "
- "or work out how to recover.");
+ "or work out how to recover.\n");
VG_(exit)(101);
}
@@ -2921,11 +2926,15 @@
VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
/* If --child-silent-after-fork=yes was specified, set the
- logging file descriptor to an 'impossible' value. This is
+ output file descriptors to 'impossible' values. This is
noticed by send_bytes_to_logging_sink in m_libcprint.c, which
- duly stops writing any further logging output. */
- if (!VG_(logging_to_socket) && VG_(clo_child_silent_after_fork))
- VG_(clo_log_fd) = -1;
+ duly stops writing any further output. */
+ if (VG_(clo_child_silent_after_fork)) {
+ if (!VG_(log_output_sink).is_socket)
+ VG_(log_output_sink).fd = -1;
+ if (!VG_(xml_output_sink).is_socket)
+ VG_(xml_output_sink).fd = -1;
+ }
} else {
VG_(do_atfork_parent)(tid);
@@ -3231,11 +3240,11 @@
static Int moans = 3;
if (moans > 0 && !VG_(clo_xml)) {
moans--;
- VG_UMSG("Warning: noted but unhandled ioctl 0x%lx"
- " with no size/direction hints", request);
- VG_UMSG(" This could cause spurious value errors to appear.");
- VG_UMSG(" See README_MISSING_SYSCALL_OR_IOCTL for "
- "guidance on writing a proper wrapper." );
+ VG_(umsg)("Warning: noted but unhandled ioctl 0x%lx"
+ " with no size/direction hints\n", request);
+ VG_(umsg)(" This could cause spurious value errors to appear.\n");
+ VG_(umsg)(" See README_MISSING_SYSCALL_OR_IOCTL for "
+ "guidance on writing a proper wrapper.\n" );
}
} else {
//VG_(message)(Vg_UserMsg, "UNKNOWN ioctl %#lx\n", request);
@@ -3306,8 +3315,9 @@
/* Check to see that the target isn't already exiting. */
if (!VG_(is_exiting)(tid)) {
if (VG_(clo_trace_signals))
- VG_(message)(Vg_DebugMsg, "Thread %d being killed with SIGKILL",
- tst->tid);
+ VG_(message)(Vg_DebugMsg,
+ "Thread %d being killed with SIGKILL\n",
+ tst->tid);
tst->exitreason = VgSrc_FatalSig;
tst->os_state.fatalsig = VKI_SIGKILL;
@@ -3340,7 +3350,7 @@
SET_STATUS_from_SysRes( VG_(do_syscall3)(SYSNO, ARG1, ARG2, ARG3) );
if (VG_(clo_trace_signals))
- VG_(message)(Vg_DebugMsg, "kill: sent signal %ld to pid %ld",
+ VG_(message)(Vg_DebugMsg, "kill: sent signal %ld to pid %ld\n",
ARG2, ARG1);
/* This kill might have given us a pending signal. Ask for a check once
diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
index 32a68f7..df61d5a 100644
--- a/coregrind/m_syswrap/syswrap-linux.c
+++ b/coregrind/m_syswrap/syswrap-linux.c
@@ -341,11 +341,15 @@
VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
/* If --child-silent-after-fork=yes was specified, set the
- logging file descriptor to an 'impossible' value. This is
+ output file descriptors to 'impossible' values. This is
noticed by send_bytes_to_logging_sink in m_libcprint.c, which
- duly stops writing any further logging output. */
- if (!VG_(logging_to_socket) && VG_(clo_child_silent_after_fork))
- VG_(clo_log_fd) = -1;
+ duly stops writing any further output. */
+ if (VG_(clo_child_silent_after_fork)) {
+ if (!VG_(log_output_sink).is_socket)
+ VG_(log_output_sink).fd = -1;
+ if (!VG_(xml_output_sink).is_socket)
+ VG_(xml_output_sink).fd = -1;
+ }
}
else
if (!sr_isError(res) && sr_Res(res) > 0) {
@@ -1188,7 +1192,7 @@
*flags |= SfPollAfter;
if (VG_(clo_trace_signals))
- VG_(message)(Vg_DebugMsg, "tkill: sending signal %ld to pid %ld",
+ VG_(message)(Vg_DebugMsg, "tkill: sending signal %ld to pid %ld\n",
ARG2, ARG1);
/* If we're sending SIGKILL, check to see if the target is one of
@@ -1212,7 +1216,7 @@
POST(sys_tkill)
{
if (VG_(clo_trace_signals))
- VG_(message)(Vg_DebugMsg, "tkill: sent signal %ld to pid %ld",
+ VG_(message)(Vg_DebugMsg, "tkill: sent signal %ld to pid %ld\n",
ARG2, ARG1);
}
@@ -1229,7 +1233,8 @@
*flags |= SfPollAfter;
if (VG_(clo_trace_signals))
- VG_(message)(Vg_DebugMsg, "tgkill: sending signal %ld to pid %ld/%ld",
+ VG_(message)(Vg_DebugMsg,
+ "tgkill: sending signal %ld to pid %ld/%ld\n",
ARG3, ARG1, ARG2);
/* If we're sending SIGKILL, check to see if the target is one of
@@ -1253,7 +1258,8 @@
POST(sys_tgkill)
{
if (VG_(clo_trace_signals))
- VG_(message)(Vg_DebugMsg, "tgkill: sent signal %ld to pid %ld/%ld",
+ VG_(message)(Vg_DebugMsg,
+ "tgkill: sent signal %ld to pid %ld/%ld\n",
ARG3, ARG1, ARG2);
}
@@ -5297,7 +5303,8 @@
else if (a->sa_family == VKI_AF_INET6)
sl = sizeof(struct vki_sockaddr_in6);
else {
- VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled address type %d", a->sa_family);
+ VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled "
+ "address type %d\n", a->sa_family);
}
a = (struct vki_sockaddr*)((char*)a + sl);
}
diff --git a/coregrind/m_syswrap/syswrap-main.c b/coregrind/m_syswrap/syswrap-main.c
index 5b8fc70..4cc9011 100644
--- a/coregrind/m_syswrap/syswrap-main.c
+++ b/coregrind/m_syswrap/syswrap-main.c
@@ -1096,15 +1096,15 @@
/*OUT*/SyscallStatus* status,
/*OUT*/UWord* flags )
{
- VG_DMSG("WARNING: unhandled syscall: %s",
+ VG_(dmsg)("WARNING: unhandled syscall: %s\n",
VG_SYSNUM_STRING_EXTRA(args->sysno));
if (VG_(clo_verbosity) > 1) {
VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
}
- VG_DMSG("You may be able to write your own handler.");
- VG_DMSG("Read the file README_MISSING_SYSCALL_OR_IOCTL.");
- VG_DMSG("Nevertheless we consider this a bug. Please report");
- VG_DMSG("it at http://valgrind.org/support/bug_reports.html.");
+ VG_(dmsg)("You may be able to write your own handler.\n");
+ VG_(dmsg)("Read the file README_MISSING_SYSCALL_OR_IOCTL.\n");
+ VG_(dmsg)("Nevertheless we consider this a bug. Please report\n");
+ VG_(dmsg)("it at http://valgrind.org/support/bug_reports.html.\n");
SET_STATUS_Failure(VKI_ENOSYS);
}
diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c
index a9e7095..d56eda5 100644
--- a/coregrind/m_syswrap/syswrap-ppc32-linux.c
+++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c
@@ -313,7 +313,8 @@
VG_(printf)("\ntid %d: guessed client stack range %#lx-%#lx\n",
ctid, seg->start, VG_PGROUNDUP(sp));
} else {
- VG_(message)(Vg_UserMsg, "!? New thread %d starts with R1(%#lx) unmapped\n",
+ VG_(message)(Vg_UserMsg,
+ "!? New thread %d starts with R1(%#lx) unmapped\n",
ctid, sp);
ctst->client_stack_szB = 0;
}
@@ -553,7 +554,7 @@
}
default:
- VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx",ARG1);
+ VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
SET_STATUS_Failure( VKI_EINVAL );
break;
}
@@ -656,7 +657,7 @@
break;
default:
- VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx",ARG1);
+ VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
VG_(core_panic)("... bye!\n");
break; /*NOTREACHED*/
}
@@ -843,7 +844,7 @@
ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
break;
default:
- VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %ld", ARG1 );
+ VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %ld\n", ARG1 );
VG_(core_panic)("... bye!\n");
break; /*NOTREACHED*/
}
@@ -908,7 +909,7 @@
break;
default:
VG_(message)(Vg_DebugMsg,
- "FATAL: unhandled syscall(ipc) %ld",
+ "FATAL: unhandled syscall(ipc) %ld\n",
ARG1 );
VG_(core_panic)("... bye!\n");
break; /*NOTREACHED*/
@@ -1015,11 +1016,11 @@
default:
/* should we just ENOSYS? */
- VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx", ARG1);
- VG_(message)(Vg_UserMsg, "");
- VG_(message)(Vg_UserMsg, "The only supported clone() uses are:");
- VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)");
- VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork");
+ VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1);
+ VG_(message)(Vg_UserMsg, "\n");
+ VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
+ VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
+ VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
VG_(unimplemented)
("Valgrind does not support general clone().");
}
diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c
index 1ce4f64..a19b3f4 100644
--- a/coregrind/m_syswrap/syswrap-ppc64-linux.c
+++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c
@@ -341,7 +341,8 @@
VG_(printf)("\ntid %d: guessed client stack range %#lx-%#lx\n",
ctid, seg->start, VG_PGROUNDUP(sp));
} else {
- VG_(message)(Vg_UserMsg, "!? New thread %d starts with R1(%#lx) unmapped\n",
+ VG_(message)(Vg_UserMsg,
+ "!? New thread %d starts with R1(%#lx) unmapped\n",
ctid, sp);
ctst->client_stack_szB = 0;
}
@@ -580,7 +581,7 @@
}
default:
- VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx",ARG1);
+ VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
SET_STATUS_Failure( VKI_EINVAL );
break;
}
@@ -683,7 +684,7 @@
break;
default:
- VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx",ARG1);
+ VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
VG_(core_panic)("... bye!\n");
break; /*NOTREACHED*/
}
@@ -856,7 +857,7 @@
ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
break;
default:
- VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %ld", ARG1 );
+ VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %ld\n", ARG1 );
VG_(core_panic)("... bye!\n");
break; /*NOTREACHED*/
}
@@ -921,7 +922,7 @@
break;
default:
VG_(message)(Vg_DebugMsg,
- "FATAL: unhandled syscall(ipc) %ld",
+ "FATAL: unhandled syscall(ipc) %ld\n",
ARG1 );
VG_(core_panic)("... bye!\n");
break; /*NOTREACHED*/
@@ -992,11 +993,11 @@
default:
/* should we just ENOSYS? */
- VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx", ARG1);
- VG_(message)(Vg_UserMsg, "");
- VG_(message)(Vg_UserMsg, "The only supported clone() uses are:");
- VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)");
- VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork");
+ VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1);
+ VG_(message)(Vg_UserMsg, "\n");
+ VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
+ VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
+ VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
VG_(unimplemented)
("Valgrind does not support general clone().");
}
diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c
index 60a052c..601ff94 100644
--- a/coregrind/m_syswrap/syswrap-x86-linux.c
+++ b/coregrind/m_syswrap/syswrap-x86-linux.c
@@ -278,7 +278,8 @@
VG_(printf)("tid %d: guessed client stack range %#lx-%#lx\n",
ctid, seg->start, VG_PGROUNDUP(esp));
} else {
- VG_(message)(Vg_UserMsg, "!? New thread %d starts with ESP(%#lx) unmapped\n",
+ VG_(message)(Vg_UserMsg,
+ "!? New thread %d starts with ESP(%#lx) unmapped\n",
ctid, esp);
ctst->client_stack_szB = 0;
}
@@ -930,13 +931,13 @@
default:
reject:
/* should we just ENOSYS? */
- VG_(message)(Vg_UserMsg, "");
- VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx", ARG1);
- VG_(message)(Vg_UserMsg, "");
- VG_(message)(Vg_UserMsg, "The only supported clone() uses are:");
- VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)");
- VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork");
- VG_(message)(Vg_UserMsg, " - for the Quadrics Elan3 user-space driver");
+ VG_(message)(Vg_UserMsg, "\n");
+ VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1);
+ VG_(message)(Vg_UserMsg, "\n");
+ VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
+ VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
+ VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
+ VG_(message)(Vg_UserMsg, " - for the Quadrics Elan3 user-space driver\n");
VG_(unimplemented)
("Valgrind does not support general clone().");
}
@@ -1235,7 +1236,7 @@
ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
break;
default:
- VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %ld", ARG1 );
+ VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %ld\n", ARG1 );
VG_(core_panic)("... bye!\n");
break; /*NOTREACHED*/
}
@@ -1300,7 +1301,7 @@
break;
default:
VG_(message)(Vg_DebugMsg,
- "FATAL: unhandled syscall(ipc) %ld",
+ "FATAL: unhandled syscall(ipc) %ld\n",
ARG1 );
VG_(core_panic)("... bye!\n");
break; /*NOTREACHED*/
@@ -1562,7 +1563,7 @@
}
default:
- VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx",ARG1);
+ VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
SET_STATUS_Failure( VKI_EINVAL );
break;
}
@@ -1665,7 +1666,7 @@
break;
default:
- VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx",ARG1);
+ VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
VG_(core_panic)("... bye!\n");
break; /*NOTREACHED*/
}
diff --git a/coregrind/m_tooliface.c b/coregrind/m_tooliface.c
index 4ed966d..e6d1652 100644
--- a/coregrind/m_tooliface.c
+++ b/coregrind/m_tooliface.c
@@ -214,7 +214,6 @@
NEEDS(libc_freeres)
NEEDS(core_errors)
NEEDS(var_info)
-NEEDS(xml_output)
void VG_(needs_superblock_discards)(
void (*discard)(Addr64, VexGuestExtents)
@@ -226,6 +225,7 @@
void VG_(needs_tool_errors)(
Bool (*eq) (VgRes, Error*, Error*),
+ void (*before_pp) (Error*),
void (*pp) (Error*),
Bool show_TIDs,
UInt (*update) (Error*),
@@ -238,6 +238,7 @@
{
VG_(needs).tool_errors = True;
VG_(tdict).tool_eq_Error = eq;
+ VG_(tdict).tool_before_pp_Error = before_pp;
VG_(tdict).tool_pp_Error = pp;
VG_(tdict).tool_show_ThreadIDs_for_errors = show_TIDs;
VG_(tdict).tool_update_extra = update;
@@ -316,6 +317,11 @@
VG_(tdict).tool_client_redzone_szB = client_malloc_redzone_szB;
}
+void VG_(needs_xml_output)( void )
+{
+ VG_(needs).xml_output = True;
+}
+
void VG_(needs_final_IR_tidy_pass)(
IRSB*(*final_tidy)(IRSB*)
)
diff --git a/coregrind/m_translate.c b/coregrind/m_translate.c
index 1e1f049..8ff300f 100644
--- a/coregrind/m_translate.c
+++ b/coregrind/m_translate.c
@@ -74,17 +74,17 @@
+ n_SP_updates_generic_unknown;
VG_(percentify)(n_SP_updates_fast, n_SP_updates, 1, 6, buf);
VG_(message)(Vg_DebugMsg,
- "translate: fast SP updates identified: %'u (%s)",
+ "translate: fast SP updates identified: %'u (%s)\n",
n_SP_updates_fast, buf );
VG_(percentify)(n_SP_updates_generic_known, n_SP_updates, 1, 6, buf);
VG_(message)(Vg_DebugMsg,
- "translate: generic_known SP updates identified: %'u (%s)",
+ "translate: generic_known SP updates identified: %'u (%s)\n",
n_SP_updates_generic_known, buf );
VG_(percentify)(n_SP_updates_generic_unknown, n_SP_updates, 1, 6, buf);
VG_(message)(Vg_DebugMsg,
- "translate: generic_unknown SP updates identified: %'u (%s)",
+ "translate: generic_unknown SP updates identified: %'u (%s)\n",
n_SP_updates_generic_unknown, buf );
}
@@ -1320,7 +1320,7 @@
ok = VG_(get_fnname_w_offset)(addr, name2, 64);
if (!ok) VG_(strcpy)(name2, "???");
VG_(message)(Vg_DebugMsg,
- "REDIR: 0x%llx (%s) redirected to 0x%llx (%s)",
+ "REDIR: 0x%llx (%s) redirected to 0x%llx (%s)\n",
nraddr, name1,
addr, name2 );
}
@@ -1357,7 +1357,7 @@
|| addr == TRANSTAB_BOGUS_GUEST_ADDR ) {
if (VG_(clo_trace_signals))
VG_(message)(Vg_DebugMsg, "translations not allowed here (0x%llx)"
- " - throwing SEGV", addr);
+ " - throwing SEGV\n", addr);
/* U R busted, sonny. Place your hands on your head and step
away from the orig_addr. */
/* Code address is bad - deliver a signal instead */
diff --git a/coregrind/m_transtab.c b/coregrind/m_transtab.c
index a224b48..c8954eb 100644
--- a/coregrind/m_transtab.c
+++ b/coregrind/m_transtab.c
@@ -736,7 +736,7 @@
}
if (VG_(clo_verbosity) > 2)
- VG_(message)(Vg_DebugMsg, "TT/TC: initialise sector %d", sno);
+ VG_(message)(Vg_DebugMsg, "TT/TC: initialise sector %d\n", sno);
} else {
@@ -780,7 +780,7 @@
}
if (VG_(clo_verbosity) > 2)
- VG_(message)(Vg_DebugMsg, "TT/TC: recycle sector %d", sno);
+ VG_(message)(Vg_DebugMsg, "TT/TC: recycle sector %d\n", sno);
}
sec->tc_next = sec->tc;
@@ -1459,7 +1459,7 @@
if (VG_(clo_verbosity) > 2)
VG_(message)(Vg_DebugMsg,
"TT/TC: VG_(init_tt_tc) "
- "(startup of code management)");
+ "(startup of code management)\n");
/* Figure out how big each tc area should be. */
avg_codeszQ = (VG_(details).avg_translation_sizeB + 7) / 8;
@@ -1495,11 +1495,11 @@
if (VG_(clo_verbosity) > 2) {
VG_(message)(Vg_DebugMsg,
- "TT/TC: cache: %d sectors of %d bytes each = %d total",
+ "TT/TC: cache: %d sectors of %d bytes each = %d total\n",
N_SECTORS, 8 * tc_sector_szQ,
N_SECTORS * 8 * tc_sector_szQ );
VG_(message)(Vg_DebugMsg,
- "TT/TC: table: %d total entries, max occupancy %d (%d%%)",
+ "TT/TC: table: %d total entries, max occupancy %d (%d%%)\n",
N_SECTORS * N_TTES_PER_SECTOR,
N_SECTORS * N_TTES_PER_SECTOR_USABLE,
SECTOR_TT_LIMIT_PERCENT );
@@ -1534,23 +1534,23 @@
void VG_(print_tt_tc_stats) ( void )
{
VG_(message)(Vg_DebugMsg,
- " tt/tc: %'llu tt lookups requiring %'llu probes",
+ " tt/tc: %'llu tt lookups requiring %'llu probes\n",
n_full_lookups, n_lookup_probes );
VG_(message)(Vg_DebugMsg,
- " tt/tc: %'llu fast-cache updates, %'llu flushes",
+ " tt/tc: %'llu fast-cache updates, %'llu flushes\n",
n_fast_updates, n_fast_flushes );
VG_(message)(Vg_DebugMsg,
" transtab: new %'lld "
- "(%'llu -> %'llu; ratio %'llu:10) [%'llu scs]",
+ "(%'llu -> %'llu; ratio %'llu:10) [%'llu scs]\n",
n_in_count, n_in_osize, n_in_tsize,
safe_idiv(10*n_in_tsize, n_in_osize),
n_in_sc_count);
VG_(message)(Vg_DebugMsg,
- " transtab: dumped %'llu (%'llu -> ?" "?)",
+ " transtab: dumped %'llu (%'llu -> ?" "?)\n",
n_dump_count, n_dump_osize );
VG_(message)(Vg_DebugMsg,
- " transtab: discarded %'llu (%'llu -> ?" "?)",
+ " transtab: discarded %'llu (%'llu -> ?" "?)\n",
n_disc_count, n_disc_osize );
if (0) {
diff --git a/coregrind/m_ume/main.c b/coregrind/m_ume/main.c
index 504bd53..bc98d9a 100644
--- a/coregrind/m_ume/main.c
+++ b/coregrind/m_ume/main.c
@@ -86,13 +86,13 @@
if (0 != ret) {
VG_(close)(fd);
if (is_setuid && !VG_(clo_xml)) {
- VG_(message)(Vg_UserMsg, "");
+ VG_(message)(Vg_UserMsg, "\n");
VG_(message)(Vg_UserMsg,
- "Warning: Can't execute setuid/setgid executable: %s",
+ "Warning: Can't execute setuid/setgid executable: %s\n",
exe_name);
VG_(message)(Vg_UserMsg, "Possible workaround: remove "
- "--trace-children=yes, if in effect");
- VG_(message)(Vg_UserMsg, "");
+ "--trace-children=yes, if in effect\n");
+ VG_(message)(Vg_UserMsg, "\n");
}
return VG_(mk_SysRes_Error)(ret);
}
diff --git a/coregrind/pub_core_libcprint.h b/coregrind/pub_core_libcprint.h
index 3b3460c..c043c2d 100644
--- a/coregrind/pub_core_libcprint.h
+++ b/coregrind/pub_core_libcprint.h
@@ -38,9 +38,15 @@
#include "pub_tool_libcprint.h"
-/* Tell the logging mechanism whether we are logging to a file
- descriptor or a socket descriptor. */
-extern Bool VG_(logging_to_socket);
+/* An output file descriptor wrapped up with a Bool indicating whether
+ or not the fd is a socket. */
+typedef
+ struct { Int fd; Bool is_socket; }
+ OutputSink;
+
+/* And the destinations for normal and XML output. */
+extern OutputSink VG_(log_output_sink);
+extern OutputSink VG_(xml_output_sink);
/* Get the elapsed wallclock time since startup into buf, which must
16 chars long. This is unchecked. It also relies on the
diff --git a/coregrind/pub_core_options.h b/coregrind/pub_core_options.h
index 73f4a63..b113a7e 100644
--- a/coregrind/pub_core_options.h
+++ b/coregrind/pub_core_options.h
@@ -65,30 +65,14 @@
intermingled with the parent's output. This is especially
problematic when VG_(clo_xml) is True. Setting
VG_(clo_child_silent_after_fork) causes children to fall silent
- after fork() calls. */
+ after fork() calls. Although note they become un-silent again
+ after the subsequent exec(). */
extern Bool VG_(clo_child_silent_after_fork);
-/* Where logging output is to be sent to.
-
- With --log-fd (and by default), clo_log_fd holds the file id, and is
- taken from the command line. (fd 2, stderr, is the default.)
- clo_log_name is irrelevant.
-
- With --log-file, clo_log_name holds the log-file name, and is taken from
- the command line (and possibly has process ID/env var contents in it, if
- the %p or %q format specifiers are used). clo_log_fd is then made to
- hold the relevant file id, by opening clo_log_name (concatenated with the
- process ID) for writing.
-
- With --log-socket, clo_log_name holds the hostname:portnumber pair,
- and is taken from the command line. clo_log_fd is then made to hold
- the relevant file handle, by opening a connection to that
- hostname:portnumber pair.
-
- Global default is to set log_to == VgLogTo_Fd and log_fd == 2
- (stderr). */
-extern Int VG_(clo_log_fd);
-extern Char* VG_(clo_log_name);
+/* If the user specified --log-file=STR and/or --xml-file=STR, these
+ hold STR after expansion of the %p and %q templates. */
+extern Char* VG_(clo_log_fname_expanded);
+extern Char* VG_(clo_xml_fname_expanded);
/* Add timestamps to log messages? default: NO */
extern Bool VG_(clo_time_stamp);
diff --git a/coregrind/pub_core_tooliface.h b/coregrind/pub_core_tooliface.h
index 25cfb26..f9a8005 100644
--- a/coregrind/pub_core_tooliface.h
+++ b/coregrind/pub_core_tooliface.h
@@ -117,6 +117,7 @@
// VG_(needs).tool_errors
Bool (*tool_eq_Error) (VgRes, Error*, Error*);
+ void (*tool_before_pp_Error) (Error*);
void (*tool_pp_Error) (Error*);
Bool tool_show_ThreadIDs_for_errors;
UInt (*tool_update_extra) (Error*);
@@ -161,6 +162,9 @@
// VG_(needs).final_IR_tidy_pass
IRSB* (*tool_final_IR_tidy_pass) (IRSB*);
+ // VG_(needs).xml_output
+ // (none)
+
// -- Event tracking functions ------------------------------------
void (*track_new_mem_startup) (Addr, SizeT, Bool, Bool, Bool, ULong);
void (*track_new_mem_stack_signal)(Addr, SizeT, ThreadId);