|
From: <sv...@va...> - 2010-07-29 05:28:10
|
Author: sewardj
Date: 2010-07-29 06:28:02 +0100 (Thu, 29 Jul 2010)
New Revision: 11234
Log:
When reporting an error about an attempt to re-lock an already-locked
lock, also report the stack where the lock was previously locked.
This makes it easier to diagnose deadlocks.
Modified:
trunk/helgrind/hg_errors.c
trunk/helgrind/hg_errors.h
trunk/helgrind/hg_main.c
Modified: trunk/helgrind/hg_errors.c
===================================================================
--- trunk/helgrind/hg_errors.c 2010-07-29 05:24:20 UTC (rev 11233)
+++ trunk/helgrind/hg_errors.c 2010-07-29 05:28:02 UTC (rev 11234)
@@ -222,8 +222,10 @@
ExeContext* after_ec;
} LockOrder;
struct {
- Thread* thr;
- HChar* errstr; /* persistent, in tool-arena */
+ Thread* thr;
+ HChar* errstr; /* persistent, in tool-arena */
+ HChar* auxstr; /* optional, persistent, in tool-arena */
+ ExeContext* auxctx; /* optional */
} Misc;
} XE;
}
@@ -507,7 +509,8 @@
XE_PthAPIerror, 0, NULL, &xe );
}
-void HG_(record_error_Misc) ( Thread* thr, HChar* errstr )
+void HG_(record_error_Misc_w_aux) ( Thread* thr, HChar* errstr,
+ HChar* auxstr, ExeContext* auxctx )
{
XError xe;
tl_assert( HG_(is_sane_Thread)(thr) );
@@ -516,6 +519,8 @@
xe.tag = XE_Misc;
xe.XE.Misc.thr = thr;
xe.XE.Misc.errstr = string_table_strdup(errstr);
+ xe.XE.Misc.auxstr = auxstr ? string_table_strdup(auxstr) : NULL;
+ xe.XE.Misc.auxctx = auxctx;
// FIXME: tid vs thr
tl_assert( HG_(is_sane_ThreadId)(thr->coretid) );
tl_assert( thr->coretid != VG_INVALID_THREADID );
@@ -523,6 +528,11 @@
XE_Misc, 0, NULL, &xe );
}
+void HG_(record_error_Misc) ( Thread* thr, HChar* errstr )
+{
+ HG_(record_error_Misc_w_aux)(thr, errstr, NULL, NULL);
+}
+
Bool HG_(eq_Error) ( VgRes not_used, Error* e1, Error* e2 )
{
XError *xe1, *xe2;
@@ -716,6 +726,11 @@
(Int)xe->XE.Misc.thr->errmsg_index );
emit( " </xwhat>\n" );
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
+ if (xe->XE.Misc.auxstr) {
+ emit(" <auxwhat>%s</auxwhat>\n", xe->XE.Misc.auxstr);
+ if (xe->XE.Misc.auxctx)
+ VG_(pp_ExeContext)( xe->XE.Misc.auxctx );
+ }
} else {
@@ -723,6 +738,11 @@
(Int)xe->XE.Misc.thr->errmsg_index,
xe->XE.Misc.errstr );
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
+ if (xe->XE.Misc.auxstr) {
+ emit(" %s\n", xe->XE.Misc.auxstr);
+ if (xe->XE.Misc.auxctx)
+ VG_(pp_ExeContext)( xe->XE.Misc.auxctx );
+ }
}
break;
Modified: trunk/helgrind/hg_errors.h
===================================================================
--- trunk/helgrind/hg_errors.h 2010-07-29 05:24:20 UTC (rev 11233)
+++ trunk/helgrind/hg_errors.h 2010-07-29 05:28:02 UTC (rev 11234)
@@ -59,8 +59,11 @@
void HG_(record_error_PthAPIerror) ( Thread*, HChar*, Word, HChar* );
void HG_(record_error_LockOrder) ( Thread*, Addr, Addr,
ExeContext*, ExeContext* );
-void HG_(record_error_Misc) ( Thread*, HChar* );
+void HG_(record_error_Misc_w_aux) ( Thread*, HChar* errstr,
+ HChar* auxstr, ExeContext* auxctx );
+void HG_(record_error_Misc) ( Thread* thr, HChar* errstr );
+
/* Statistics pertaining to error management. */
extern ULong HG_(stats__LockN_to_P_queries);
extern ULong HG_(stats__LockN_to_P_get_map_size) ( void );
Modified: trunk/helgrind/hg_main.c
===================================================================
--- trunk/helgrind/hg_main.c 2010-07-29 05:24:20 UTC (rev 11233)
+++ trunk/helgrind/hg_main.c 2010-07-29 05:28:02 UTC (rev 11234)
@@ -1980,8 +1980,14 @@
this is a real lock operation (not a speculative "tryLock"
kind of thing). Duh. Deadlock coming up; but at least
produce an error message. */
- HG_(record_error_Misc)( thr, "Attempt to re-lock a "
- "non-recursive lock I already hold" );
+ HChar* errstr = "Attempt to re-lock a "
+ "non-recursive lock I already hold";
+ HChar* auxstr = "Lock was previously acquired";
+ if (lk->acquired_at) {
+ HG_(record_error_Misc_w_aux)( thr, errstr, auxstr, lk->acquired_at );
+ } else {
+ HG_(record_error_Misc)( thr, errstr );
+ }
}
}
|