Implement a sanity check for CCS fields in profiling builds
authorÖmer Sinan Ağacan <omeragacan@gmail.com>
Thu, 10 Jan 2019 09:42:04 +0000 (12:42 +0300)
committerÖmer Sinan Ağacan <omeragacan@gmail.com>
Thu, 10 Jan 2019 09:42:04 +0000 (12:42 +0300)
This helped me debug one of the bugs in #15508. I'm not sure if this is
a good idea, but it worked for me, so wanted to submit this as a MR.

rts/Arena.c
rts/Arena.h
rts/Profiling.c
rts/Profiling.h
rts/sm/Sanity.c

index cd547e5..e0b4ebd 100644 (file)
@@ -117,3 +117,16 @@ arenaBlocks( void )
 {
     return arena_blocks;
 }
+
+#if defined(DEBUG)
+void checkPtrInArena( StgPtr p, Arena *arena )
+{
+    for (bdescr *bd = arena->current; bd; bd = bd->link) {
+        if (p >= bd->start && p < bd->free) {
+            return;
+        }
+    }
+
+    barf("Location %p is not in arena %p", (void*)p, (void*)arena);
+}
+#endif
index 8fa8236..4929871 100644 (file)
@@ -20,3 +20,7 @@ RTS_PRIVATE void arenaFree  ( Arena * );
 
 // For internal use only:
 RTS_PRIVATE unsigned long arenaBlocks( void );
+
+#if defined(DEBUG)
+void checkPtrInArena( StgPtr p, Arena *arena );
+#endif
index 7abad59..70bf375 100644 (file)
 /*
  * Profiling allocation arena.
  */
+#if defined(DEBUG)
+Arena *prof_arena;
+#else
 static Arena *prof_arena;
+#endif
 
 /*
  * Global variables used to assign unique IDs to cc's, ccs's, and
index 45725e5..c692c22 100644 (file)
 #include "BeginPrivate.h"
 #include "Rts.h"
 
+#if defined(DEBUG)
+#include "Arena.h"
+#endif
+
 #if defined(PROFILING)
 #define PROFILING_ONLY(s) s
 #else
@@ -46,6 +50,8 @@ bool ignoreCCS (CostCentreStack const *ccs);
 bool ignoreCC (CostCentre const *cc);
 
 #if defined(DEBUG)
+extern Arena *prof_arena;
+
 void debugCCS( CostCentreStack *ccs );
 #endif
 
index 1da3e44..28c9b43 100644 (file)
@@ -29,6 +29,7 @@
 #include "Arena.h"
 #include "RetainerProfile.h"
 #include "CNF.h"
+#include "Profiling.h" // prof_arena
 
 /* -----------------------------------------------------------------------------
    Forward decls.
@@ -210,6 +211,17 @@ checkPAP (StgClosure *tagged_fun, StgClosure** payload, StgWord n_args)
            : GET_CLOSURE_TAG(tagged_fun) == fun_info->f.arity);
 }
 
+#if defined(PROFILING)
+static void
+checkClosureProfSanity(const StgClosure *p)
+{
+    StgProfHeader prof_hdr = p->header.prof;
+    CostCentreStack *ccs = prof_hdr.ccs;
+    if (HEAP_ALLOCED_GC((void*)ccs)) {
+        checkPtrInArena((StgPtr)ccs, prof_arena);
+    }
+}
+#endif
 
 StgOffset
 checkClosure( const StgClosure* p )
@@ -225,6 +237,11 @@ checkClosure( const StgClosure* p )
     if (IS_FORWARDING_PTR(info)) {
         barf("checkClosure: found EVACUATED closure %d", info->type);
     }
+
+#if defined(PROFILING)
+    checkClosureProfSanity(p);
+#endif
+
     info = INFO_PTR_TO_STRUCT(info);
 
     switch (info->type) {