diff --git a/include/interfaces/SMPDBInterface.h b/include/interfaces/SMPDBInterface.h
index 05063bfe3399960a5beb701d31fa5e2335940660..7a5b5835b9082374bd43dd9969ff3f6605f84597 100644
--- a/include/interfaces/SMPDBInterface.h
+++ b/include/interfaces/SMPDBInterface.h
@@ -170,6 +170,12 @@ extern unsigned long STARS_MaxBlockCount;
 extern unsigned long STARS_SafeIndirectMemWriteCount;
 extern unsigned long STARS_UnsafeIndirectMemWriteCount;
 
+// Counters for function pointer shadowing.
+extern unsigned long STARS_FuncPtrShadowPointsAttempted;
+extern unsigned long STARS_FuncPtrShadowPointsSucceeded;
+extern unsigned long STARS_FuncPtrShadowPointsFailed;
+extern unsigned long STARS_FuncPtrShadowPointsSafe;  // not vulnerable to overwrite, so not shadowed.
+
 // strings for printing ZST_SysCallType
 extern const char *CallTypeNames[4];
 
diff --git a/src/base/SMPDBInterface.cpp b/src/base/SMPDBInterface.cpp
index f565220669375da80de9fe60265c9fc98addf34a..57e52a0777fe71c6705b3977a3cae176221de7cb 100644
--- a/src/base/SMPDBInterface.cpp
+++ b/src/base/SMPDBInterface.cpp
@@ -119,6 +119,13 @@ unsigned long STARS_MaxBlockCount;
 unsigned long STARS_SafeIndirectMemWriteCount;
 unsigned long STARS_UnsafeIndirectMemWriteCount;
 
+// Counters for function pointer shadowing.
+unsigned long STARS_FuncPtrShadowPointsAttempted;
+unsigned long STARS_FuncPtrShadowPointsSucceeded;
+unsigned long STARS_FuncPtrShadowPointsFailed;
+unsigned long STARS_FuncPtrShadowPointsSafe;  // not vulnerable to overwrite, so not shadowed.
+
+
 // strings for printing ZST_SysCallType
 const char *CallTypeNames[4] = { "Unrestricted", "High-Privilege", "File-Access", "Network-Access" };
 
diff --git a/src/base/SMPFunction.cpp b/src/base/SMPFunction.cpp
index 6c519424cd64fb988bfc2a6156ffef9959449cd3..9a6416fa8bf29a49720ab1937c9a1b7197a38736 100644
--- a/src/base/SMPFunction.cpp
+++ b/src/base/SMPFunction.cpp
@@ -11261,8 +11261,10 @@ void SMPFunction::EmitFuncPtrHelper(FILE *InfoAnnotFile, SMPInstr *CurrInst) {
 		}
 
 		bool UnsafeCodePointerChain = false;
