drd: Enable XML output. See also #282949. To do: document the output format.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12137 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/drd/drd_error.c b/drd/drd_error.c
index 0bd0a10..35c2b62 100644
--- a/drd/drd_error.c
+++ b/drd/drd_error.c
@@ -42,6 +42,11 @@
#include "pub_tool_tooliface.h" /* VG_(needs_tool_errors)() */
+/* Local function declarations. */
+
+static Char* drd_get_error_name(Error* e);
+
+
/* Local variables. */
static Bool s_show_conflicting_segments = True;
@@ -56,7 +61,28 @@
{
va_list vargs;
va_start(vargs, format);
- VG_(vmessage)(Vg_UserMsg, format, vargs);
+ if (VG_(clo_xml)) {
+ VG_(printf_xml)("<traceline>\n ");
+ VG_(vprintf_xml)(format, vargs);
+ VG_(printf_xml)("</traceline>\n");
+ } else {
+ VG_(vmessage)(Vg_UserMsg, format, vargs);
+ }
+ va_end(vargs);
+}
+
+/**
+ * Emit error message detail in the format requested by the user.
+ */
+static void print_err_detail(const char* format, ...) PRINTF_CHECK(1, 2);
+static void print_err_detail(const char* format, ...)
+{
+ va_list vargs;
+ va_start(vargs, format);
+ if (VG_(clo_xml))
+ VG_(vprintf_xml)(format, vargs);
+ else
+ VG_(vmessage)(Vg_UserMsg, format, vargs);
va_end(vargs);
}
@@ -89,20 +115,30 @@
DrdClientobj* cl;
cl = DRD_(clientobj_get_any)(obj);
- if (cl)
- {
+ if (cl) {
tl_assert(cl->any.first_observed_at);
- VG_(message)(Vg_UserMsg,
- "%s 0x%lx was first observed at:\n",
- DRD_(clientobj_type_name)(cl->any.type),
- obj);
- VG_(pp_ExeContext)(cl->any.first_observed_at);
+ if (VG_(clo_xml)) {
+ print_err_detail(" <first_observed_at>\n"
+ " <what>%pS</what>\n"
+ " <address>0x%lx</address>\n",
+ DRD_(clientobj_type_name)(cl->any.type), obj);
+ VG_(pp_ExeContext)(cl->any.first_observed_at);
+ print_err_detail(" </first_observed_at>\n");
+ } else {
+ print_err_detail("%s 0x%lx was first observed at:\n",
+ DRD_(clientobj_type_name)(cl->any.type), obj);
+ VG_(pp_ExeContext)(cl->any.first_observed_at);
+ }
}
}
static
void drd_report_data_race(Error* const err, const DataRaceErrInfo* const dri)
{
+ const Bool xml = VG_(clo_xml);
+ const char* const what_prefix = xml ? " <what>" : "";
+ const char* const what_suffix = xml ? "</what>" : "";
+ const char* const indent = xml ? " " : "";
AddrInfo ai;
XArray* /* of HChar */ descr1
@@ -143,44 +179,50 @@
/* No. Do Plan B. */
describe_malloced_addr(dri->addr, &ai);
}
- VG_(message)(Vg_UserMsg,
- "Conflicting %s by thread %d at 0x%08lx size %ld\n",
- dri->access_type == eStore ? "store" : "load",
- dri->tid,
- dri->addr,
- dri->size);
+
+ print_err_detail("%sConflicting %s by thread %d at 0x%08lx size %ld%s\n",
+ what_prefix, dri->access_type == eStore ? "store" : "load",
+ dri->tid, dri->addr, dri->size, what_suffix);
+
VG_(pp_ExeContext)(VG_(get_error_where)(err));
- if (descr1 != NULL)
- {
- VG_(message)(Vg_UserMsg, "%s\n", (HChar*)VG_(indexXA)(descr1, 0));
+ if (descr1 != NULL) {
+ print_err_detail("%s%s\n", indent, (HChar*)VG_(indexXA)(descr1, 0));
if (descr2 != NULL)
- VG_(message)(Vg_UserMsg, "%s\n", (HChar*)VG_(indexXA)(descr2, 0));
- }
- else if (ai.akind == eMallocd && ai.lastchange)
- {
- VG_(message)(Vg_UserMsg,
- "Address 0x%lx is at offset %ld from 0x%lx."
- " Allocation context:\n",
- dri->addr, ai.rwoffset, dri->addr - ai.rwoffset);
+ print_err_detail("%s%s\n", indent, (HChar*)VG_(indexXA)(descr2, 0));
+ } else if (ai.akind == eMallocd && ai.lastchange) {
+ if (xml)
+ print_err_detail(" <auxwhat>\n <text>");
+ print_err_detail("Address 0x%lx is at offset %ld from 0x%lx.",
+ dri->addr, ai.rwoffset, dri->addr - ai.rwoffset);
+ if (xml)
+ print_err_detail("</text>\n");
+ else
+ print_err_detail(" Allocation context:\n");
VG_(pp_ExeContext)(ai.lastchange);
- }
- else
- {
+ if (xml)
+ print_err_detail(" </auxwhat>\n");
+ } else {
char sect_name[64];
VgSectKind sect_kind;
sect_kind = VG_(DebugInfo_sect_kind)(sect_name, sizeof(sect_name),
dri->addr);
- if (sect_kind != Vg_SectUnknown)
- {
- VG_(message)(Vg_UserMsg,
- "Allocation context: %s section of %s\n",
- VG_(pp_SectKind)(sect_kind),
- sect_name);
- }
- else
- {
- VG_(message)(Vg_UserMsg, "Allocation context: unknown.\n");
+ if (xml) {
+ print_err_detail(" <auxwhat><text>");
+ if (sect_kind != Vg_SectUnknown) {
+ print_err_detail(" Allocation context: %pS section of %pS\n",
+ VG_(pp_SectKind)(sect_kind), sect_name);
+ } else {
+ print_err_detail(" Allocation context: unknown.\n");
+ }
+ print_err_detail(" </text><auxwhat>\n");
+ } else {
+ if (sect_kind != Vg_SectUnknown) {
+ print_err_detail("Allocation context: %s section of %s\n",
+ VG_(pp_SectKind)(sect_kind), sect_name);
+ } else {
+ print_err_detail("Allocation context: unknown.\n");
+ }
}
}
if (s_show_conflicting_segments)
@@ -238,8 +280,7 @@
err_extra = VG_(get_error_extra)(e);
- if (err_extra && *err_extra != s_last_tid_printed)
- {
+ if (err_extra && *err_extra != s_last_tid_printed && !VG_(clo_xml)) {
VG_(umsg)("%s:\n", DRD_(thread_get_name)(*err_extra));
s_last_tid_printed = *err_extra;
}
@@ -248,6 +289,13 @@
/** Report an error to the user. */
static void drd_tool_error_pp(Error* const e)
{
+ const Bool xml = VG_(clo_xml);
+ const char* const what_prefix = xml ? " <what>" : "";
+ const char* const what_suffix = xml ? "</what>" : "";
+
+ if (xml)
+ VG_(printf_xml)( " <kind>%pS</kind>\n", drd_get_error_name(e));
+
switch (VG_(get_error_kind)(e))
{
case DataRaceErr: {
@@ -257,20 +305,13 @@
case MutexErr: {
MutexErrInfo* p = (MutexErrInfo*)(VG_(get_error_extra)(e));
tl_assert(p);
- if (p->recursion_count >= 0)
- {
- VG_(message)(Vg_UserMsg,
- "%s: mutex 0x%lx, recursion count %d, owner %d.\n",
- VG_(get_error_string)(e),
- p->mutex,
- p->recursion_count,
- p->owner);
- }
- else
- {
- VG_(message)(Vg_UserMsg,
- "The object at address 0x%lx is not a mutex.\n",
- p->mutex);
+ if (p->recursion_count >= 0) {
+ print_err_detail("%s%s: mutex 0x%lx, recursion count %d, owner %d."
+ "%s\n", what_prefix, VG_(get_error_string)(e),
+ p->mutex, p->recursion_count, p->owner, what_suffix);
+ } else {
+ print_err_detail("%sThe object at address 0x%lx is not a mutex.%s\n",
+ what_prefix, p->mutex, what_suffix);
}
VG_(pp_ExeContext)(VG_(get_error_where)(e));
first_observed(p->mutex);
@@ -278,32 +319,27 @@
}
case CondErr: {
CondErrInfo* cdei =(CondErrInfo*)(VG_(get_error_extra)(e));
- VG_(message)(Vg_UserMsg,
- "%s: cond 0x%lx\n",
- VG_(get_error_string)(e),
- cdei->cond);
+ print_err_detail("%s%s: cond 0x%lx%s\n", what_prefix,
+ VG_(get_error_string)(e), cdei->cond, what_suffix);
VG_(pp_ExeContext)(VG_(get_error_where)(e));
first_observed(cdei->cond);
break;
}
case CondDestrErr: {
CondDestrErrInfo* cdi = (CondDestrErrInfo*)(VG_(get_error_extra)(e));
- VG_(message)(Vg_UserMsg,
- "%s: cond 0x%lx, mutex 0x%lx locked by thread %d\n",
- VG_(get_error_string)(e),
- cdi->cond, cdi->mutex,
- cdi->owner);
+ print_err_detail("%s%s: cond 0x%lx, mutex 0x%lx locked by thread %d%s\n",
+ what_prefix, VG_(get_error_string)(e), cdi->cond,
+ cdi->mutex, cdi->owner, what_suffix);
VG_(pp_ExeContext)(VG_(get_error_where)(e));
first_observed(cdi->mutex);
break;
}
case CondRaceErr: {
CondRaceErrInfo* cei = (CondRaceErrInfo*)(VG_(get_error_extra)(e));
- VG_(message)(Vg_UserMsg,
- "Probably a race condition: condition variable 0x%lx has"
- " been signaled but the associated mutex 0x%lx is not"
- " locked by the signalling thread.\n",
- cei->cond, cei->mutex);
+ print_err_detail("%sProbably a race condition: condition variable 0x%lx"
+ " has been signaled but the associated mutex 0x%lx is"
+ " not locked by the signalling thread.%s\n",
+ what_prefix, cei->cond, cei->mutex, what_suffix);
VG_(pp_ExeContext)(VG_(get_error_where)(e));
first_observed(cei->cond);
first_observed(cei->mutex);
@@ -311,12 +347,9 @@
}
case CondWaitErr: {
CondWaitErrInfo* cwei = (CondWaitErrInfo*)(VG_(get_error_extra)(e));
- VG_(message)(Vg_UserMsg,
- "%s: condition variable 0x%lx, mutexes 0x%lx and 0x%lx\n",
- VG_(get_error_string)(e),
- cwei->cond,
- cwei->mutex1,
- cwei->mutex2);
+ print_err_detail("%s%s: condition variable 0x%lx, mutexes 0x%lx and"
+ " 0x%lx%s\n", what_prefix, VG_(get_error_string)(e),
+ cwei->cond, cwei->mutex1, cwei->mutex2, what_suffix);
VG_(pp_ExeContext)(VG_(get_error_where)(e));
first_observed(cwei->cond);
first_observed(cwei->mutex1);
@@ -326,10 +359,8 @@
case SemaphoreErr: {
SemaphoreErrInfo* sei = (SemaphoreErrInfo*)(VG_(get_error_extra)(e));
tl_assert(sei);
- VG_(message)(Vg_UserMsg,
- "%s: semaphore 0x%lx\n",
- VG_(get_error_string)(e),
- sei->semaphore);
+ print_err_detail("%s%s: semaphore 0x%lx%s\n", VG_(get_error_string)(e),
+ what_prefix, sei->semaphore, what_suffix);
VG_(pp_ExeContext)(VG_(get_error_where)(e));
first_observed(sei->semaphore);
break;
@@ -337,17 +368,17 @@
case BarrierErr: {
BarrierErrInfo* bei = (BarrierErrInfo*)(VG_(get_error_extra)(e));
tl_assert(bei);
- VG_(message)(Vg_UserMsg,
- "%s: barrier 0x%lx\n",
- VG_(get_error_string)(e),
- bei->barrier);
+ print_err_detail("%s%s: barrier 0x%lx%s\n", what_prefix,
+ VG_(get_error_string)(e), bei->barrier, what_suffix);
VG_(pp_ExeContext)(VG_(get_error_where)(e));
- if (bei->other_context)
- {
- VG_(message)(Vg_UserMsg,
- "Conflicting wait call by thread %d:\n",
- bei->other_tid);
+ if (bei->other_context) {
+ if (xml)
+ print_err_detail(" <confl_wait_call>\n");
+ print_err_detail("%sConflicting wait call by thread %d:%s\n",
+ what_prefix, bei->other_tid, what_suffix);
VG_(pp_ExeContext)(bei->other_context);
+ if (xml)
+ print_err_detail(" </confl_wait_call>\n");
}
first_observed(bei->barrier);
break;
@@ -355,10 +386,8 @@
case RwlockErr: {
RwlockErrInfo* p = (RwlockErrInfo*)(VG_(get_error_extra)(e));
tl_assert(p);
- VG_(message)(Vg_UserMsg,
- "%s: rwlock 0x%lx.\n",
- VG_(get_error_string)(e),
- p->rwlock);
+ print_err_detail("%s%s: rwlock 0x%lx.%s\n", what_prefix,
+ VG_(get_error_string)(e), p->rwlock, what_suffix);
VG_(pp_ExeContext)(VG_(get_error_where)(e));
first_observed(p->rwlock);
break;
@@ -367,21 +396,25 @@
HoldtimeErrInfo* p =(HoldtimeErrInfo*)(VG_(get_error_extra)(e));
tl_assert(p);
tl_assert(p->acquired_at);
- VG_(message)(Vg_UserMsg, "Acquired at:\n");
+ if (xml)
+ print_err_detail(" <acquired_at>\n");
+ else
+ print_err_detail("Acquired at:\n");
VG_(pp_ExeContext)(p->acquired_at);
- VG_(message)(Vg_UserMsg,
- "Lock on %s 0x%lx was held during %d ms (threshold: %d ms).\n",
- VG_(get_error_string)(e),
- p->synchronization_object,
- p->hold_time_ms,
- p->threshold_ms);
+ print_err_detail("%sLock on %s 0x%lx was held during %d ms"
+ " (threshold: %d ms).%s\n", what_prefix,
+ VG_(get_error_string)(e), p->synchronization_object,
+ p->hold_time_ms, p->threshold_ms, what_suffix);
VG_(pp_ExeContext)(VG_(get_error_where)(e));
+ if (xml)
+ print_err_detail(" </acquired_at>\n");
first_observed(p->synchronization_object);
break;
}
case GenericErr: {
GenericErrInfo* gei = (GenericErrInfo*)(VG_(get_error_extra)(e));
- VG_(message)(Vg_UserMsg, "%s\n", VG_(get_error_string)(e));
+ print_err_detail("%s%s%s\n", what_prefix, VG_(get_error_string)(e),
+ what_suffix);
VG_(pp_ExeContext)(VG_(get_error_where)(e));
if (gei->addr)
first_observed(gei->addr);
@@ -389,33 +422,30 @@
}
case InvalidThreadId: {
InvalidThreadIdInfo* iti =(InvalidThreadIdInfo*)(VG_(get_error_extra)(e));
- VG_(message)(Vg_UserMsg,
- "%s 0x%llx\n", VG_(get_error_string)(e), iti->ptid);
+ print_err_detail("%s%s 0x%llx%s\n", what_prefix, VG_(get_error_string)(e),
+ iti->ptid, what_suffix);
VG_(pp_ExeContext)(VG_(get_error_where)(e));
break;
}
case UnimpHgClReq: {
UnimpClReqInfo* uicr =(UnimpClReqInfo*)(VG_(get_error_extra)(e));
- VG_(message)(Vg_UserMsg,
- "The annotation macro %s has not yet been implemented in"
- " <valgrind/helgrind.h>\n",
- /*VG_(get_error_string)(e),*/ uicr->descr);
+ print_err_detail("%sThe annotation macro %s has not yet been implemented"
+ " in %ps%s\n", what_prefix, uicr->descr,
+ "<valgrind/helgrind.h>", what_suffix);
VG_(pp_ExeContext)(VG_(get_error_where)(e));
break;
}
case UnimpDrdClReq: {
UnimpClReqInfo* uicr =(UnimpClReqInfo*)(VG_(get_error_extra)(e));
- VG_(message)(Vg_UserMsg,
- "The annotation macro %s has not yet been implemented in"
- " <valgrind/drd.h>\n",
- uicr->descr);
+ print_err_detail("%sThe annotation macro %s has not yet been implemented"
+ " in %ps%s\n", what_prefix, uicr->descr,
+ "<valgrind/drd.h>", what_suffix);
VG_(pp_ExeContext)(VG_(get_error_where)(e));
break;
}
default:
- VG_(message)(Vg_UserMsg,
- "%s\n",
- VG_(get_error_string)(e));
+ print_err_detail("%s%s%s\n", what_prefix, VG_(get_error_string)(e),
+ what_suffix);
VG_(pp_ExeContext)(VG_(get_error_where)(e));
break;
}