1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4/*********************************************************************/
5/* AllocaCheck */
6/*********************************************************************/
7
8/* check for alloca overruns (which otherwise are hard to track down
9 and often only repro on optimized builds).
10
11 USAGE:
12
13 void foo() {
14 ALLOCA_CHECK(); // Declare at function level scope
15
16 ....
17 void* mem = ALLOCA(size); // does an alloca,
18
19 } // destructor of ALLOCA_CHECK for buffer overruns.
20*/
21
22/* */
23/*********************************************************************/
24
25#ifndef AllocaCheck_h
26#define AllocaCheck_h
27#include <malloc.h> // for alloca itself
28
29#if defined(assert) && !defined(_ASSERTE)
30#define _ASSERTE assert
31#endif
32
33#if defined(_DEBUG) || defined(DEBUG)
34
35/*********************************************************************/
36class AllocaCheck {
37public:
38 enum { CheckBytes = 0xCCCDCECF,
39 };
40
41 struct AllocaSentinal {
42 int check;
43 AllocaSentinal* next;
44 };
45
46public:
47 /***************************************************/
48 AllocaCheck() {
49 sentinals = 0;
50 }
51
52 ~AllocaCheck() {
53 AllocaSentinal* ptr = sentinals;
54 while (ptr != 0) {
55 if (ptr->check != (int)CheckBytes)
56 _ASSERTE(!"alloca buffer overrun");
57 ptr = ptr->next;
58 }
59 }
60
61 void* add(void* allocaBuff, unsigned size) {
62 AllocaSentinal* newSentinal = (AllocaSentinal*) ((char*) allocaBuff + size);
63 newSentinal->check = CheckBytes;
64 newSentinal->next = sentinals;
65 sentinals = newSentinal;
66 memset(allocaBuff, 0xDD, size);
67 return allocaBuff;
68 }
69
70private:
71 AllocaSentinal* sentinals;
72};
73
74#define ALLOCA_CHECK() AllocaCheck __allocaChecker
75#define ALLOCA(size) __allocaChecker.add(_alloca(size+sizeof(AllocaCheck::AllocaSentinal)), size);
76
77#else
78
79#define ALLOCA_CHECK()
80#define ALLOCA(size) _alloca(size)
81
82#endif
83
84#endif
85