+		++STARS_FuncPtrShadowPointsAttempted;
 		bool ValidShadowing = this->FindShadowingPoint2(CriticalOp, ShadowUses, UnsafeCodePointerChain, NewCriticalOps);
 		if (ValidShadowing && UnsafeCodePointerChain) {
+			++STARS_FuncPtrShadowPointsSucceeded;
 			// Need to shadow ShadowDefs right before their addrs, validate CriticalOp USE at ShadowCheckAddr
 			unsigned int CurrentShadowID = global_STARS_program->GetShadowID();
 			for (ShadowSet::const_iterator ShadowIter = ShadowUses.cbegin(); ShadowIter != ShadowUses.cend(); ++ShadowIter) {
@@ -11298,6 +11300,12 @@ void SMPFunction::EmitFuncPtrHelper(FILE *InfoAnnotFile, SMPInstr *CurrInst) {
 				global_STARS_program->IncrementShadowID();
 			}
 		} // end if (ValidShadowing && UnsafeCodePointerChain)
+		else if (ValidShadowing) { // Must be safe from overwriting
+			++STARS_FuncPtrShadowPointsSafe;
+		}
+		else {
+			++STARS_FuncPtrShadowPointsFailed;
+		}
 
 		// Now we need to find shadowing points for the NewCriticalOps.
 		if (!NewCriticalOps.empty()) {
diff --git a/src/base/SMPProgram.cpp b/src/base/SMPProgram.cpp
index a6d3012f0d75281feb7040964f583ea343de0bb5..1eec47b1143896a21147ce5f7e05eece127b9996 100644
--- a/src/base/SMPProgram.cpp
+++ b/src/base/SMPProgram.cpp
@@ -116,6 +116,15 @@ SMPProgram::SMPProgram(void) {
 	this->FuncList.clear();
 	this->GlobalVarTable.clear();
 	this->GlobalNameMap.clear();
+
+	// Initialize global counters.
+	STARS_SafeIndirectMemWriteCount = 0;
+	STARS_UnsafeIndirectMemWriteCount = 0;
+	STARS_FuncPtrShadowPointsAttempted = 0;
+	STARS_FuncPtrShadowPointsFailed = 0;
+	STARS_FuncPtrShadowPointsSafe = 0;
+	STARS_FuncPtrShadowPointsSucceeded = 0;
+
 	return;
 }
 
@@ -451,7 +460,10 @@ void SMPProgram::Analyze(ProfilerInformation *pi, FILE *AnnotFile, FILE *InfoAnn
 		}
 		CurrFunc->FreeUnusedMemory2(); // free memory
 		if (CurrFunc->StackPtrAnalysisSucceeded() && CurrFunc->HasGoodRTLs()
-			&& (!CurrFunc->HasUnresolvedIndirectJumps())) {
+#if 1   // test our ability to perform AliasAnalysis even when we have unresolved indirect jumps?
+			&& (!CurrFunc->HasUnresolvedIndirectJumps())
+#endif
+			) {
 #if 0  // LVA is now performed from Func->AdvancedAnalysis() in STEP 1 above
 			if (DebugFlag) {
 				SMP_msg("Performing LVA for %s.\n", CurrFunc->GetFuncName());
@@ -670,8 +682,8 @@ void SMPProgram::Analyze(ProfilerInformation *pi, FILE *AnnotFile, FILE *InfoAnn
 #endif
 				changed |= CurrFunc->InferInterproceduralTypes();
 			}
-#if 1
-			if ((!changed || (IterationCounter > STARS_INTERPROCEDURAL_ITERATION_LIMIT)) && (0 == strcmp("hash_clear", CurrFunc->GetFuncName()))) {
+#if 0
+			if ((!changed || (IterationCounter > STARS_INTERPROCEDURAL_ITERATION_LIMIT)) && (0 == strcmp("__mktime_internal", CurrFunc->GetFuncName()))) {
 				CurrFunc->Dump();
 			}
 #endif		
@@ -972,6 +984,12 @@ void SMPProgram::EmitAnnotations(FILE *AnnotFile, FILE *InfoAnnotFile) {
 	SMP_msg("INFO: NUMERIC: Suppressions for truncations when all subregs are used: %lu\n", SuppressTruncationRegPiecesAllUsed);
 	SMP_msg("INFO: NUMERIC: Suppressions for signedness on truncations: %lu\n", SuppressSignednessOnTruncation);
 #endif
+
+	SMP_msg("Total func ptr shadowing attempts: %lu\n", STARS_FuncPtrShadowPointsAttempted);
+	SMP_msg("Total func ptr shadowing successes: %lu\n", STARS_FuncPtrShadowPointsSucceeded);
+	SMP_msg("Total func ptr shadowing failures: %lu\n", STARS_FuncPtrShadowPointsFailed);
+	SMP_msg("Total func ptr shadowing chains not vulnerable: %lu\n", STARS_FuncPtrShadowPointsSafe);
+
 	return;
 } // end of SMPProgram::EmitAnnotations()