summaryrefslogtreecommitdiff
path: root/src/inc/allocacheck.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/inc/allocacheck.h')
-rw-r--r--src/inc/allocacheck.h84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/inc/allocacheck.h b/src/inc/allocacheck.h
new file mode 100644
index 0000000000..3ba2e4da43
--- /dev/null
+++ b/src/inc/allocacheck.h
@@ -0,0 +1,84 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+/*********************************************************************/
+/* AllocaCheck */
+/*********************************************************************/
+
+/* check for alloca overruns (which otherwise are hard to track down
+ and often only repro on optimized builds).
+
+ USAGE:
+
+ void foo() {
+ ALLOCA_CHECK(); // Declare at function level scope
+
+ ....
+ void* mem = ALLOCA(size); // does an alloca,
+
+ } // destructor of ALLOCA_CHECK for buffer overruns.
+*/
+
+/* */
+/*********************************************************************/
+
+#ifndef AllocaCheck_h
+#define AllocaCheck_h
+#include <malloc.h> // for alloca itself
+
+#if defined(assert) && !defined(_ASSERTE)
+#define _ASSERTE assert
+#endif
+
+#if defined(_DEBUG) || defined(DEBUG)
+
+/*********************************************************************/
+class AllocaCheck {
+public:
+ enum { CheckBytes = 0xCCCDCECF,
+ };
+
+ struct AllocaSentinal {
+ int check;
+ AllocaSentinal* next;
+ };
+
+public:
+ /***************************************************/
+ AllocaCheck() {
+ sentinals = 0;
+ }
+
+ ~AllocaCheck() {
+ AllocaSentinal* ptr = sentinals;
+ while (ptr != 0) {
+ if (ptr->check != (int)CheckBytes)
+ _ASSERTE(!"alloca buffer overrun");
+ ptr = ptr->next;
+ }
+ }
+
+ void* add(void* allocaBuff, unsigned size) {
+ AllocaSentinal* newSentinal = (AllocaSentinal*) ((char*) allocaBuff + size);
+ newSentinal->check = CheckBytes;
+ newSentinal->next = sentinals;
+ sentinals = newSentinal;
+ memset(allocaBuff, 0xDD, size);
+ return allocaBuff;
+ }
+
+private:
+ AllocaSentinal* sentinals;
+};
+
+#define ALLOCA_CHECK() AllocaCheck __allocaChecker
+#define ALLOCA(size) __allocaChecker.add(_alloca(size+sizeof(AllocaCheck::AllocaSentinal)), size);
+
+#else
+
+#define ALLOCA_CHECK()
+#define ALLOCA(size) _alloca(size)
+
+#endif
+
+#endif