diff options
Diffstat (limited to 'src/inc/allocacheck.h')
-rw-r--r-- | src/inc/allocacheck.h | 84 |
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 |